Import Cobalt 4.12347
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsAnonymousIndexedGetterInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsAnonymousIndexedGetterInterface.cc
index be7915c..a0e4bc7 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsAnonymousIndexedGetterInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsAnonymousIndexedGetterInterface.cc
@@ -280,6 +280,17 @@
JSBool get_length(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<AnonymousIndexedGetterInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsAnonymousNamedIndexedGetterInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsAnonymousNamedIndexedGetterInterface.cc
index 388c186..d763c55 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsAnonymousNamedIndexedGetterInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsAnonymousNamedIndexedGetterInterface.cc
@@ -371,6 +371,17 @@
JSBool get_length(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<AnonymousNamedIndexedGetterInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsArbitraryInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsArbitraryInterface.cc
index 71b31f2..7e28810 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsArbitraryInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsArbitraryInterface.cc
@@ -191,6 +191,17 @@
JSBool get_arbitraryProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ArbitraryInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsBaseInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsBaseInterface.cc
index bf4b5a3..b6d7b8c 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsBaseInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsBaseInterface.cc
@@ -191,6 +191,17 @@
JSBool get_baseAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<BaseInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsBooleanTypeTestInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsBooleanTypeTestInterface.cc
index 1796c62..0ef0a1b 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsBooleanTypeTestInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsBooleanTypeTestInterface.cc
@@ -189,6 +189,17 @@
JSBool get_booleanProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<BooleanTypeTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsCallbackFunctionInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsCallbackFunctionInterface.cc
index 0b7e907..3a7967e 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsCallbackFunctionInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsCallbackFunctionInterface.cc
@@ -193,6 +193,17 @@
JSBool get_callbackAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<CallbackFunctionInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -237,6 +248,17 @@
JSBool get_nullableCallbackAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<CallbackFunctionInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsCallbackInterfaceInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsCallbackInterfaceInterface.cc
index d4321ff..d43b8d1 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsCallbackInterfaceInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsCallbackInterfaceInterface.cc
@@ -193,6 +193,17 @@
JSBool get_callbackAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<CallbackInterfaceInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsConditionalInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsConditionalInterface.cc
index e8e5a7d..19ec00c 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsConditionalInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsConditionalInterface.cc
@@ -192,6 +192,17 @@
JSBool get_enabledAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ConditionalInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -238,6 +249,17 @@
JSBool get_disabledAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ConditionalInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsConstructorWithArgumentsInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsConstructorWithArgumentsInterface.cc
index 09ccf2a..dc0902e 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsConstructorWithArgumentsInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsConstructorWithArgumentsInterface.cc
@@ -191,6 +191,17 @@
JSBool get_longArg(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ConstructorWithArgumentsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -213,6 +224,17 @@
JSBool get_booleanArg(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ConstructorWithArgumentsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -235,6 +257,17 @@
JSBool get_stringArg(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ConstructorWithArgumentsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsDOMStringTestInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsDOMStringTestInterface.cc
index 7fb410b..841f7a8 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsDOMStringTestInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsDOMStringTestInterface.cc
@@ -189,6 +189,17 @@
JSBool get_property(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DOMStringTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -233,6 +244,17 @@
JSBool get_readOnlyProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DOMStringTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -255,6 +277,17 @@
JSBool get_readOnlyTokenProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DOMStringTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -277,6 +310,17 @@
JSBool get_nullIsEmptyProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DOMStringTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -321,6 +365,17 @@
JSBool get_undefinedIsEmptyProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DOMStringTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -365,6 +420,17 @@
JSBool get_nullableUndefinedIsEmptyProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DOMStringTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsDerivedGetterSetterInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsDerivedGetterSetterInterface.cc
index 9d7f281..9814942 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsDerivedGetterSetterInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsDerivedGetterSetterInterface.cc
@@ -371,6 +371,17 @@
JSBool get_length(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DerivedGetterSetterInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -393,6 +404,17 @@
JSBool get_propertyOnDerivedClass(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DerivedGetterSetterInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsDerivedInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsDerivedInterface.cc
index 8d64be2..bcb9fda 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsDerivedInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsDerivedInterface.cc
@@ -191,6 +191,17 @@
JSBool get_derivedAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DerivedInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsDisabledInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsDisabledInterface.cc
index 3f3d4a7..28cbd52 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsDisabledInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsDisabledInterface.cc
@@ -191,6 +191,17 @@
JSBool get_disabledProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<DisabledInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsEnumerationInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsEnumerationInterface.cc
index c54bde2..871154e 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsEnumerationInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsEnumerationInterface.cc
@@ -200,6 +200,17 @@
JSBool get_enumProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<EnumerationInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsExceptionObjectInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsExceptionObjectInterface.cc
index 64e3ca6..3a99fe0 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsExceptionObjectInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsExceptionObjectInterface.cc
@@ -190,6 +190,17 @@
JSBool get_error(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ExceptionObjectInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -212,6 +223,17 @@
JSBool get_message(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ExceptionObjectInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsExceptionsInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsExceptionsInterface.cc
index 5f1a396..8eb1363 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsExceptionsInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsExceptionsInterface.cc
@@ -191,6 +191,17 @@
JSBool get_attributeThrowsException(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ExceptionsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsExtendedIDLAttributesInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsExtendedIDLAttributesInterface.cc
index 07cceda..c98193f 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsExtendedIDLAttributesInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsExtendedIDLAttributesInterface.cc
@@ -208,10 +208,10 @@
WrapperPrivate::GetFromObject(context, object);
ExtendedIDLAttributesInterface* impl =
wrapper_private->wrappable<ExtendedIDLAttributesInterface>().get();
- MozjsGlobalEnvironment* global_environment =
+ MozjsGlobalEnvironment* callwith_global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
- impl->CallWithSettings(global_environment->GetEnvironmentSettings());
+ impl->CallWithSettings(callwith_global_environment->GetEnvironmentSettings());
result_value.set(JS::UndefinedHandleValue);
return !exception_state.is_exception_set();
}
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsGarbageCollectionTestInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsGarbageCollectionTestInterface.cc
index d2cfb40..fe27347 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsGarbageCollectionTestInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsGarbageCollectionTestInterface.cc
@@ -202,6 +202,17 @@
JSBool get_previous(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<GarbageCollectionTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -246,6 +257,17 @@
JSBool get_next(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<GarbageCollectionTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsIndexedGetterInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsIndexedGetterInterface.cc
index 752334e..e62a360 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsIndexedGetterInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsIndexedGetterInterface.cc
@@ -295,6 +295,17 @@
JSBool get_length(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<IndexedGetterInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsInterfaceWithUnsupportedProperties.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsInterfaceWithUnsupportedProperties.cc
index a578e9c..3612e1c 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsInterfaceWithUnsupportedProperties.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsInterfaceWithUnsupportedProperties.cc
@@ -189,6 +189,17 @@
JSBool get_supportedAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<InterfaceWithUnsupportedProperties>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsNamedIndexedGetterInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsNamedIndexedGetterInterface.cc
index 2965f0f..72d99fc 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsNamedIndexedGetterInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsNamedIndexedGetterInterface.cc
@@ -371,6 +371,17 @@
JSBool get_length(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NamedIndexedGetterInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -393,6 +404,17 @@
JSBool get_propertyOnBaseClass(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NamedIndexedGetterInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsNestedPutForwardsInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsNestedPutForwardsInterface.cc
index 69fab04..d283446 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsNestedPutForwardsInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsNestedPutForwardsInterface.cc
@@ -193,6 +193,17 @@
JSBool get_nestedForwardingAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NestedPutForwardsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsNullableTypesTestInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsNullableTypesTestInterface.cc
index c0010f4..2580dfc 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsNullableTypesTestInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsNullableTypesTestInterface.cc
@@ -193,6 +193,17 @@
JSBool get_nullableBooleanProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NullableTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -237,6 +248,17 @@
JSBool get_nullableNumericProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NullableTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -281,6 +303,17 @@
JSBool get_nullableStringProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NullableTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -325,6 +358,17 @@
JSBool get_nullableObjectProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NullableTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsNumericTypesTestInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsNumericTypesTestInterface.cc
index 4bf1c6e..772085f 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsNumericTypesTestInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsNumericTypesTestInterface.cc
@@ -189,6 +189,17 @@
JSBool get_byteProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -233,6 +244,17 @@
JSBool get_octetProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -277,6 +299,17 @@
JSBool get_shortProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -321,6 +354,17 @@
JSBool get_unsignedShortProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -365,6 +409,17 @@
JSBool get_longProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -409,6 +464,17 @@
JSBool get_unsignedLongProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -453,6 +519,17 @@
JSBool get_longLongProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -497,6 +574,17 @@
JSBool get_unsignedLongLongProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -541,6 +629,17 @@
JSBool get_doubleProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -585,6 +684,17 @@
JSBool get_unrestrictedDoubleProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<NumericTypesTestInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsObjectTypeBindingsInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsObjectTypeBindingsInterface.cc
index 1b20995..84cd31d 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsObjectTypeBindingsInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsObjectTypeBindingsInterface.cc
@@ -201,6 +201,17 @@
JSBool get_arbitraryObject(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ObjectTypeBindingsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -245,6 +256,17 @@
JSBool get_baseInterface(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ObjectTypeBindingsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -267,6 +289,17 @@
JSBool get_derivedInterface(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ObjectTypeBindingsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -311,6 +344,17 @@
JSBool get_objectProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<ObjectTypeBindingsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsOperationsTestInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsOperationsTestInterface.cc
index b30eecb..c264d39 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsOperationsTestInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsOperationsTestInterface.cc
@@ -738,6 +738,10 @@
MozjsGlobalEnvironment* global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ JS::RootedObject object(context);
+ if (arg.isObject()) {
+ object = JSVAL_TO_OBJECT(arg);
+ }
if (arg.isNumber()) {
return fcn_overloadedFunction2(
context, argc, vp);
@@ -759,8 +763,12 @@
MozjsGlobalEnvironment* global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ JS::RootedObject object(context);
+ if (arg.isObject()) {
+ object = JSVAL_TO_OBJECT(arg);
+ }
if (arg.isObject() ? wrapper_factory->DoesObjectImplementInterface(
- JSVAL_TO_OBJECT(arg), base::GetTypeId<ArbitraryInterface>()) :
+ object, base::GetTypeId<ArbitraryInterface>()) :
false) {
return fcn_overloadedFunction5(
context, argc, vp);
@@ -883,6 +891,10 @@
MozjsGlobalEnvironment* global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ JS::RootedObject object(context);
+ if (arg.isObject()) {
+ object = JSVAL_TO_OBJECT(arg);
+ }
if (arg.isNullOrUndefined()) {
return fcn_overloadedNullable2(
context, argc, vp);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsPutForwardsInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsPutForwardsInterface.cc
index 870e3a3..c5946c1 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsPutForwardsInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsPutForwardsInterface.cc
@@ -193,6 +193,17 @@
JSBool get_forwardingAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<PutForwardsInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsStaticPropertiesInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsStaticPropertiesInterface.cc
index 02ad356..82a5868 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsStaticPropertiesInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsStaticPropertiesInterface.cc
@@ -425,6 +425,10 @@
MozjsGlobalEnvironment* global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ JS::RootedObject object(context);
+ if (arg.isObject()) {
+ object = JSVAL_TO_OBJECT(arg);
+ }
if (arg.isNumber()) {
return staticfcn_staticFunction2(
context, argc, vp);
@@ -446,8 +450,12 @@
MozjsGlobalEnvironment* global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ JS::RootedObject object(context);
+ if (arg.isObject()) {
+ object = JSVAL_TO_OBJECT(arg);
+ }
if (arg.isObject() ? wrapper_factory->DoesObjectImplementInterface(
- JSVAL_TO_OBJECT(arg), base::GetTypeId<ArbitraryInterface>()) :
+ object, base::GetTypeId<ArbitraryInterface>()) :
false) {
return staticfcn_staticFunction5(
context, argc, vp);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsStringifierAttributeInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsStringifierAttributeInterface.cc
index b1b8349..e6a70f8 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsStringifierAttributeInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsStringifierAttributeInterface.cc
@@ -189,6 +189,17 @@
JSBool get_theStringifierAttribute(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<StringifierAttributeInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsUnionTypesInterface.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsUnionTypesInterface.cc
index 5c9b31f..698be31 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsUnionTypesInterface.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsUnionTypesInterface.cc
@@ -197,6 +197,17 @@
JSBool get_unionProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<UnionTypesInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -241,6 +252,17 @@
JSBool get_unionWithNullableMemberProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<UnionTypesInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -285,6 +307,17 @@
JSBool get_nullableUnionProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<UnionTypesInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -329,6 +362,17 @@
JSBool get_unionBaseProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<UnionTypesInterface>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
diff --git a/src/cobalt/bindings/generated/mozjs/testing/MozjsWindow.cc b/src/cobalt/bindings/generated/mozjs/testing/MozjsWindow.cc
index 0a5ddd1..f6d8a45 100644
--- a/src/cobalt/bindings/generated/mozjs/testing/MozjsWindow.cc
+++ b/src/cobalt/bindings/generated/mozjs/testing/MozjsWindow.cc
@@ -382,6 +382,17 @@
JSBool get_windowProperty(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<Window>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -426,6 +437,17 @@
JSBool get_window(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<Window>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
MozjsExceptionState exception_state(context);
JS::RootedValue result_value(context);
@@ -467,12 +489,12 @@
WrapperPrivate::GetFromObject(context, object);
Window* impl =
wrapper_private->wrappable<Window>().get();
- MozjsGlobalEnvironment* global_environment =
+ MozjsGlobalEnvironment* callwith_global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
if (!exception_state.is_exception_set()) {
ToJSValue(context,
- impl->GetStackTrace(global_environment->GetStackTrace()),
+ impl->GetStackTrace(callwith_global_environment->GetStackTrace()),
&result_value);
}
if (!exception_state.is_exception_set()) {
diff --git a/src/cobalt/bindings/mozjs/code_generator.py b/src/cobalt/bindings/mozjs/code_generator.py
index 12ac5fb..c99c10a 100644
--- a/src/cobalt/bindings/mozjs/code_generator.py
+++ b/src/cobalt/bindings/mozjs/code_generator.py
@@ -42,8 +42,8 @@
def inherits_interface(self, interface_name, arg):
return ('%s.isObject() ?'
' wrapper_factory->DoesObjectImplementInterface(\n'
- ' JSVAL_TO_OBJECT(%s), base::GetTypeId<%s>()) :\n'
- ' false') % (arg, arg, interface_name)
+ ' object, base::GetTypeId<%s>()) :\n'
+ ' false') % (arg, interface_name)
def is_number(self, arg):
return '%s.isNumber()' % arg
diff --git a/src/cobalt/bindings/mozjs/templates/interface.cc.template b/src/cobalt/bindings/mozjs/templates/interface.cc.template
index eb4e553..dcc3e7c 100644
--- a/src/cobalt/bindings/mozjs/templates/interface.cc.template
+++ b/src/cobalt/bindings/mozjs/templates/interface.cc.template
@@ -458,6 +458,17 @@
JSBool get_{{attribute.idl_name}}(
JSContext* context, JS::HandleObject object, JS::HandleId id,
JS::MutableHandleValue vp) {
+ MozjsGlobalEnvironment* global_environment =
+ static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
+ WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ if (!wrapper_factory->DoesObjectImplementInterface(
+ object, base::GetTypeId<{{impl_class}}>())) {
+ MozjsExceptionState exception(context);
+ exception.SetSimpleException(script::kDoesNotImplementInterface);
+ vp.set(JS::UndefinedValue());
+ return false;
+ }
+
{{ nonstatic_function_prologue(impl_class) }}
{% endif %}
{{ call_cobalt_function(impl_class, attribute.type,
diff --git a/src/cobalt/bindings/mozjs/templates/macros.cc.template b/src/cobalt/bindings/mozjs/templates/macros.cc.template
index f9153c7..8520293 100644
--- a/src/cobalt/bindings/mozjs/templates/macros.cc.template
+++ b/src/cobalt/bindings/mozjs/templates/macros.cc.template
@@ -256,10 +256,10 @@
#}
{% macro add_extra_arguments(arguments_list, raises_exception, call_with) %}
{% if call_with %}
- MozjsGlobalEnvironment* global_environment =
+ MozjsGlobalEnvironment* callwith_global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
-{% do arguments_list.insert(0,
- 'global_environment->Get%s()'|format(call_with)) %}
+{% do arguments_list.insert(
+ 0, 'callwith_global_environment->Get%s()'|format(call_with)) %}
{% endif %}
{% do arguments_list.append('&exception_state') if raises_exception %}
{%- endmacro %}
@@ -372,6 +372,10 @@
MozjsGlobalEnvironment* global_environment =
static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
+ JS::RootedObject object(context);
+ if (arg.isObject()) {
+ object = JSVAL_TO_OBJECT(arg);
+ }
{% endif %}
{% for test, overload in resolution_tests %}
if ({{test("arg")}}) {
diff --git a/src/cobalt/browser/application.cc b/src/cobalt/browser/application.cc
index bde2b8f..fe26699 100644
--- a/src/cobalt/browser/application.cc
+++ b/src/cobalt/browser/application.cc
@@ -558,10 +558,14 @@
DLOG(INFO) << "Got suspend event.";
app_status_ = kSuspendedAppStatus;
++app_suspend_count_;
+ browser_module_->Suspend();
+ DLOG(INFO) << "Finished suspending.";
} else if (app_event->type() == system_window::ApplicationEvent::kResume) {
DLOG(INFO) << "Got resume event.";
app_status_ = kPausedAppStatus;
++app_resume_count_;
+ browser_module_->Resume();
+ DLOG(INFO) << "Finished resuming.";
}
}
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index 621c12a..1532cca 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -141,7 +141,7 @@
options.media_module_options)),
network_module_(&storage_manager_, system_window->event_dispatcher(),
options.network_module_options),
- render_tree_combiner_(renderer_module_.pipeline(),
+ render_tree_combiner_(&renderer_module_,
renderer_module_.render_target()->GetSize()),
#if defined(ENABLE_SCREENSHOT)
screen_shot_writer_(new ScreenShotWriter(renderer_module_.pipeline())),
@@ -169,7 +169,8 @@
h5vcc_url_handler_(this, system_window, account_manager)),
web_module_options_(options.web_module_options),
has_resumed_(true, false),
- will_quit_(false) {
+ will_quit_(false),
+ suspended_(false) {
// Setup our main web module to have the H5VCC API injected into it.
DCHECK(!ContainsKey(web_module_options_.injected_window_attributes, "h5vcc"));
h5vcc::H5vcc::Settings h5vcc_settings;
@@ -619,6 +620,73 @@
network_module_.SetProxy(proxy_rules);
}
+void BrowserModule::Suspend() {
+ DCHECK_EQ(MessageLoop::current(), self_message_loop_);
+ DCHECK(!suspended_);
+
+// First suspend all our web modules which implies that they will release their
+// resource provider and all resources created through it.
+#if defined(ENABLE_DEBUG_CONSOLE)
+ if (debug_console_) {
+ debug_console_->Suspend();
+ }
+#endif
+ if (splash_screen_) {
+ splash_screen_->Suspend();
+ }
+ if (web_module_) {
+ web_module_->Suspend();
+ }
+
+ // Flush out any submitted render trees pushed since we started shutting down
+ // the web modules above.
+ render_tree_submission_queue_.ProcessAll();
+
+#if defined(ENABLE_SCREENSHOT)
+ // The screenshot writer may be holding on to a reference to a render tree
+ // which could in turn be referencing resources like images, so clear that
+ // out.
+ screen_shot_writer_->ClearLastPipelineSubmission();
+#endif
+
+ // Clear out the render tree combiner so that it doesn't hold on to any
+ // render tree resources either.
+ render_tree_combiner_.Reset();
+
+ // Place the renderer module into a suspended state where it releases all its
+ // graphical resources.
+ renderer_module_.Suspend();
+
+ suspended_ = true;
+}
+
+void BrowserModule::Resume() {
+ DCHECK_EQ(MessageLoop::current(), self_message_loop_);
+ DCHECK(suspended_);
+
+ renderer_module_.Resume();
+
+ // Note that at this point, it is probable that this resource provider is
+ // different than the one that was managed in the associated call to
+ // Suspend().
+ render_tree::ResourceProvider* resource_provider =
+ renderer_module_.pipeline()->GetResourceProvider();
+
+#if defined(ENABLE_DEBUG_CONSOLE)
+ if (debug_console_) {
+ debug_console_->Resume(resource_provider);
+ }
+#endif
+ if (splash_screen_) {
+ splash_screen_->Resume(resource_provider);
+ }
+ if (web_module_) {
+ web_module_->Resume(resource_provider);
+ }
+
+ suspended_ = false;
+}
+
#if defined(OS_STARBOARD)
void BrowserModule::OnRendererSubmissionRasterized() {
if (!is_rendered_) {
diff --git a/src/cobalt/browser/browser_module.h b/src/cobalt/browser/browser_module.h
index d589084..82322b3 100644
--- a/src/cobalt/browser/browser_module.h
+++ b/src/cobalt/browser/browser_module.h
@@ -113,6 +113,13 @@
// Change the network proxy settings while the application is running.
void SetProxy(const std::string& proxy_rules);
+ // Suspends the browser module from activity, and releases all graphical
+ // resources, placing the application into a low-memory state.
+ void Suspend();
+
+ // Undoes the call to Suspend(), returning to normal functionality.
+ void Resume();
+
private:
// Recreates web module with the given URL.
void NavigateInternal(const GURL& url);
@@ -327,6 +334,8 @@
// this object) and read from another. This lock is used to
// ensure synchronous access.
base::Lock quit_lock_;
+
+ bool suspended_;
};
} // namespace browser
diff --git a/src/cobalt/browser/debug_console.cc b/src/cobalt/browser/debug_console.cc
index b02557d..332eebb 100644
--- a/src/cobalt/browser/debug_console.cc
+++ b/src/cobalt/browser/debug_console.cc
@@ -221,6 +221,12 @@
return mode_;
}
+void DebugConsole::Suspend() { web_module_->Suspend(); }
+
+void DebugConsole::Resume(render_tree::ResourceProvider* resource_provider) {
+ web_module_->Resume(resource_provider);
+}
+
} // namespace browser
} // namespace cobalt
diff --git a/src/cobalt/browser/debug_console.h b/src/cobalt/browser/debug_console.h
index f15a8a6..527298d 100644
--- a/src/cobalt/browser/debug_console.h
+++ b/src/cobalt/browser/debug_console.h
@@ -60,6 +60,9 @@
// Returns the currently set debug console visibility mode.
int GetMode();
+ void Suspend();
+ void Resume(render_tree::ResourceProvider* resource_provider);
+
private:
void OnError(const GURL& /* url */, const std::string& error) {
LOG(ERROR) << error;
diff --git a/src/cobalt/browser/render_tree_combiner.cc b/src/cobalt/browser/render_tree_combiner.cc
index 15b35cb..364158b 100644
--- a/src/cobalt/browser/render_tree_combiner.cc
+++ b/src/cobalt/browser/render_tree_combiner.cc
@@ -23,14 +23,20 @@
namespace browser {
#if defined(ENABLE_DEBUG_CONSOLE)
-RenderTreeCombiner::RenderTreeCombiner(renderer::Pipeline* renderer_pipeline,
- const math::Size& viewport_size)
+RenderTreeCombiner::RenderTreeCombiner(
+ renderer::RendererModule* renderer_module, const math::Size& viewport_size)
: render_debug_console_(true),
- renderer_pipeline_(renderer_pipeline),
+ renderer_module_(renderer_module),
viewport_size_(viewport_size) {}
RenderTreeCombiner::~RenderTreeCombiner() {}
+void RenderTreeCombiner::Reset() {
+ main_render_tree_ = base::nullopt;
+ debug_console_render_tree_ = base::nullopt;
+ main_render_tree_receipt_time_ = base::nullopt;
+}
+
void RenderTreeCombiner::UpdateMainRenderTree(
const renderer::Submission& render_tree_submission) {
main_render_tree_ = render_tree_submission;
@@ -62,7 +68,7 @@
main_render_tree_->time_offset +
(base::TimeTicks::HighResNow() - *main_render_tree_receipt_time_);
- renderer_pipeline_->Submit(combined_submission);
+ renderer_module_->pipeline()->Submit(combined_submission);
} else {
// If we are rendering the debug console by itself, give it a solid black
// background to it.
@@ -76,24 +82,26 @@
renderer::Submission combined_submission(*debug_console_render_tree_);
combined_submission.render_tree =
new render_tree::CompositionNode(builder);
- renderer_pipeline_->Submit(combined_submission);
+ renderer_module_->pipeline()->Submit(combined_submission);
}
} else if (main_render_tree_) {
- renderer_pipeline_->Submit(*main_render_tree_);
+ renderer_module_->pipeline()->Submit(*main_render_tree_);
}
}
#else // ENABLE_DEBUG_CONSOLE
-RenderTreeCombiner::RenderTreeCombiner(renderer::Pipeline* renderer_pipeline,
- const math::Size& viewport_size)
- : renderer_pipeline_(renderer_pipeline) {
+RenderTreeCombiner::RenderTreeCombiner(
+ renderer::RendererModule* renderer_module, const math::Size& viewport_size)
+ : renderer_module_(renderer_module) {
UNREFERENCED_PARAMETER(viewport_size);
}
RenderTreeCombiner::~RenderTreeCombiner() {}
+void RenderTreeCombiner::Reset() {}
+
void RenderTreeCombiner::UpdateMainRenderTree(
const renderer::Submission& render_tree_submission) {
- renderer_pipeline_->Submit(render_tree_submission);
+ renderer_module_->pipeline()->Submit(render_tree_submission);
}
void RenderTreeCombiner::UpdateDebugConsoleRenderTree(
diff --git a/src/cobalt/browser/render_tree_combiner.h b/src/cobalt/browser/render_tree_combiner.h
index 9f3456a..44f38d6 100644
--- a/src/cobalt/browser/render_tree_combiner.h
+++ b/src/cobalt/browser/render_tree_combiner.h
@@ -17,7 +17,7 @@
#ifndef COBALT_BROWSER_RENDER_TREE_COMBINER_H_
#define COBALT_BROWSER_RENDER_TREE_COMBINER_H_
-#include "cobalt/renderer/pipeline.h"
+#include "cobalt/renderer/renderer_module.h"
#include "cobalt/renderer/submission.h"
namespace cobalt {
@@ -29,10 +29,12 @@
// otherwise (e.g. in release builds) a stub implementation is used.
class RenderTreeCombiner {
public:
- explicit RenderTreeCombiner(renderer::Pipeline* renderer_pipeline,
+ explicit RenderTreeCombiner(renderer::RendererModule* renderer_module,
const math::Size& viewport_size);
~RenderTreeCombiner();
+ void Reset();
+
// Update the main web module render tree.
void UpdateMainRenderTree(const renderer::Submission& render_tree_submission);
@@ -61,7 +63,7 @@
// Local reference to the render pipeline, so we can submit the combined tree.
// Reference counted pointer not necessary here.
- renderer::Pipeline* renderer_pipeline_;
+ renderer::RendererModule* renderer_module_;
// The size of the output viewport.
math::Size viewport_size_;
@@ -79,7 +81,7 @@
base::optional<renderer::Submission> debug_console_render_tree_;
#else // ENABLE_DEBUG_CONSOLE
// Use this local reference even in release builds to submit the main tree.
- renderer::Pipeline* renderer_pipeline_;
+ renderer::RendererModule* renderer_module_;
#endif // ENABLE_DEBUG_CONSOLE
};
diff --git a/src/cobalt/browser/screen_shot_writer.cc b/src/cobalt/browser/screen_shot_writer.cc
index 5003558..9dac1a4 100644
--- a/src/cobalt/browser/screen_shot_writer.cc
+++ b/src/cobalt/browser/screen_shot_writer.cc
@@ -82,6 +82,10 @@
last_submission_time_ = base::TimeTicks::HighResNow();
}
+void ScreenShotWriter::ClearLastPipelineSubmission() {
+ last_submission_ = base::nullopt;
+}
+
void ScreenShotWriter::RasterizationComplete(
const PNGEncodeCompleteCallback& encode_complete_callback,
scoped_array<uint8> pixel_data, const math::Size& dimensions) {
diff --git a/src/cobalt/browser/screen_shot_writer.h b/src/cobalt/browser/screen_shot_writer.h
index 8e4de5d..eb24115 100644
--- a/src/cobalt/browser/screen_shot_writer.h
+++ b/src/cobalt/browser/screen_shot_writer.h
@@ -57,6 +57,11 @@
// screenshot is requested.
void SetLastPipelineSubmission(const renderer::Submission& submission);
+ // Clears the last submission from the pipeline, putting the ScreenShotWriter
+ // into a state similar to when it was first created, where there was no
+ // "last pipeline submission".
+ void ClearLastPipelineSubmission();
+
private:
// Callback function that will be fired from the rasterizer thread when
// rasterization of |last_submission_| is complete.
diff --git a/src/cobalt/browser/splash_screen.cc b/src/cobalt/browser/splash_screen.cc
index 804b92d..a2a3d97 100644
--- a/src/cobalt/browser/splash_screen.cc
+++ b/src/cobalt/browser/splash_screen.cc
@@ -42,5 +42,10 @@
layout_refresh_rate, web_module_options));
}
+void SplashScreen::Suspend() { web_module_->Suspend(); }
+void SplashScreen::Resume(render_tree::ResourceProvider* resource_provider) {
+ web_module_->Resume(resource_provider);
+}
+
} // namespace browser
} // namespace cobalt
diff --git a/src/cobalt/browser/splash_screen.h b/src/cobalt/browser/splash_screen.h
index 24a18f9..a105fe4 100644
--- a/src/cobalt/browser/splash_screen.h
+++ b/src/cobalt/browser/splash_screen.h
@@ -45,6 +45,9 @@
render_tree::ResourceProvider* resource_provider,
float layout_refresh_rate, const Options& options = Options());
+ void Suspend();
+ void Resume(render_tree::ResourceProvider* resource_provider);
+
private:
void OnError(const GURL& /* url */, const std::string& error) {
LOG(ERROR) << error;
diff --git a/src/cobalt/browser/testdata/mtm-demo/README.txt b/src/cobalt/browser/testdata/mtm-demo/README.txt
new file mode 100644
index 0000000..5368357
--- /dev/null
+++ b/src/cobalt/browser/testdata/mtm-demo/README.txt
@@ -0,0 +1,37 @@
+These test whether the presence of the CSS MTM filter affect the path taken in
+rendering the video replaced box. <normal.html> has a video tag without the
+filter, while <mtm.html> has a video with the filter applied to it.
+
+To test locally, all 3 of mtm.html, normal.html and progressive.mp4 have to be
+hosted on a server that supports HTTP RANGE header, which is needed for video to
+be loaded correctly. One such server is the extension to the Python
+SimpleHTTPServer at https://github.com/danvk/RangeHTTPServer (run from this
+directory, "cobalt/src/cobalt/browser/testdata/mtm-demo/"):
+
+ $ sudo apt-get install python-pip
+ $ pip install --user rangehttpserver
+ $ python -m RangeHTTPServer
+
+Test video without the MTM filter (should render normally, run from cobalt/src
+directory):
+
+ $ out/linux-x64x11_debug/cobalt --csp_mode=disable --allow_http --url=http://localhost:8000/normal.html
+
+Test the video with the MTM filter (should NOT render in its bounding box in the
+document, and in the presence of the correct rasterizer, should be rendered onto
+its own texture off the main UI layout):
+
+ $ out/linux-x64x11_debug/cobalt --csp_mode=disable --allow_http --url=http://localhost:8000/mtm.html
+
+There is also the option of using the google cloud utils and the cloud storage
+to publish these files, as is done with the other demos. Care should be taken
+that nothing confidential gets uploaded with these files. "public-read" is
+needed in the ACL because linking and video srcing does not work without it.
+
+A bucket specifically for this demo already exists at "gs://yt-cobalt-mtm-test",
+but uploading to it often might be problematic since buckets are not verison-
+controlled:
+
+ $ gsutil cp -a public-read cobalt/browser/testdata/mtm-demo/normal.html cobalt/browser/testdata/mtm-demo/mtm.html cobalt/browser/testdata/mtm-demo/progressive.mp4 gs://yt-cobalt-mtm-test/
+ $ out/linux-x64x11_debug/cobalt --csp_mode=disable --url=https://storage.googleapis.com/yt-cobalt-mtm-test/mtm.html
+ $ out/linux-x64x11_debug/cobalt --csp_mode=disable --url=https://storage.googleapis.com/yt-cobalt-mtm-test/normal.html
diff --git a/src/cobalt/browser/testdata/mtm-demo/mtm.html b/src/cobalt/browser/testdata/mtm-demo/mtm.html
new file mode 100644
index 0000000..6877674
--- /dev/null
+++ b/src/cobalt/browser/testdata/mtm-demo/mtm.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>mtm Demo</title>
+ <style>
+ body {
+ background-color: rgb(255, 255, 255);
+ color: #0047ab;
+ font-size: 100px;
+ }
+ .vid {
+ margin: 100px;
+ border: 10px solid blue;
+ width: 960px;
+ height: 540px;
+ filter: -cobalt-mtm(url(projection.msh), 100deg 60deg,
+ matrix3d(1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1));
+ }
+ </style>
+</head>
+<body>
+ <div>Mtm Demo!!!</div>
+ <video autoplay loop id="v" class="vid" src="progressive.mp4"></video>
+</body>
+</html>
diff --git a/src/cobalt/browser/testdata/mtm-demo/normal.html b/src/cobalt/browser/testdata/mtm-demo/normal.html
new file mode 100644
index 0000000..3d516f6
--- /dev/null
+++ b/src/cobalt/browser/testdata/mtm-demo/normal.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Normal Demo</title>
+ <style>
+ body {
+ background-color: rgb(255, 255, 255);
+ color: #0047ab;
+ font-size: 100px;
+ }
+ .vid {
+ margin: 100px;
+ border: 10px solid blue;
+ width: 960px;
+ height: 540px;
+ }
+ </style>
+</head>
+<body>
+ <div>Normal Demo</div>
+ <video autoplay loop id="v" class="vid" src="progressive.mp4"></video>
+</body>
+</html>
diff --git a/src/cobalt/browser/testdata/mtm-demo/progressive.mp4 b/src/cobalt/browser/testdata/mtm-demo/progressive.mp4
new file mode 100644
index 0000000..2686a9b
--- /dev/null
+++ b/src/cobalt/browser/testdata/mtm-demo/progressive.mp4
Binary files differ
diff --git a/src/cobalt/browser/web_module.cc b/src/cobalt/browser/web_module.cc
index 7932196..775f7e6 100644
--- a/src/cobalt/browser/web_module.cc
+++ b/src/cobalt/browser/web_module.cc
@@ -108,6 +108,9 @@
void CreateDebugServerIfNull();
#endif // ENABLE_DEBUG_CONSOLE
+ void Suspend();
+ void Resume(render_tree::ResourceProvider* resource_provider);
+
private:
class DocumentLoadedObserver;
@@ -141,6 +144,9 @@
// Simple flag used for basic error checking.
bool is_running_;
+ // Object that provides renderer resources like images and fonts.
+ render_tree::ResourceProvider* resource_provider_;
+
// CSS parser.
scoped_ptr<css_parser::Parser> css_parser_;
@@ -150,6 +156,10 @@
// FetcherFactory that is used to create a fetcher according to URL.
scoped_ptr<loader::FetcherFactory> fetcher_factory_;
+ // LoaderFactory that is used to acquire references to resources from a
+ // URL.
+ scoped_ptr<loader::LoaderFactory> loader_factory_;
+
// ImageCache that is used to manage image cache logic.
scoped_ptr<loader::image::ImageCache> image_cache_;
@@ -211,7 +221,6 @@
// Allows the debugger to add render components to the web module.
// Used for DOM node highlighting and overlay messages.
scoped_ptr<debug::RenderOverlay> debug_overlay_;
- render_tree::ResourceProvider* resource_provider_;
// The core of the debugging system, described here:
// https://docs.google.com/document/d/1lZhrBTusQZJsacpt21J3kPgnkj7pyQObhFqYktvm40Y
@@ -249,6 +258,8 @@
WebModule::Impl::Impl(const ConstructionData& data)
: name_(data.options.name), is_running_(false) {
+ resource_provider_ = data.resource_provider;
+
css_parser_ = css_parser::Parser::Create();
DCHECK(css_parser_);
@@ -261,11 +272,14 @@
data.network_module, data.options.extra_web_file_dir));
DCHECK(fetcher_factory_);
+ loader_factory_.reset(
+ new loader::LoaderFactory(fetcher_factory_.get(), resource_provider_));
+
DCHECK_LE(0, data.options.image_cache_capacity);
image_cache_ = loader::image::CreateImageCache(
base::StringPrintf("Memory.%s.ImageCache", name_.c_str()),
static_cast<uint32>(data.options.image_cache_capacity),
- data.resource_provider, fetcher_factory_.get());
+ loader_factory_.get());
DCHECK(image_cache_);
reduced_image_cache_capacity_manager_.reset(
@@ -277,7 +291,7 @@
remote_typeface_cache_ = loader::font::CreateRemoteTypefaceCache(
base::StringPrintf("Memory.%s.RemoteTypefaceCache", name_.c_str()),
static_cast<uint32>(data.options.remote_typeface_cache_capacity),
- data.resource_provider, fetcher_factory_.get());
+ loader_factory_.get());
DCHECK(remote_typeface_cache_);
local_storage_database_.reset(
@@ -307,7 +321,7 @@
window_ = new dom::Window(
data.window_dimensions.width(), data.window_dimensions.height(),
css_parser_.get(), dom_parser_.get(), fetcher_factory_.get(),
- data.resource_provider, image_cache_.get(),
+ &resource_provider_, image_cache_.get(),
reduced_image_cache_capacity_manager_.get(), remote_typeface_cache_.get(),
local_storage_database_.get(), data.media_module, data.media_module,
execution_state_.get(), script_runner_.get(),
@@ -348,10 +362,11 @@
web_module_stat_tracker_->layout_stat_tracker()));
DCHECK(layout_manager_);
+ resource_provider_ = data.resource_provider;
+
#if defined(ENABLE_DEBUG_CONSOLE)
debug_overlay_.reset(
new debug::RenderOverlay(data.render_tree_produced_callback));
- resource_provider_ = data.resource_provider;
#endif // ENABLE_DEBUG_CONSOLE
#if !defined(COBALT_FORCE_CSP)
@@ -534,6 +549,44 @@
}
}
+void WebModule::Impl::Suspend() {
+ TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Suspend()");
+ DCHECK(resource_provider_);
+
+ // Stop the generation of render trees.
+ layout_manager_->Suspend();
+
+ // Clear out all image resources from the image cache.
+ image_cache_->Purge();
+
+#if defined(ENABLE_DEBUG_CONSOLE)
+ // The debug overlay may be holding onto a render tree, clear that out.
+ debug_overlay_->ClearInput();
+#endif
+
+ // Clear out the loader factory's resource provider, possibly aborting any
+ // in-progress loads.
+ loader_factory_->Suspend();
+
+ // Finally mark that we have no resource provider.
+ resource_provider_ = NULL;
+}
+
+void WebModule::Impl::Resume(render_tree::ResourceProvider* resource_provider) {
+ TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Resume()");
+ DCHECK(resource_provider);
+ DCHECK(!resource_provider_);
+
+ resource_provider_ = resource_provider;
+
+ loader_factory_->Resume(resource_provider_);
+
+ // Permit render trees to be generated again. Layout will have been
+ // invalidated with the call to Suspend(), so the layout manager's first task
+ // will be to perform a full re-layout.
+ layout_manager_->Resume();
+}
+
WebModule::DestructionObserver::DestructionObserver(WebModule* web_module)
: web_module_(web_module) {}
@@ -736,5 +789,24 @@
}
#endif // defined(ENABLE_DEBUG_CONSOLE)
+void WebModule::Suspend() {
+ message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&WebModule::Impl::Suspend, base::Unretained(impl_.get())));
+
+ base::WaitableEvent resource_provider_released(true, false);
+ message_loop()->PostTask(
+ FROM_HERE, base::Bind(&base::WaitableEvent::Signal,
+ base::Unretained(&resource_provider_released)));
+
+ resource_provider_released.Wait();
+}
+
+void WebModule::Resume(render_tree::ResourceProvider* resource_provider) {
+ message_loop()->PostTask(
+ FROM_HERE, base::Bind(&WebModule::Impl::Resume,
+ base::Unretained(impl_.get()), resource_provider));
+}
+
} // namespace browser
} // namespace cobalt
diff --git a/src/cobalt/browser/web_module.h b/src/cobalt/browser/web_module.h
index 55706e7..4987ebe 100644
--- a/src/cobalt/browser/web_module.h
+++ b/src/cobalt/browser/web_module.h
@@ -182,6 +182,14 @@
debug::DebugServer* GetDebugServer();
#endif // ENABLE_DEBUG_CONSOLE
+ // Suspends the WebModule from creating new render trees, and releases this
+ // web module's reference to the resource provider, clearing it out and
+ // releasing all references to any resources created from it.
+ void Suspend();
+ // Resumes the WebModule, possibly with a new resource provider. This method
+ // can only be called if we have previously suspended the WebModule.
+ void Resume(render_tree::ResourceProvider* resource_provider);
+
#if defined(COBALT_BUILD_TYPE_DEBUG)
// Non-optimized builds require a bigger stack size.
static const size_t kBaseStackSize = 2 * 1024 * 1024;
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index e3f28c7..66974b8 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-12096
\ No newline at end of file
+12347
\ No newline at end of file
diff --git a/src/cobalt/css_parser/grammar.h b/src/cobalt/css_parser/grammar.h
index 7168cb1..6842105 100644
--- a/src/cobalt/css_parser/grammar.h
+++ b/src/cobalt/css_parser/grammar.h
@@ -55,6 +55,8 @@
#include "cobalt/cssom/css_style_declaration.h"
#include "cobalt/cssom/css_style_rule.h"
#include "cobalt/cssom/css_style_sheet.h"
+#include "cobalt/cssom/filter_function.h"
+#include "cobalt/cssom/filter_function_list_value.h"
#include "cobalt/cssom/integer_value.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/cssom/length_value.h"
@@ -64,6 +66,7 @@
#include "cobalt/cssom/media_feature_keyword_value.h"
#include "cobalt/cssom/media_list.h"
#include "cobalt/cssom/media_query.h"
+#include "cobalt/cssom/mtm_function.h"
#include "cobalt/cssom/number_value.h"
#include "cobalt/cssom/percentage_value.h"
#include "cobalt/cssom/property_key_list_value.h"
@@ -78,6 +81,8 @@
#include "cobalt/cssom/transform_function.h"
#include "cobalt/cssom/transform_function_list_value.h"
#include "cobalt/cssom/url_src_value.h"
+#include "third_party/glm/glm/gtc/type_ptr.hpp"
+#include "third_party/glm/glm/mat4x4.hpp"
namespace cobalt {
namespace css_parser {
diff --git a/src/cobalt/css_parser/grammar.y b/src/cobalt/css_parser/grammar.y
index 34a7143..a1b62f7 100644
--- a/src/cobalt/css_parser/grammar.y
+++ b/src/cobalt/css_parser/grammar.y
@@ -114,6 +114,7 @@
%token kColorToken // color
%token kContentToken // content
%token kDisplayToken // display
+%token kFilterToken // filter
%token kFontToken // font
%token kFontFamilyToken // font-family
%token kFontSizeToken // font-size
@@ -353,6 +354,7 @@
%token kLinearGradientFunctionToken // linear-gradient(
%token kLocalFunctionToken // local(
%token kMatrixFunctionToken // matrix(
+%token kMatrix3dFunctionToken // matrix3d(
%token kNotFunctionToken // not(
%token kNthChildFunctionToken // nth-child(
%token kNthLastChildFunctionToken // nth-last-child(
@@ -370,6 +372,7 @@
%token kRadialGradientFunctionToken // radial-gradient(
%token kRGBFunctionToken // rgb(
%token kRGBAFunctionToken // rgba(
+%token kCobaltMtmFunctionToken // -cobalt-mtm(
// Tokens with a string value.
%token <string> kStringToken // "...", '...'
@@ -582,8 +585,17 @@
white_space_property_value
width_property_value
z_index_property_value
+ filter_property_value
%destructor { SafeRelease($$); } <property_value>
+%union { std::vector<float>* number_matrix; }
+%type <number_matrix> number_matrix
+%destructor { delete $$; } <number_matrix>
+
+%union { glm::mat4* matrix4x4; }
+%type <matrix4x4> cobalt_mtm_transform_function
+%destructor { delete $$; } <matrix4x4>
+
%union { MarginOrPaddingShorthand* margin_or_padding_shorthand; }
%type <margin_or_padding_shorthand> margin_property_value padding_property_value
%destructor { delete $$; } <margin_or_padding_shorthand>
@@ -763,6 +775,24 @@
%type <transform_functions> transform_list
%destructor { delete $$; } <transform_functions>
+%union { cssom::FilterFunction* filter_function; }
+%type <filter_function> cobalt_mtm_filter_function
+%type <filter_function> filter_function
+%destructor { delete $$; } <filter_function>
+
+%union { cssom::FilterFunctionListValue::Builder* cobalt_mtm_filter_functions; }
+%type <cobalt_mtm_filter_functions> filter_function_list
+%destructor { delete $$; } <cobalt_mtm_filter_functions>
+
+%union {
+ cssom::MTMFunction::ResolutionMatchedMeshListBuilder* cobalt_mtm_resolution_matched_meshes; }
+%type <cobalt_mtm_resolution_matched_meshes> cobalt_mtm_resolution_matched_mesh_list
+%destructor { delete $$; } <cobalt_mtm_resolution_matched_meshes>
+
+%union { cssom::MTMFunction::ResolutionMatchedMesh* cobalt_mtm_resolution_matched_mesh; }
+%type <cobalt_mtm_resolution_matched_mesh> cobalt_mtm_resolution_matched_mesh
+%destructor { delete $$; } <cobalt_mtm_resolution_matched_mesh>
+
%union { cssom::TimeListValue::Builder* time_list; }
%type <time_list> comma_separated_time_list
%destructor { delete $$; } <time_list>
@@ -1371,6 +1401,10 @@
$$ = TrivialStringPiece::FromCString(
cssom::GetPropertyName(cssom::kDisplayProperty));
}
+ | kFilterToken {
+ $$ = TrivialStringPiece::FromCString(
+ cssom::GetPropertyName(cssom::kFilterProperty));
+ }
| kFontToken {
$$ = TrivialStringPiece::FromCString(
cssom::GetPropertyName(cssom::kFontProperty));
@@ -5761,6 +5795,12 @@
MakeScopedRefPtrAndRelease($4), $5)
: NULL;
}
+ | kFilterToken maybe_whitespace colon filter_property_value
+ maybe_important {
+ $$ = $4 ? new PropertyDeclaration(cssom::kFilterProperty,
+ MakeScopedRefPtrAndRelease($4), $5)
+ : NULL;
+ }
| kFontToken maybe_whitespace colon font_property_value maybe_important {
scoped_ptr<FontShorthand> font($4);
DCHECK(font);
@@ -6406,3 +6446,99 @@
}
}
;
+
+// Filters that can be applied to the object's rendering.
+// https://www.w3.org/TR/filter-effects-1/#FilterProperty
+filter_property_value:
+ kNoneToken maybe_whitespace {
+ $$ = AddRef(cssom::KeywordValue::GetNone().get());
+ }
+ | filter_function_list {
+ scoped_ptr<cssom::FilterFunctionListValue::Builder> property_value($1);
+ $$ = AddRef(new cssom::FilterFunctionListValue(property_value->Pass()));
+ }
+ | common_values
+ ;
+
+filter_function_list:
+ // TODO: Parse list of filter_function's. This only parses one-element lists.
+ filter_function {
+ $$ = new cssom::FilterFunctionListValue::Builder();
+ $$->push_back($1);
+ }
+ ;
+
+// The set of allowed filter functions.
+// https://www.w3.org/TR/filter-effects-1/
+filter_function:
+ cobalt_mtm_filter_function {
+ $$ = $1;
+ }
+ ;
+
+cobalt_mtm_filter_function:
+ // Encodes an mtm filter. Currently the only type of filter function supported.
+ kCobaltMtmFunctionToken maybe_whitespace url
+ cobalt_mtm_resolution_matched_mesh_list comma angle angle comma
+ cobalt_mtm_transform_function ')' maybe_whitespace {
+ scoped_ptr<cssom::MTMFunction::ResolutionMatchedMeshListBuilder>
+ resolution_matched_mesh_urls($4);
+ scoped_ptr<glm::mat4> transform($9);
+
+ $$ = new cssom::MTMFunction(
+ MakeScopedRefPtrAndRelease($3),
+ resolution_matched_mesh_urls->Pass(),
+ $6,
+ $7,
+ *transform);
+ }
+ ;
+
+cobalt_mtm_resolution_matched_mesh_list:
+ /* empty */ {
+ $$ = new cssom::MTMFunction::ResolutionMatchedMeshListBuilder();
+ }
+ // Specifies a different mesh for a particular image resolution.
+ | cobalt_mtm_resolution_matched_mesh_list cobalt_mtm_resolution_matched_mesh {
+ $$ = $1;
+ $$->push_back($2);
+ }
+ ;
+
+cobalt_mtm_resolution_matched_mesh:
+ non_negative_integer non_negative_integer url {
+ $$ = new cssom::MTMFunction::ResolutionMatchedMesh($1, $2,
+ MakeScopedRefPtrAndRelease($3));
+ }
+ ;
+
+// The set of transform functions allowed in MTM filters, currently a separate
+// production hierarchy from the main <transform_function> and represented as a
+// glm::mat4.
+// https://www.w3.org/TR/css-transforms-1/#three-d-transform-functions
+cobalt_mtm_transform_function:
+ // Specifies an arbitrary affine 3D transformation, currently the only
+ // supported transform in MTM.
+ kMatrix3dFunctionToken maybe_whitespace number_matrix ')' maybe_whitespace {
+ scoped_ptr<std::vector<float> > matrix($3);
+ if (matrix == NULL || matrix->size() != 16) {
+ parser_impl->LogError(
+ @3,
+ "matrix3d function expects 16 floating-point numbers as arguments");
+ YYERROR;
+ } else {
+ // GLM and the W3 spec both use column-major order.
+ $$ = new glm::mat4(glm::make_mat4(&(*matrix)[0]));
+ }
+ }
+ ;
+
+number_matrix:
+ number {
+ $$ = new std::vector<float>(1, $1);
+ }
+ | number_matrix comma number {
+ $$ = $1;
+ $$->push_back($3);
+ }
+ ;
diff --git a/src/cobalt/css_parser/parser.cc b/src/cobalt/css_parser/parser.cc
index d289e3c..c3ff81a 100644
--- a/src/cobalt/css_parser/parser.cc
+++ b/src/cobalt/css_parser/parser.cc
@@ -66,6 +66,7 @@
#include "cobalt/cssom/matrix_function.h"
#include "cobalt/cssom/media_list.h"
#include "cobalt/cssom/media_query.h"
+#include "cobalt/cssom/mtm_function.h"
#include "cobalt/cssom/next_sibling_combinator.h"
#include "cobalt/cssom/not_pseudo_class.h"
#include "cobalt/cssom/number_value.h"
diff --git a/src/cobalt/css_parser/parser_test.cc b/src/cobalt/css_parser/parser_test.cc
index 0aaf421..85fe7c4 100644
--- a/src/cobalt/css_parser/parser_test.cc
+++ b/src/cobalt/css_parser/parser_test.cc
@@ -38,6 +38,7 @@
#include "cobalt/cssom/css_style_sheet.h"
#include "cobalt/cssom/descendant_combinator.h"
#include "cobalt/cssom/empty_pseudo_class.h"
+#include "cobalt/cssom/filter_function_list_value.h"
#include "cobalt/cssom/focus_pseudo_class.h"
#include "cobalt/cssom/following_sibling_combinator.h"
#include "cobalt/cssom/font_style_value.h"
@@ -52,6 +53,7 @@
#include "cobalt/cssom/matrix_function.h"
#include "cobalt/cssom/media_list.h"
#include "cobalt/cssom/media_query.h"
+#include "cobalt/cssom/mtm_function.h"
#include "cobalt/cssom/next_sibling_combinator.h"
#include "cobalt/cssom/not_pseudo_class.h"
#include "cobalt/cssom/number_value.h"
@@ -8262,5 +8264,118 @@
EXPECT_TRUE(media_list->EvaluateConditionValue(size));
}
+TEST_F(ParserTest, ParsesNoneFilter) {
+ scoped_refptr<cssom::CSSDeclaredStyleData> style =
+ parser_.ParseStyleDeclarationList("filter: none;", source_location_);
+
+ EXPECT_EQ(cssom::KeywordValue::GetNone(),
+ style->GetPropertyValue(cssom::kFilterProperty));
+}
+
+TEST_F(ParserTest, ParsesFilterWithKeywordInitial) {
+ scoped_refptr<cssom::CSSDeclaredStyleData> style =
+ parser_.ParseStyleDeclarationList("filter: initial;", source_location_);
+
+ EXPECT_EQ(cssom::KeywordValue::GetInitial(),
+ style->GetPropertyValue(cssom::kFilterProperty));
+}
+
+TEST_F(ParserTest, ParsesFilterWithKeywordInherit) {
+ scoped_refptr<cssom::CSSDeclaredStyleData> style =
+ parser_.ParseStyleDeclarationList("filter: inherit;", source_location_);
+
+ EXPECT_EQ(cssom::KeywordValue::GetInherit(),
+ style->GetPropertyValue(cssom::kFilterProperty));
+}
+
+TEST_F(ParserTest, ParsesMtmSingleUrlFilter) {
+ scoped_refptr<cssom::CSSDeclaredStyleData> style =
+ parser_.ParseStyleDeclarationList(
+ "filter: -cobalt-mtm(url(projection.msh),"
+ " 180deg 1.5rad,"
+ " matrix3d(1, 0, 0, 0,"
+ " 0, 1, 0, 0,"
+ " 0, 0, 1, 0,"
+ " 0, 0, 0, 1));",
+ source_location_);
+ scoped_refptr<cssom::FilterFunctionListValue> filter_list =
+ dynamic_cast<cssom::FilterFunctionListValue*>(
+ style->GetPropertyValue(cssom::kFilterProperty).get());
+
+ ASSERT_TRUE(filter_list);
+ ASSERT_EQ(1, filter_list->value().size());
+
+ const cssom::MTMFunction* mtm_function =
+ dynamic_cast<const cssom::MTMFunction*>(filter_list->value()[0]);
+ ASSERT_TRUE(mtm_function);
+
+ EXPECT_EQ(static_cast<float>(M_PI), mtm_function->horizontal_fov());
+ EXPECT_EQ(1.5f, mtm_function->vertical_fov());
+}
+
+TEST_F(ParserTest, ParsesMtmResolutionMatchedUrlsFilter) {
+ scoped_refptr<cssom::CSSDeclaredStyleData> style =
+ parser_.ParseStyleDeclarationList(
+ "filter: -cobalt-mtm(url(projection.msh)"
+ " 640 480 url(p2.msh)"
+ " 1920 1080 url(yeehaw.msh)"
+ " 33 22 url(yoda.msh),"
+ " 100deg 60deg,"
+ " matrix3d(1, 0, 0, 5,"
+ " 0, 2, 0, 0,"
+ " 6, 0, 3, 0,"
+ " 0, 7, 0, 4));",
+ source_location_);
+
+ scoped_refptr<cssom::FilterFunctionListValue> filter_list =
+ dynamic_cast<cssom::FilterFunctionListValue*>(
+ style->GetPropertyValue(cssom::kFilterProperty).get());
+
+ ASSERT_TRUE(filter_list);
+ const cssom::MTMFunction* mtm_function =
+ dynamic_cast<const cssom::MTMFunction*>(filter_list->value()[0]);
+
+ const cssom::MTMFunction::ResolutionMatchedMeshListBuilder& meshes =
+ mtm_function->resolution_matched_meshes();
+
+ ASSERT_EQ(3, meshes.size());
+ EXPECT_EQ(640, meshes[0]->width_match());
+ EXPECT_EQ(22, meshes[2]->height_match());
+
+ EXPECT_EQ(
+ "yeehaw.msh",
+ dynamic_cast<cssom::URLValue*>(meshes[1]->mesh_url().get())->value());
+}
+
+TEST_F(ParserTest, ParsesMtmTransformMatrixFilter) {
+ scoped_refptr<cssom::CSSDeclaredStyleData> style =
+ parser_.ParseStyleDeclarationList(
+ "filter: -cobalt-mtm(url(p.msh),"
+ " 100deg 60deg,"
+ " matrix3d(1, 0, 0, 5,"
+ " 0, 2, 0, 0,"
+ " 6, 0, 3, 0,"
+ " 0, 7, 0, 4));",
+ source_location_);
+
+ scoped_refptr<cssom::FilterFunctionListValue> filter_list =
+ dynamic_cast<cssom::FilterFunctionListValue*>(
+ style->GetPropertyValue(cssom::kFilterProperty).get());
+
+ ASSERT_TRUE(filter_list);
+ const cssom::MTMFunction* mtm_function =
+ dynamic_cast<const cssom::MTMFunction*>(filter_list->value()[0]);
+
+ const glm::mat4& actual = mtm_function->transform();
+ EXPECT_TRUE(
+ glm::all(glm::equal(glm::vec4(1.0f, 0.0f, 0.0f, 5.0f), actual[0])));
+ EXPECT_TRUE(
+ glm::all(glm::equal(glm::vec4(6.0f, 0.0f, 3.0f, 0.0f), actual[2])));
+ EXPECT_EQ(7.0f, actual[3][1]);
+ EXPECT_EQ(2.0f, actual[1][1]);
+ EXPECT_EQ(0.0f, actual[2][3]);
+ EXPECT_EQ(4.0f, actual[3][3]);
+}
+
} // namespace css_parser
} // namespace cobalt
diff --git a/src/cobalt/css_parser/scanner.cc b/src/cobalt/css_parser/scanner.cc
index fadfebb..b295346 100644
--- a/src/cobalt/css_parser/scanner.cc
+++ b/src/cobalt/css_parser/scanner.cc
@@ -312,7 +312,8 @@
// The input must be part of an identifier if "actual" or "expected"
// contains '-'. Otherwise ToAsciiLowerUnchecked('\r') would be equal
// to '-'.
- DCHECK((*expected >= 'a' && *expected <= 'z') || *expected == '-');
+ DCHECK((*expected >= 'a' && *expected <= 'z') ||
+ (*expected >= '0' && *expected <= '9') || *expected == '-');
DCHECK(*expected != '-' || IsCssLetter(*actual));
if (ToAsciiLowerUnchecked(*actual++) != (*expected++)) {
return false;
@@ -772,6 +773,15 @@
// Cache the open brace.
open_braces_.push('(');
+ if (!has_escape) {
+ Token function_token;
+ if (DetectKnownFunctionTokenAndMaybeChangeParsingMode(
+ name, &function_token)) {
+ ++input_iterator_;
+ return function_token;
+ }
+ }
+
++input_iterator_;
token_value->string = name;
return kInvalidFunctionToken;
@@ -1326,6 +1336,11 @@
return true;
}
if (IsEqualToCssIdentifier(
+ name.begin, cssom::GetPropertyName(cssom::kFilterProperty))) {
+ *property_name_token = kFilterToken;
+ return true;
+ }
+ if (IsEqualToCssIdentifier(
name.begin, cssom::GetPropertyName(cssom::kHeightProperty))) {
*property_name_token = kHeightToken;
return true;
@@ -2417,6 +2432,13 @@
}
return false;
+ case 8:
+ if (IsEqualToCssIdentifier(name.begin, "matrix3d")) {
+ *known_function_token = kMatrix3dFunctionToken;
+ return true;
+ }
+ return false;
+
case 9:
if (IsEqualToCssIdentifier(name.begin, "translate")) {
*known_function_token = kTranslateFunctionToken;
@@ -2450,6 +2472,10 @@
*known_function_token = kNthOfTypeFunctionToken;
return true;
}
+ if (IsEqualToCssIdentifier(name.begin, "-cobalt-mtm")) {
+ *known_function_token = kCobaltMtmFunctionToken;
+ return true;
+ }
return false;
case 12:
diff --git a/src/cobalt/css_parser/scanner_test.cc b/src/cobalt/css_parser/scanner_test.cc
index c1afabf..16b24f7 100644
--- a/src/cobalt/css_parser/scanner_test.cc
+++ b/src/cobalt/css_parser/scanner_test.cc
@@ -172,6 +172,17 @@
ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
}
+TEST_F(ScannerTest, ScansInvalidFunctionWithNumber) {
+ Scanner scanner("sample-matrix4d()", &string_pool_);
+
+ ASSERT_EQ(kInvalidFunctionToken,
+ yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ("sample-matrix4d", token_value_.string);
+
+ ASSERT_EQ(')', yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
+}
+
TEST_F(ScannerTest, ScansFunctionLikeMediaAnd) {
Scanner scanner("@media tv and(monochrome)", &string_pool_);
@@ -269,6 +280,15 @@
ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
}
+TEST_F(ScannerTest, ScansIdentifierWithNumber) {
+ Scanner scanner("matrix3d5s7wss-47", &string_pool_);
+
+ ASSERT_EQ(kIdentifierToken, yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ("matrix3d5s7wss-47", token_value_.string);
+
+ ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
+}
+
TEST_F(ScannerTest, ScansDot) {
Scanner scanner(".", &string_pool_);
@@ -414,6 +434,17 @@
ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
}
+TEST_F(ScannerTest, ScansUnknownDashFunctionWithNumber) {
+ Scanner scanner("-cobalt-ma5555gic()", &string_pool_);
+
+ ASSERT_EQ(kInvalidFunctionToken,
+ yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ("-cobalt-ma5555gic", token_value_.string);
+
+ ASSERT_EQ(')', yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
+}
+
TEST_F(ScannerTest, ScansUnknownDashFunctionWithoutClosingAtEnd) {
Scanner scanner("-cobalt-magic(", &string_pool_);
@@ -425,6 +456,26 @@
ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
}
+TEST_F(ScannerTest, ScansKnownDashFunction) {
+ Scanner scanner("-cobalt-mtm()", &string_pool_);
+
+ ASSERT_EQ(kCobaltMtmFunctionToken,
+ yylex(&token_value_, &token_location_, &scanner));
+
+ ASSERT_EQ(')', yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
+}
+
+TEST_F(ScannerTest, ScansKnownDashFunctionWithoutClosingAtEnd) {
+ Scanner scanner("-cobalt-mtm(", &string_pool_);
+
+ ASSERT_EQ(kCobaltMtmFunctionToken,
+ yylex(&token_value_, &token_location_, &scanner));
+
+ ASSERT_EQ(')', yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
+}
+
TEST_F(ScannerTest, ScansMinusNPlusConstant) {
Scanner scanner("nth-child(-n+2)", &string_pool_);
@@ -943,6 +994,15 @@
ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
}
+TEST_F(ScannerTest, ScansMatrix3dFunction) {
+ Scanner scanner("matrix3d()", &string_pool_);
+
+ ASSERT_EQ(kMatrix3dFunctionToken,
+ yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ(')', yylex(&token_value_, &token_location_, &scanner));
+ ASSERT_EQ(kEndOfFileToken, yylex(&token_value_, &token_location_, &scanner));
+}
+
TEST_F(ScannerTest, ScansNthOfTypeFunction) {
Scanner scanner("nth-of-type()", &string_pool_);
diff --git a/src/cobalt/cssom/computed_style.cc b/src/cobalt/cssom/computed_style.cc
index c2c1a6e..756819f 100644
--- a/src/cobalt/cssom/computed_style.cc
+++ b/src/cobalt/cssom/computed_style.cc
@@ -2919,6 +2919,7 @@
case kBorderTopStyleProperty:
case kColorProperty:
case kContentProperty:
+ case kFilterProperty:
case kFontFamilyProperty:
case kFontStyleProperty:
case kOpacityProperty:
@@ -3026,6 +3027,7 @@
case kBoxShadowProperty:
case kContentProperty:
case kDisplayProperty:
+ case kFilterProperty:
case kFontFamilyProperty:
case kFontProperty:
case kFontStyleProperty:
diff --git a/src/cobalt/cssom/css_computed_style_data.cc b/src/cobalt/cssom/css_computed_style_data.cc
index a5e2fcd..3866deb 100644
--- a/src/cobalt/cssom/css_computed_style_data.cc
+++ b/src/cobalt/cssom/css_computed_style_data.cc
@@ -195,6 +195,7 @@
case kColorProperty:
case kContentProperty:
case kFontFamilyProperty:
+ case kFilterProperty:
case kFontProperty:
case kFontStyleProperty:
case kFontWeightProperty:
diff --git a/src/cobalt/cssom/css_computed_style_data.h b/src/cobalt/cssom/css_computed_style_data.h
index e303868..c2c82c1 100644
--- a/src/cobalt/cssom/css_computed_style_data.h
+++ b/src/cobalt/cssom/css_computed_style_data.h
@@ -329,6 +329,13 @@
SetPropertyValue(kDisplayProperty, display);
}
+ const scoped_refptr<PropertyValue>& filter() const {
+ return GetPropertyValueReference(kFilterProperty);
+ }
+ void set_filter(const scoped_refptr<PropertyValue>& filter) {
+ SetPropertyValue(kFilterProperty, filter);
+ }
+
const scoped_refptr<PropertyValue>& font_family() const {
return GetPropertyValueReference(kFontFamilyProperty);
}
diff --git a/src/cobalt/cssom/css_computed_style_data_test.cc b/src/cobalt/cssom/css_computed_style_data_test.cc
index 2fcb1ea..4aede0c 100644
--- a/src/cobalt/cssom/css_computed_style_data_test.cc
+++ b/src/cobalt/cssom/css_computed_style_data_test.cc
@@ -1191,5 +1191,22 @@
ASSERT_TRUE(style2->DoDeclaredPropertiesMatch(style1));
}
+TEST(CSSComputedStyleDataTest, FilterSettersAndGettersAreConsistent) {
+ scoped_refptr<CSSComputedStyleData> style = new CSSComputedStyleData();
+
+ EXPECT_EQ(GetPropertyInitialValue(kFilterProperty), style->filter());
+ EXPECT_EQ(style->filter(), style->GetPropertyValue(kFilterProperty));
+
+ style->set_filter(KeywordValue::GetInitial());
+ EXPECT_EQ(KeywordValue::GetInitial(), style->filter());
+ EXPECT_EQ(KeywordValue::GetInitial(),
+ style->GetPropertyValue(kFilterProperty));
+
+ style->SetPropertyValue(kFilterProperty, KeywordValue::GetInherit());
+ EXPECT_EQ(KeywordValue::GetInherit(), style->filter());
+ EXPECT_EQ(KeywordValue::GetInherit(),
+ style->GetPropertyValue(kFilterProperty));
+}
+
} // namespace cssom
} // namespace cobalt
diff --git a/src/cobalt/cssom/css_declared_style_data.cc b/src/cobalt/cssom/css_declared_style_data.cc
index 6768e50..80a05df 100644
--- a/src/cobalt/cssom/css_declared_style_data.cc
+++ b/src/cobalt/cssom/css_declared_style_data.cc
@@ -65,7 +65,14 @@
ExpandShorthandProperty(key);
for (LonghandPropertySet::const_iterator iter = longhand_properties.begin();
iter != longhand_properties.end(); ++iter) {
- ClearPropertyValueAndImportanceForLonghandProperty(*iter);
+ PropertyKey longhand_key = *iter;
+ if (IsShorthandProperty(longhand_key)) {
+ // If the property is another shorthand property, then recurse to clear
+ // it's registered longhand properties.
+ ClearPropertyValueAndImportance(longhand_key);
+ } else {
+ ClearPropertyValueAndImportanceForLonghandProperty(longhand_key);
+ }
}
} else {
ClearPropertyValueAndImportanceForLonghandProperty(key);
diff --git a/src/cobalt/cssom/css_declared_style_data_test.cc b/src/cobalt/cssom/css_declared_style_data_test.cc
index 31388a8..0761c8d 100644
--- a/src/cobalt/cssom/css_declared_style_data_test.cc
+++ b/src/cobalt/cssom/css_declared_style_data_test.cc
@@ -696,5 +696,36 @@
EXPECT_EQ(*style1 == *style2, false);
}
+TEST(CSSDeclaredStyleDataTest, CanClearLongHandPropertyValueAndImportance) {
+ scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData();
+ style->SetPropertyValueAndImportance(kBorderLeftWidthProperty,
+ KeywordValue::GetInherit(), true);
+ style->ClearPropertyValueAndImportance(kBorderLeftWidthProperty);
+
+ scoped_refptr<CSSDeclaredStyleData> empty_style = new CSSDeclaredStyleData();
+ EXPECT_EQ(*style, *empty_style);
+}
+
+TEST(CSSDeclaredStyleDataTest, CanClearPropertyValueAndImportance) {
+ scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData();
+ style->SetPropertyValueAndImportance(kBorderLeftWidthProperty,
+ KeywordValue::GetInherit(), true);
+ style->ClearPropertyValueAndImportance(kBorderWidthProperty);
+
+ scoped_refptr<CSSDeclaredStyleData> empty_style = new CSSDeclaredStyleData();
+ EXPECT_EQ(*style, *empty_style);
+}
+
+TEST(CSSDeclaredStyleDataTest,
+ CanClearPropertyValueAndImportanceWithRecursion) {
+ scoped_refptr<CSSDeclaredStyleData> style = new CSSDeclaredStyleData();
+ style->SetPropertyValueAndImportance(kBorderLeftWidthProperty,
+ KeywordValue::GetInherit(), true);
+ style->ClearPropertyValueAndImportance(kBorderProperty);
+
+ scoped_refptr<CSSDeclaredStyleData> empty_style = new CSSDeclaredStyleData();
+ EXPECT_EQ(*style, *empty_style);
+}
+
} // namespace cssom
} // namespace cobalt
diff --git a/src/cobalt/cssom/cssom.gyp b/src/cobalt/cssom/cssom.gyp
index 63be9ea..a3af6c4 100644
--- a/src/cobalt/cssom/cssom.gyp
+++ b/src/cobalt/cssom/cssom.gyp
@@ -100,6 +100,9 @@
'descendant_combinator.h',
'empty_pseudo_class.cc',
'empty_pseudo_class.h',
+ 'filter_function.h',
+ 'filter_function_list_value.cc',
+ 'filter_function_list_value.h',
'focus_pseudo_class.cc',
'focus_pseudo_class.h',
'following_sibling_combinator.cc',
@@ -143,6 +146,8 @@
'media_query.h',
'media_type_names.cc',
'media_type_names.h',
+ 'mtm_function.cc',
+ 'mtm_function.h',
'mutation_observer.h',
'next_sibling_combinator.cc',
'next_sibling_combinator.h',
diff --git a/src/cobalt/cssom/filter_function.h b/src/cobalt/cssom/filter_function.h
new file mode 100644
index 0000000..c3053c0
--- /dev/null
+++ b/src/cobalt/cssom/filter_function.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COBALT_CSSOM_FILTER_FUNCTION_H_
+#define COBALT_CSSOM_FILTER_FUNCTION_H_
+
+#include <string>
+
+#include "cobalt/base/polymorphic_equatable.h"
+
+namespace cobalt {
+namespace cssom {
+
+// A base class for filter functions. Filters manipulate an element's rendering.
+// https://www.w3.org/TR/filter-effects-1/
+class FilterFunction : public base::PolymorphicEquatable {
+ public:
+ virtual std::string ToString() const = 0;
+
+ virtual ~FilterFunction() {}
+};
+
+} // namespace cssom
+} // namespace cobalt
+
+#endif // COBALT_CSSOM_FILTER_FUNCTION_H_
diff --git a/src/cobalt/cssom/filter_function_list_value.cc b/src/cobalt/cssom/filter_function_list_value.cc
new file mode 100644
index 0000000..443832b
--- /dev/null
+++ b/src/cobalt/cssom/filter_function_list_value.cc
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cobalt/cssom/filter_function_list_value.h"
+
+namespace cobalt {
+namespace cssom {
+
+std::string FilterFunctionListValue::ToString() const {
+ std::string result;
+ for (size_t i = 0; i < value().size(); ++i) {
+ if (!result.empty()) result.append(" ");
+ result.append(value()[i]->ToString());
+ }
+ return result;
+}
+
+} // namespace cssom
+} // namespace cobalt
diff --git a/src/cobalt/cssom/filter_function_list_value.h b/src/cobalt/cssom/filter_function_list_value.h
new file mode 100644
index 0000000..c1f137b
--- /dev/null
+++ b/src/cobalt/cssom/filter_function_list_value.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COBALT_CSSOM_FILTER_FUNCTION_LIST_VALUE_H_
+#define COBALT_CSSOM_FILTER_FUNCTION_LIST_VALUE_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "cobalt/base/polymorphic_equatable.h"
+#include "cobalt/cssom/filter_function.h"
+#include "cobalt/cssom/property_value_visitor.h"
+#include "cobalt/cssom/scoped_list_value.h"
+
+namespace cobalt {
+namespace cssom {
+
+// A list of composed filter functions.
+class FilterFunctionListValue : public ScopedListValue<FilterFunction> {
+ public:
+ explicit FilterFunctionListValue(
+ ScopedListValue<FilterFunction>::Builder value)
+ : ScopedListValue(value.Pass()) {}
+
+ void Accept(PropertyValueVisitor* visitor) OVERRIDE {
+ visitor->VisitFilterFunctionList(this);
+ }
+
+ std::string ToString() const OVERRIDE;
+
+ DEFINE_POLYMORPHIC_EQUATABLE_TYPE(FilterFunctionListValue);
+
+ private:
+ virtual ~FilterFunctionListValue() OVERRIDE {}
+};
+
+} // namespace cssom
+} // namespace cobalt
+
+#endif // COBALT_CSSOM_FILTER_FUNCTION_LIST_VALUE_H_
diff --git a/src/cobalt/cssom/interpolate_property_value.cc b/src/cobalt/cssom/interpolate_property_value.cc
index 061332d..d9bea8b 100644
--- a/src/cobalt/cssom/interpolate_property_value.cc
+++ b/src/cobalt/cssom/interpolate_property_value.cc
@@ -70,6 +70,8 @@
void VisitAbsoluteURL(AbsoluteURLValue* start_absolute_url_value) OVERRIDE;
void VisitCalc(CalcValue* start_calc_value) OVERRIDE;
+ void VisitFilterFunctionList(
+ FilterFunctionListValue* start_filter_function_list_value) OVERRIDE;
void VisitFontStyle(FontStyleValue* start_font_style_value) OVERRIDE;
void VisitFontWeight(FontWeightValue* start_font_weight_value) OVERRIDE;
void VisitInteger(IntegerValue* integer_value) OVERRIDE;
@@ -356,6 +358,12 @@
interpolated_value_ = end_value_;
}
+void InterpolateVisitor::VisitFilterFunctionList(
+ FilterFunctionListValue* /*start_filter_function_list_value*/) {
+ NOTIMPLEMENTED();
+ interpolated_value_ = end_value_;
+}
+
void InterpolateVisitor::VisitFontStyle(
FontStyleValue* /*start_font_style_value*/) {
NOTIMPLEMENTED();
diff --git a/src/cobalt/cssom/mtm_function.cc b/src/cobalt/cssom/mtm_function.cc
new file mode 100644
index 0000000..ee51938
--- /dev/null
+++ b/src/cobalt/cssom/mtm_function.cc
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cobalt/cssom/mtm_function.h"
+
+#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "base/stringprintf.h"
+#include "cobalt/cssom/filter_function_list_value.h"
+#include "cobalt/cssom/keyword_value.h"
+#include "cobalt/cssom/property_value_visitor.h"
+
+namespace cobalt {
+namespace cssom {
+
+MTMFunction::MTMFunction(
+ const scoped_refptr<PropertyValue>& mesh_url,
+ ResolutionMatchedMeshListBuilder resolution_matched_meshes,
+ float horizontal_fov, float vertical_fov, const glm::mat4& transform)
+ : mesh_url_(mesh_url),
+ resolution_matched_meshes_(resolution_matched_meshes.Pass()),
+ horizontal_fov_(horizontal_fov),
+ vertical_fov_(vertical_fov),
+ transform_(transform) {
+ DCHECK(mesh_url_);
+}
+
+std::string MTMFunction::ToString() const {
+ std::string result = "-cobalt-mtm(";
+
+ result.append(mesh_url()->ToString());
+
+ const ResolutionMatchedMeshListBuilder& meshes = resolution_matched_meshes();
+ for (size_t mesh_index = 0; mesh_index < meshes.size(); ++mesh_index) {
+ result.push_back(' ');
+ result.append(base::IntToString(meshes[mesh_index]->width_match()));
+ result.push_back(' ');
+ result.append(base::IntToString(meshes[mesh_index]->height_match()));
+ result.push_back(' ');
+ result.append(meshes[mesh_index]->mesh_url()->ToString());
+ }
+
+ result.append(base::StringPrintf(", %.7grad", horizontal_fov()));
+ result.append(base::StringPrintf(" %.7grad, ", vertical_fov()));
+
+ result.append("matrix3d(");
+ for (int col = 0; col <= 3; ++col) {
+ for (int row = 0; row <= 3; ++row) {
+ if (col > 0 || row > 0) {
+ result.append(", ");
+ }
+ result.append(base::StringPrintf("%.7g", transform()[col][row]));
+ }
+ }
+ result.append("))");
+
+ return result;
+}
+
+MTMFunction::ResolutionMatchedMesh::ResolutionMatchedMesh(
+ int width_match, int height_match,
+ const scoped_refptr<PropertyValue>& mesh_url)
+ : width_match_(width_match),
+ height_match_(height_match),
+ mesh_url_(mesh_url) {
+ DCHECK(mesh_url_);
+}
+
+bool MTMFunction::ResolutionMatchedMesh::operator==(
+ const MTMFunction::ResolutionMatchedMesh& rhs) const {
+ return mesh_url()->Equals(*rhs.mesh_url()) &&
+ width_match() == rhs.width_match() &&
+ height_match() == rhs.height_match();
+}
+
+bool MTMFunction::ResolutionMatchedMesh::operator!=(
+ const MTMFunction::ResolutionMatchedMesh& rhs) const {
+ return !(*this == rhs);
+}
+
+const MTMFunction* MTMFunction::ExtractFromFilterList(
+ PropertyValue* filter_value) {
+ if (filter_value && filter_value != cssom::KeywordValue::GetNone()) {
+ const cssom::FilterFunctionListValue::Builder& filter_list =
+ base::polymorphic_downcast<cssom::FilterFunctionListValue*>(
+ filter_value)
+ ->value();
+
+ for (size_t list_index = 0; list_index < filter_list.size(); ++list_index) {
+ if (filter_list[list_index]->GetTypeId() ==
+ base::GetTypeId<cssom::MTMFunction>()) {
+ return base::polymorphic_downcast<const cssom::MTMFunction*>(
+ filter_list[list_index]);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+bool MTMFunction::operator==(const MTMFunction& rhs) const {
+ if (!mesh_url()->Equals(*rhs.mesh_url()) ||
+ horizontal_fov() != rhs.horizontal_fov() ||
+ horizontal_fov() != rhs.horizontal_fov()) {
+ return false;
+ }
+ const ResolutionMatchedMeshListBuilder& lhs_meshes =
+ resolution_matched_meshes();
+ const ResolutionMatchedMeshListBuilder& rhs_meshes =
+ rhs.resolution_matched_meshes();
+
+ if (lhs_meshes.size() != rhs_meshes.size()) {
+ return false;
+ }
+
+ for (size_t i = 0; i < lhs_meshes.size(); ++i) {
+ if (*lhs_meshes[i] != *rhs_meshes[i]) {
+ return false;
+ }
+ }
+
+ for (int col = 0; col <= 3; ++col) {
+ if (!glm::all(glm::equal(transform()[col], rhs.transform()[col]))) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace cssom
+} // namespace cobalt
diff --git a/src/cobalt/cssom/mtm_function.h b/src/cobalt/cssom/mtm_function.h
new file mode 100644
index 0000000..59498b4
--- /dev/null
+++ b/src/cobalt/cssom/mtm_function.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COBALT_CSSOM_MTM_FUNCTION_H_
+#define COBALT_CSSOM_MTM_FUNCTION_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_vector.h"
+#include "cobalt/base/polymorphic_equatable.h"
+#include "cobalt/cssom/filter_function.h"
+#include "cobalt/cssom/property_value.h"
+#include "cobalt/cssom/url_value.h"
+#include "third_party/glm/glm/mat4x4.hpp"
+
+namespace cobalt {
+namespace cssom {
+
+// Represent an MTM filter.
+class MTMFunction : public FilterFunction {
+ public:
+ // A resolution-matched mesh specifier.
+ class ResolutionMatchedMesh {
+ public:
+ ResolutionMatchedMesh(int width_match, int height_match,
+ const scoped_refptr<PropertyValue>& mesh_url);
+ int width_match() const { return width_match_; }
+ int height_match() const { return height_match_; }
+ const scoped_refptr<PropertyValue>& mesh_url() const { return mesh_url_; }
+ bool operator==(const MTMFunction::ResolutionMatchedMesh& rhs) const;
+ bool operator!=(const MTMFunction::ResolutionMatchedMesh& rhs) const;
+
+ private:
+ const int width_match_;
+ const int height_match_;
+ const scoped_refptr<PropertyValue> mesh_url_;
+ };
+ typedef ScopedVector<ResolutionMatchedMesh> ResolutionMatchedMeshListBuilder;
+
+ MTMFunction(const scoped_refptr<PropertyValue>& mesh_url,
+ ResolutionMatchedMeshListBuilder resolution_matched_meshes,
+ float horizontal_fov, float vertical_fov,
+ const glm::mat4& transform);
+
+ ~MTMFunction() OVERRIDE {}
+
+ const scoped_refptr<PropertyValue>& mesh_url() const { return mesh_url_; }
+ const ResolutionMatchedMeshListBuilder& resolution_matched_meshes() const {
+ return resolution_matched_meshes_;
+ }
+
+ float horizontal_fov() const { return horizontal_fov_; }
+ float vertical_fov() const { return vertical_fov_; }
+ const glm::mat4& transform() const { return transform_; }
+
+ std::string ToString() const OVERRIDE;
+
+ bool operator==(const MTMFunction& rhs) const;
+
+ static const MTMFunction* ExtractFromFilterList(PropertyValue* filter_list);
+
+ DEFINE_POLYMORPHIC_EQUATABLE_TYPE(MTMFunction);
+
+ private:
+ const scoped_refptr<PropertyValue> mesh_url_;
+ const ResolutionMatchedMeshListBuilder resolution_matched_meshes_;
+ const float horizontal_fov_;
+ const float vertical_fov_;
+ const glm::mat4 transform_;
+
+ DISALLOW_COPY_AND_ASSIGN(MTMFunction);
+};
+
+} // namespace cssom
+} // namespace cobalt
+
+#endif // COBALT_CSSOM_MTM_FUNCTION_H_
diff --git a/src/cobalt/cssom/property_definitions.cc b/src/cobalt/cssom/property_definitions.cc
index 8133992..1bcdb2a 100644
--- a/src/cobalt/cssom/property_definitions.cc
+++ b/src/cobalt/cssom/property_definitions.cc
@@ -386,6 +386,12 @@
kImpactsBoxCrossReferencesNo,
KeywordValue::GetInline());
+ // https://www.w3.org/TR/filter-effects-1/#FilterProperty
+ SetPropertyDefinition(kFilterProperty, "filter", kInheritedNo, kAnimatableNo,
+ kImpactsChildDeclaredStyleNo, kImpactsBoxGenerationNo,
+ kImpactsBoxSizesNo, kImpactsBoxCrossReferencesNo,
+ KeywordValue::GetNone());
+
// Varies by platform in Chromium, Roboto in Cobalt.
// https://www.w3.org/TR/css3-fonts/#font-family-prop
SetPropertyDefinition(
@@ -1003,6 +1009,10 @@
return kBottomProperty;
}
if (LowerCaseEqualsASCII(property_name,
+ GetPropertyName(kFilterProperty))) {
+ return kFilterProperty;
+ }
+ if (LowerCaseEqualsASCII(property_name,
GetPropertyName(kHeightProperty))) {
return kHeightProperty;
}
diff --git a/src/cobalt/cssom/property_definitions.h b/src/cobalt/cssom/property_definitions.h
index 14a1c39..f4c9333 100644
--- a/src/cobalt/cssom/property_definitions.h
+++ b/src/cobalt/cssom/property_definitions.h
@@ -72,6 +72,7 @@
kColorProperty,
kContentProperty,
kDisplayProperty,
+ kFilterProperty,
kFontFamilyProperty,
kFontSizeProperty,
kFontStyleProperty,
diff --git a/src/cobalt/cssom/property_value_is_equal_test.cc b/src/cobalt/cssom/property_value_is_equal_test.cc
index b2f4f88..0b647d0 100644
--- a/src/cobalt/cssom/property_value_is_equal_test.cc
+++ b/src/cobalt/cssom/property_value_is_equal_test.cc
@@ -15,6 +15,7 @@
*/
#include "cobalt/cssom/absolute_url_value.h"
+#include "cobalt/cssom/filter_function_list_value.h"
#include "cobalt/cssom/font_style_value.h"
#include "cobalt/cssom/font_weight_value.h"
#include "cobalt/cssom/integer_value.h"
@@ -23,6 +24,7 @@
#include "cobalt/cssom/linear_gradient_value.h"
#include "cobalt/cssom/matrix_function.h"
#include "cobalt/cssom/media_feature_keyword_value.h"
+#include "cobalt/cssom/mtm_function.h"
#include "cobalt/cssom/number_value.h"
#include "cobalt/cssom/percentage_value.h"
#include "cobalt/cssom/property_definitions.h"
@@ -596,5 +598,59 @@
EXPECT_FALSE(value_a->Equals(*value_b));
}
+TEST(PropertyValueIsEqualTest, FilterListsAreEqual) {
+ FilterFunctionListValue::Builder filter_list_a;
+ filter_list_a.push_back(new MTMFunction(
+ new URLValue("somemesh.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 0.70707f, 6.28f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 9.0f, 0.0f, 0.0f,
+ 1.0f, 0.07878f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ filter_list_a.push_back(new MTMFunction(
+ new URLValue("sphere.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 0.676f, 6.28f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ scoped_refptr<FilterFunctionListValue> value_a(
+ new FilterFunctionListValue(filter_list_a.Pass()));
+
+ FilterFunctionListValue::Builder filter_list_b;
+ filter_list_b.push_back(new MTMFunction(
+ new URLValue("somemesh.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 0.70707f, 6.28f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 9.0f, 0.0f, 0.0f,
+ 1.0f, 0.07878f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ filter_list_b.push_back(new MTMFunction(
+ new URLValue("sphere.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 0.676f, 6.28f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ scoped_refptr<FilterFunctionListValue> value_b(
+ new FilterFunctionListValue(filter_list_b.Pass()));
+
+ EXPECT_TRUE(value_a->Equals(*value_b));
+}
+
+TEST(PropertyValueIsEqualTest, FilterListsAreNotEqual) {
+ FilterFunctionListValue::Builder filter_list_a;
+ filter_list_a.push_back(new MTMFunction(
+ new URLValue("format.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 8.5f, 3.14f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ scoped_refptr<FilterFunctionListValue> value_a(
+ new FilterFunctionListValue(filter_list_a.Pass()));
+
+ FilterFunctionListValue::Builder filter_list_b;
+ filter_list_b.push_back(new MTMFunction(
+ new URLValue("format.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 8.5f, 3.14f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ scoped_refptr<FilterFunctionListValue> value_b(
+ new FilterFunctionListValue(filter_list_b.Pass()));
+
+ EXPECT_FALSE(value_a->Equals(*value_b));
+}
+
} // namespace cssom
} // namespace cobalt
diff --git a/src/cobalt/cssom/property_value_to_string_test.cc b/src/cobalt/cssom/property_value_to_string_test.cc
index 6c90ec6..fd51fe9 100644
--- a/src/cobalt/cssom/property_value_to_string_test.cc
+++ b/src/cobalt/cssom/property_value_to_string_test.cc
@@ -18,6 +18,7 @@
#include "base/time.h"
#include "cobalt/cssom/absolute_url_value.h"
+#include "cobalt/cssom/filter_function_list_value.h"
#include "cobalt/cssom/font_style_value.h"
#include "cobalt/cssom/font_weight_value.h"
#include "cobalt/cssom/integer_value.h"
@@ -26,6 +27,7 @@
#include "cobalt/cssom/linear_gradient_value.h"
#include "cobalt/cssom/matrix_function.h"
#include "cobalt/cssom/media_feature_keyword_value.h"
+#include "cobalt/cssom/mtm_function.h"
#include "cobalt/cssom/number_value.h"
#include "cobalt/cssom/percentage_value.h"
#include "cobalt/cssom/property_definitions.h"
@@ -346,5 +348,61 @@
EXPECT_EQ(property->ToString(), "url(foo.png)");
}
+TEST(PropertyValueToStringTest, MTMFunctionSingleMesh) {
+ scoped_ptr<MTMFunction> function(new MTMFunction(
+ new URLValue("-.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 2.5f, 3.14f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ EXPECT_EQ(
+ "-cobalt-mtm(url(-.msh), "
+ "2.5rad 3.14rad, "
+ "matrix3d(1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))",
+ function->ToString());
+}
+
+TEST(PropertyValueToStringTest, MTMFunctionWithResolutionMatchedMeshes) {
+ MTMFunction::ResolutionMatchedMeshListBuilder meshes;
+ meshes.push_back(new MTMFunction::ResolutionMatchedMesh(
+ 1920, 2000000, new URLValue("a.msh")));
+ meshes.push_back(
+ new MTMFunction::ResolutionMatchedMesh(640, 5, new URLValue("b.msh")));
+ scoped_ptr<MTMFunction> function(new MTMFunction(
+ new URLValue("-.msh"), meshes.Pass(), 28.5f, 3.14f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ EXPECT_EQ(
+ "-cobalt-mtm(url(-.msh) 1920 2000000 url(a.msh) 640 5 url(b.msh), "
+ "28.5rad 3.14rad, "
+ "matrix3d(1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))",
+ function->ToString());
+}
+
+TEST(PropertyValueToStringTest, FilterFunctionListValue) {
+ FilterFunctionListValue::Builder filter_list;
+ filter_list.push_back(new MTMFunction(
+ new URLValue("-.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 8.5f, 3.14f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)));
+ filter_list.push_back(new MTMFunction(
+ new URLValue("world.msh"),
+ MTMFunction::ResolutionMatchedMeshListBuilder().Pass(), 8.5f, 39.0f,
+ glm::mat4(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f)));
+
+ scoped_refptr<FilterFunctionListValue> property(
+ new FilterFunctionListValue(filter_list.Pass()));
+
+ EXPECT_EQ(
+ "-cobalt-mtm(url(-.msh), "
+ "8.5rad 3.14rad, "
+ "matrix3d(1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)) "
+ "-cobalt-mtm(url(world.msh), "
+ "8.5rad 39rad, "
+ "matrix3d(1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1))",
+ property->ToString());
+}
+
} // namespace cssom
} // namespace cobalt
diff --git a/src/cobalt/cssom/property_value_visitor.cc b/src/cobalt/cssom/property_value_visitor.cc
index cba67cb..12d234b 100644
--- a/src/cobalt/cssom/property_value_visitor.cc
+++ b/src/cobalt/cssom/property_value_visitor.cc
@@ -19,6 +19,7 @@
#include "base/logging.h"
#include "cobalt/cssom/absolute_url_value.h"
#include "cobalt/cssom/calc_value.h"
+#include "cobalt/cssom/filter_function_list_value.h"
#include "cobalt/cssom/font_style_value.h"
#include "cobalt/cssom/font_weight_value.h"
#include "cobalt/cssom/integer_value.h"
@@ -57,6 +58,11 @@
VisitDefault(calc_value);
}
+void DefaultingPropertyValueVisitor::VisitFilterFunctionList(
+ FilterFunctionListValue* filter_function_list_value) {
+ VisitDefault(filter_function_list_value);
+}
+
void DefaultingPropertyValueVisitor::VisitFontStyle(
FontStyleValue* font_style_value) {
VisitDefault(font_style_value);
diff --git a/src/cobalt/cssom/property_value_visitor.h b/src/cobalt/cssom/property_value_visitor.h
index d363630..3457a9f 100644
--- a/src/cobalt/cssom/property_value_visitor.h
+++ b/src/cobalt/cssom/property_value_visitor.h
@@ -24,6 +24,7 @@
class AbsoluteURLValue;
class CalcValue;
+class FilterFunctionListValue;
class FontStyleValue;
class FontWeightValue;
class IntegerValue;
@@ -58,6 +59,7 @@
public:
virtual void VisitAbsoluteURL(AbsoluteURLValue* url_value) = 0;
virtual void VisitCalc(CalcValue* calc_value) = 0;
+ virtual void VisitFilterFunctionList(FilterFunctionListValue*) = 0;
virtual void VisitFontStyle(FontStyleValue* font_style_value) = 0;
virtual void VisitFontWeight(FontWeightValue* font_weight_value) = 0;
virtual void VisitInteger(IntegerValue* integer_value) = 0;
@@ -102,6 +104,8 @@
public:
void VisitAbsoluteURL(AbsoluteURLValue* url_value) OVERRIDE;
void VisitCalc(CalcValue* calc_value) OVERRIDE;
+ void VisitFilterFunctionList(
+ FilterFunctionListValue* filter_function_list_value) OVERRIDE;
void VisitFontStyle(FontStyleValue* font_style_value) OVERRIDE;
void VisitFontWeight(FontWeightValue* font_weight_value) OVERRIDE;
void VisitKeyword(KeywordValue* keyword_value) OVERRIDE;
diff --git a/src/cobalt/cssom/property_value_visitor_test.cc b/src/cobalt/cssom/property_value_visitor_test.cc
index 953dd12..550c8b9 100644
--- a/src/cobalt/cssom/property_value_visitor_test.cc
+++ b/src/cobalt/cssom/property_value_visitor_test.cc
@@ -20,6 +20,7 @@
#include "cobalt/cssom/absolute_url_value.h"
#include "cobalt/cssom/calc_value.h"
+#include "cobalt/cssom/filter_function_list_value.h"
#include "cobalt/cssom/font_style_value.h"
#include "cobalt/cssom/font_weight_value.h"
#include "cobalt/cssom/integer_value.h"
@@ -28,6 +29,7 @@
#include "cobalt/cssom/linear_gradient_value.h"
#include "cobalt/cssom/local_src_value.h"
#include "cobalt/cssom/media_feature_keyword_value.h"
+#include "cobalt/cssom/mtm_function.h"
#include "cobalt/cssom/number_value.h"
#include "cobalt/cssom/percentage_value.h"
#include "cobalt/cssom/property_key_list_value.h"
@@ -59,6 +61,8 @@
MOCK_METHOD1(VisitAbsoluteURL, void(AbsoluteURLValue* absolute_url_value));
MOCK_METHOD1(VisitCalc, void(CalcValue* calc_value));
MOCK_METHOD1(VisitFontStyle, void(FontStyleValue* font_style_value));
+ MOCK_METHOD1(VisitFilterFunctionList,
+ void(FilterFunctionListValue* filter_list_value));
MOCK_METHOD1(VisitFontWeight, void(FontWeightValue* font_weight_value));
MOCK_METHOD1(VisitInteger, void(IntegerValue* integer_value));
MOCK_METHOD1(VisitKeyword, void(KeywordValue* keyword_value));
@@ -110,6 +114,23 @@
calc_value->Accept(&mock_visitor);
}
+TEST(PropertyValueVisitorTest, VisitsFilterListValue) {
+ MTMFunction::ResolutionMatchedMeshListBuilder resMs;
+ resMs.push_back(
+ new MTMFunction::ResolutionMatchedMesh(22, 22, new URLValue("a.msh")));
+
+ FilterFunctionListValue::Builder builder;
+ builder.push_back(new MTMFunction(new URLValue("p.msh"), resMs.Pass(), 120,
+ 60, glm::mat4(1.0f)));
+
+ scoped_refptr<FilterFunctionListValue> filter_list_value =
+ new FilterFunctionListValue(builder.Pass());
+
+ MockPropertyValueVisitor mock_visitor;
+ EXPECT_CALL(mock_visitor, VisitFilterFunctionList(filter_list_value.get()));
+ filter_list_value->Accept(&mock_visitor);
+}
+
TEST(PropertyValueVisitorTest, VisitsFontStyleValue) {
scoped_refptr<FontStyleValue> font_style_value = FontStyleValue::GetNormal();
MockPropertyValueVisitor mock_visitor;
diff --git a/src/cobalt/debug/render_overlay.cc b/src/cobalt/debug/render_overlay.cc
index 5a60043..0b1f5a6 100644
--- a/src/cobalt/debug/render_overlay.cc
+++ b/src/cobalt/debug/render_overlay.cc
@@ -39,6 +39,11 @@
Process();
}
+void RenderOverlay::ClearInput() {
+ input_layout_ = LayoutResults(NULL, base::TimeDelta());
+ input_receipt_time_ = base::nullopt;
+}
+
void RenderOverlay::Process() {
if (input_layout_.render_tree) {
// Calculate a modified layout time accounting for the offset between now
diff --git a/src/cobalt/debug/render_overlay.h b/src/cobalt/debug/render_overlay.h
index bac07a9..6658d52 100644
--- a/src/cobalt/debug/render_overlay.h
+++ b/src/cobalt/debug/render_overlay.h
@@ -45,6 +45,8 @@
// Updates the overlay that will be added to the input layout.
void SetOverlay(const scoped_refptr<render_tree::Node>& overlay);
+ void ClearInput();
+
private:
// Adds the overlay (if any) to the input layout and passes on to the
// callback specified in the constructor.
diff --git a/src/cobalt/dom/document.cc b/src/cobalt/dom/document.cc
index 928ba1f..233682b 100644
--- a/src/cobalt/dom/document.cc
+++ b/src/cobalt/dom/document.cc
@@ -640,6 +640,22 @@
}
}
+void Document::InvalidateLayout() {
+ // Set all invalidation flags and recursively invalidate the computed style.
+ is_selector_tree_dirty_ = true;
+ is_computed_style_dirty_ = true;
+ are_font_faces_dirty_ = true;
+ are_keyframes_dirty_ = true;
+
+ scoped_refptr<HTMLHtmlElement> current_html = html();
+ if (current_html) {
+ current_html->InvalidateComputedStylesRecursively();
+ }
+
+ // Finally, also destroy all cached layout boxes.
+ InvalidateLayoutBoxesFromNodeAndDescendants();
+}
+
void Document::DispatchOnLoadEvent() {
TRACE_EVENT0("cobalt::dom", "Document::DispatchOnLoadEvent()");
diff --git a/src/cobalt/dom/document.h b/src/cobalt/dom/document.h
index aee887f..5fca443 100644
--- a/src/cobalt/dom/document.h
+++ b/src/cobalt/dom/document.h
@@ -320,6 +320,9 @@
// Exposed for test purposes.
void UpdateSelectorTree();
+ // Invalidates the document's cached layout tree and associated data.
+ void InvalidateLayout();
+
DEFINE_WRAPPABLE_TYPE(Document);
protected:
diff --git a/src/cobalt/dom/font_cache.cc b/src/cobalt/dom/font_cache.cc
index e7f0f0f..0ee045c 100644
--- a/src/cobalt/dom/font_cache.cc
+++ b/src/cobalt/dom/font_cache.cc
@@ -42,7 +42,7 @@
typeface_load_event_callback);
}
-FontCache::FontCache(render_tree::ResourceProvider* resource_provider,
+FontCache::FontCache(render_tree::ResourceProvider** resource_provider,
loader::font::RemoteTypefaceCache* remote_typeface_cache,
const base::Closure& external_typeface_load_event_callback,
const std::string& language)
@@ -180,23 +180,26 @@
FontCache::GetCharacterFallbackTypeface(int32 utf32_character,
const render_tree::FontStyle& style) {
DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(resource_provider());
return GetCachedLocalTypeface(
- resource_provider_->GetCharacterFallbackTypeface(utf32_character, style,
- language_));
+ resource_provider()->GetCharacterFallbackTypeface(utf32_character, style,
+ language_));
}
scoped_refptr<render_tree::GlyphBuffer> FontCache::CreateGlyphBuffer(
const char16* text_buffer, int32 text_length, bool is_rtl,
FontList* font_list) {
- return resource_provider_->CreateGlyphBuffer(text_buffer,
- static_cast<size_t>(text_length),
- language_, is_rtl, font_list);
+ DCHECK(resource_provider());
+ return resource_provider()->CreateGlyphBuffer(
+ text_buffer, static_cast<size_t>(text_length), language_, is_rtl,
+ font_list);
}
float FontCache::GetTextWidth(const char16* text_buffer, int32 text_length,
bool is_rtl, FontList* font_list,
render_tree::FontVector* maybe_used_fonts) {
- return resource_provider_->GetTextWidth(
+ DCHECK(resource_provider());
+ return resource_provider()->GetTextWidth(
text_buffer, static_cast<size_t>(text_length), language_, is_rtl,
font_list, maybe_used_fonts);
}
@@ -342,6 +345,7 @@
scoped_refptr<render_tree::Font> FontCache::TryGetLocalFont(
const std::string& family, render_tree::FontStyle style, float size,
FontListFont::State* state) {
+ DCHECK(resource_provider());
// Only request the local font from the resource provider if the family is
// empty or the resource provider actually has the family. The reason for this
// is that the resource provider's |GetLocalTypeface()| is guaranteed to
@@ -349,14 +353,14 @@
// the subsequent fonts in the font list need to be attempted. An empty family
// signifies using the default font.
if (!family.empty() &&
- !resource_provider_->HasLocalFontFamily(family.c_str())) {
+ !resource_provider()->HasLocalFontFamily(family.c_str())) {
*state = FontListFont::kUnavailableState;
return NULL;
} else {
*state = FontListFont::kLoadedState;
return GetFontFromTypefaceAndSize(
GetCachedLocalTypeface(
- resource_provider_->GetLocalTypeface(family.c_str(), style)),
+ resource_provider()->GetLocalTypeface(family.c_str(), style)),
size);
}
}
diff --git a/src/cobalt/dom/font_cache.h b/src/cobalt/dom/font_cache.h
index dd74c4e..e3a574a 100644
--- a/src/cobalt/dom/font_cache.h
+++ b/src/cobalt/dom/font_cache.h
@@ -172,7 +172,7 @@
typedef std::map<CharacterFallbackKey, CharacterFallbackTypefaceMap>
CharacterFallbackTypefaceMaps;
- FontCache(render_tree::ResourceProvider* resource_provider,
+ FontCache(render_tree::ResourceProvider** resource_provider,
loader::font::RemoteTypefaceCache* remote_typeface_cache,
const base::Closure& external_typeface_load_event_callback,
const std::string& language);
@@ -234,6 +234,10 @@
render_tree::FontVector* maybe_used_fonts);
private:
+ render_tree::ResourceProvider* resource_provider() const {
+ return *resource_provider_;
+ }
+
void ProcessInactiveFontLists(const base::TimeTicks& current_time);
void ProcessInactiveFonts(const base::TimeTicks& current_time);
@@ -269,7 +273,7 @@
// so that they'll be re-requested from the cache.
void OnRemoteTypefaceLoadEvent(const GURL& url);
- render_tree::ResourceProvider* const resource_provider_;
+ render_tree::ResourceProvider** resource_provider_;
// TODO: Explore eliminating the remote typeface cache and moving its
// logic into the font cache when the loader interface improves.
diff --git a/src/cobalt/dom/html_element.cc b/src/cobalt/dom/html_element.cc
index 2ed74fd..06e16c02 100644
--- a/src/cobalt/dom/html_element.cc
+++ b/src/cobalt/dom/html_element.cc
@@ -664,11 +664,13 @@
void HTMLElement::InvalidateLayoutBoxesFromNodeAndAncestors() {
layout_boxes_.reset();
+ cached_background_images_.clear();
Node::InvalidateLayoutBoxesFromNodeAndAncestors();
}
void HTMLElement::InvalidateLayoutBoxesFromNodeAndDescendants() {
layout_boxes_.reset();
+ cached_background_images_.clear();
Node::InvalidateLayoutBoxesFromNodeAndDescendants();
}
diff --git a/src/cobalt/dom/html_element_context.cc b/src/cobalt/dom/html_element_context.cc
index eee30eb..c7a9975 100644
--- a/src/cobalt/dom/html_element_context.cc
+++ b/src/cobalt/dom/html_element_context.cc
@@ -27,7 +27,7 @@
media::WebMediaPlayerFactory* web_media_player_factory,
script::ScriptRunner* script_runner,
MediaSource::Registry* media_source_registry,
- render_tree::ResourceProvider* resource_provider,
+ render_tree::ResourceProvider** resource_provider,
loader::image::ImageCache* image_cache,
loader::image::ReducedCacheCapacityManager*
reduced_image_cache_capacity_manager,
diff --git a/src/cobalt/dom/html_element_context.h b/src/cobalt/dom/html_element_context.h
index 8cdc86b..a751b03 100644
--- a/src/cobalt/dom/html_element_context.h
+++ b/src/cobalt/dom/html_element_context.h
@@ -48,7 +48,7 @@
media::WebMediaPlayerFactory* web_media_player_factory,
script::ScriptRunner* script_runner,
MediaSource::Registry* media_source_registry,
- render_tree::ResourceProvider* resource_provider,
+ render_tree::ResourceProvider** resource_provider,
loader::image::ImageCache* image_cache,
loader::image::ReducedCacheCapacityManager*
reduced_image_cache_capacity_manager,
@@ -75,7 +75,7 @@
return media_source_registry_;
}
- render_tree::ResourceProvider* resource_provider() const {
+ render_tree::ResourceProvider** resource_provider() const {
return resource_provider_;
}
@@ -108,7 +108,7 @@
media::WebMediaPlayerFactory* const web_media_player_factory_;
script::ScriptRunner* const script_runner_;
MediaSource::Registry* const media_source_registry_;
- render_tree::ResourceProvider* resource_provider_;
+ render_tree::ResourceProvider** resource_provider_;
loader::image::ImageCache* const image_cache_;
loader::image::ReducedCacheCapacityManager* const
reduced_image_cache_capacity_manager_;
diff --git a/src/cobalt/dom/html_media_element.cc b/src/cobalt/dom/html_media_element.cc
index 55d1295..e0f632c 100644
--- a/src/cobalt/dom/html_media_element.cc
+++ b/src/cobalt/dom/html_media_element.cc
@@ -509,7 +509,9 @@
html_element_context()->image_cache()->Purge();
// Ensure that all resource destructions are flushed and the memory is
// reclaimed.
- html_element_context()->resource_provider()->Finish();
+ if (*html_element_context()->resource_provider()) {
+ (*html_element_context()->resource_provider())->Finish();
+ }
}
player_.reset();
diff --git a/src/cobalt/dom/node.cc b/src/cobalt/dom/node.cc
index 59aed34..6ce2955 100644
--- a/src/cobalt/dom/node.cc
+++ b/src/cobalt/dom/node.cc
@@ -37,6 +37,13 @@
#include "cobalt/dom/node_list_live.h"
#include "cobalt/dom/rule_matching.h"
#include "cobalt/dom/text.h"
+#if defined(OS_STARBOARD)
+#include "starboard/configuration.h"
+#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
+#define HANDLE_CORE_DUMP
+#include "starboard/ps4/core_dump_handler.h"
+#endif // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
+#endif // defined(OS_STARBOARD)
namespace cobalt {
namespace dom {
@@ -49,8 +56,25 @@
NodeCountLog() : count(0) {
base::UserLog::Register(base::UserLog::kNodeCountIndex, "NodeCnt", &count,
sizeof(count));
+#if defined(HANDLE_CORE_DUMP)
+ SbCoreDumpRegisterHandler(CoreDumpHandler, this);
+#endif
}
- ~NodeCountLog() { base::UserLog::Deregister(base::UserLog::kNodeCountIndex); }
+
+ ~NodeCountLog() {
+#if defined(HANDLE_CORE_DUMP)
+ SbCoreDumpUnregisterHandler(CoreDumpHandler, this);
+#endif
+ base::UserLog::Deregister(base::UserLog::kNodeCountIndex);
+ }
+
+#if defined(HANDLE_CORE_DUMP)
+ static void CoreDumpHandler(void* context) {
+ SbCoreDumpLogInteger(
+ "Total number of nodes",
+ static_cast<NodeCountLog*>(context)->count);
+ }
+#endif
int count;
diff --git a/src/cobalt/dom/window.cc b/src/cobalt/dom/window.cc
index 054f995..fc3d881 100644
--- a/src/cobalt/dom/window.cc
+++ b/src/cobalt/dom/window.cc
@@ -62,7 +62,7 @@
Window::Window(int width, int height, cssom::CSSParser* css_parser,
Parser* dom_parser, loader::FetcherFactory* fetcher_factory,
- render_tree::ResourceProvider* resource_provider,
+ render_tree::ResourceProvider** resource_provider,
loader::image::ImageCache* image_cache,
loader::image::ReducedCacheCapacityManager*
reduced_image_cache_capacity_manager,
diff --git a/src/cobalt/dom/window.h b/src/cobalt/dom/window.h
index 7853ada..3a10095 100644
--- a/src/cobalt/dom/window.h
+++ b/src/cobalt/dom/window.h
@@ -87,7 +87,7 @@
Window(int width, int height, cssom::CSSParser* css_parser,
Parser* dom_parser, loader::FetcherFactory* fetcher_factory,
- render_tree::ResourceProvider* resource_provider,
+ render_tree::ResourceProvider** resource_provider,
loader::image::ImageCache* image_cache,
loader::image::ReducedCacheCapacityManager*
reduced_image_cache_capacity_manager,
diff --git a/src/cobalt/dom_parser/libxml_parser_wrapper.cc b/src/cobalt/dom_parser/libxml_parser_wrapper.cc
index 5e331f7..ef19c762 100644
--- a/src/cobalt/dom_parser/libxml_parser_wrapper.cc
+++ b/src/cobalt/dom_parser/libxml_parser_wrapper.cc
@@ -24,11 +24,81 @@
#include "cobalt/dom/comment.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/text.h"
+#if defined(OS_STARBOARD)
+#include "starboard/configuration.h"
+#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
+#define HANDLE_CORE_DUMP
+#include "base/lazy_instance.h"
+#include "starboard/ps4/core_dump_handler.h"
+#endif // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
+#endif // defined(OS_STARBOARD)
namespace cobalt {
namespace dom_parser {
namespace {
+#if defined(HANDLE_CORE_DUMP)
+
+class LibxmlParserWrapperLog {
+ public:
+ LibxmlParserWrapperLog()
+ : total_parsed_bytes_(0),
+ total_warning_count_(0),
+ total_error_count_(0),
+ total_fatal_count_(0) {
+ SbCoreDumpRegisterHandler(CoreDumpHandler, this);
+ }
+ ~LibxmlParserWrapperLog() {
+ SbCoreDumpUnregisterHandler(CoreDumpHandler, this);
+ }
+
+ static void CoreDumpHandler(void* context) {
+ SbCoreDumpLogInteger(
+ "LibxmlParserWrapper total parsed bytes",
+ static_cast<LibxmlParserWrapperLog*>(context)->total_parsed_bytes_);
+ SbCoreDumpLogInteger(
+ "LibxmlParserWrapper total warning count",
+ static_cast<LibxmlParserWrapperLog*>(context)->total_warning_count_);
+ SbCoreDumpLogInteger(
+ "LibxmlParserWrapper total error count",
+ static_cast<LibxmlParserWrapperLog*>(context)->total_error_count_);
+ SbCoreDumpLogInteger(
+ "LibxmlParserWrapper total fatal error count",
+ static_cast<LibxmlParserWrapperLog*>(context)->total_fatal_count_);
+ SbCoreDumpLogString("LibxmlParserWrapper last fatal error",
+ static_cast<LibxmlParserWrapperLog*>(context)
+ ->last_fatal_message_.c_str());
+ }
+
+ void IncrementParsedBytes(int length) { total_parsed_bytes_ += length; }
+ void LogParsingIssue(LibxmlParserWrapper::IssueSeverity severity,
+ const std::string& message) {
+ if (severity == LibxmlParserWrapper::kWarning) {
+ total_warning_count_++;
+ } else if (severity == LibxmlParserWrapper::kError) {
+ total_error_count_++;
+ } else if (severity == LibxmlParserWrapper::kFatal) {
+ total_fatal_count_++;
+ last_fatal_message_ = message;
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ private:
+ int total_parsed_bytes_;
+ int total_warning_count_;
+ int total_error_count_;
+ int total_fatal_count_;
+ std::string last_fatal_message_;
+ DISALLOW_COPY_AND_ASSIGN(LibxmlParserWrapperLog);
+};
+
+base::LazyInstance<LibxmlParserWrapperLog> libxml_parser_wrapper_log =
+ LAZY_INSTANCE_INITIALIZER;
+
+#endif // defined(HANDLE_CORE_DUMP)
+
/////////////////////////////////////////////////////////////////////////////
// Helpers
/////////////////////////////////////////////////////////////////////////////
@@ -226,12 +296,18 @@
if (severity < LibxmlParserWrapper::kFatal) {
LOG(WARNING) << "Libxml "
<< (severity == kWarning ? "Warning: " : "Error: ") << message;
- } else {
+ } else if (severity == LibxmlParserWrapper::kFatal) {
LOG(ERROR) << "Libxml Fatal Error: " << message;
if (!error_callback_.is_null()) {
error_callback_.Run(message);
}
+ } else {
+ NOTREACHED();
}
+
+#if defined(HANDLE_CORE_DUMP)
+ libxml_parser_wrapper_log.Get().LogParsingIssue(severity, message);
+#endif
}
void LibxmlParserWrapper::OnCDATABlock(const std::string& value) {
@@ -261,6 +337,10 @@
return max_severity_;
}
+#if defined(HANDLE_CORE_DUMP)
+ libxml_parser_wrapper_log.Get().IncrementParsedBytes(static_cast<int>(size));
+#endif
+
return max_severity_;
}
diff --git a/src/cobalt/layout/layout_manager.cc b/src/cobalt/layout/layout_manager.cc
index da165f9..adca585 100644
--- a/src/cobalt/layout/layout_manager.cc
+++ b/src/cobalt/layout/layout_manager.cc
@@ -51,6 +51,9 @@
// Called to perform a synchronous layout.
void DoSynchronousLayout();
+ void Suspend();
+ void Resume();
+
private:
void StartLayoutTimer();
void DoLayoutAndProduceRenderTree();
@@ -88,6 +91,8 @@
// the box tree remains valid.
scoped_refptr<BlockLevelBlockContainerBox> initial_containing_block_;
+ bool suspended_;
+
DISALLOW_COPY_AND_ASSIGN(Impl);
};
@@ -108,7 +113,8 @@
layout_timer_(true, true, true),
dom_max_element_depth_(dom_max_element_depth),
layout_refresh_rate_(layout_refresh_rate),
- layout_stat_tracker_(layout_stat_tracker) {
+ layout_stat_tracker_(layout_stat_tracker),
+ suspended_(false) {
window_->document()->AddObserver(this);
window_->SetSynchronousLayoutCallback(
base::Bind(&Impl::DoSynchronousLayout, base::Unretained(this)));
@@ -166,6 +172,10 @@
void LayoutManager::Impl::DoSynchronousLayout() {
TRACE_EVENT0("cobalt::layout", "LayoutManager::Impl::DoSynchronousLayout()");
+ if (suspended_) {
+ return;
+ }
+
layout::UpdateComputedStylesAndLayoutBoxTree(
locale_, window_->document(), dom_max_element_depth_,
used_style_provider_.get(), layout_stat_tracker_,
@@ -173,6 +183,26 @@
&initial_containing_block_);
}
+void LayoutManager::Impl::Suspend() {
+ // Mark that we are suspended so that we don't try to perform any layouts.
+ suspended_ = true;
+
+ // Clear our reference to the initial containing block to allow any resources
+ // like images that were referenced by it to be released.
+ initial_containing_block_ = NULL;
+
+ // Invalidate the document's layout so that all references to any resources
+ // such as images will be released.
+ window_->document()->InvalidateLayout();
+}
+
+void LayoutManager::Impl::Resume() {
+ // Mark that we are no longer suspended and indicate that the layout is
+ // dirty since when Suspend() was called we invalidated our previous layout.
+ layout_dirty_ = true;
+ suspended_ = false;
+}
+
#if defined(ENABLE_TEST_RUNNER)
void LayoutManager::Impl::DoTestRunnerLayoutCallback() {
DCHECK_EQ(kTestRunnerMode, layout_trigger_);
@@ -211,6 +241,8 @@
TRACE_EVENT0("cobalt::layout",
"LayoutManager::Impl::DoLayoutAndProduceRenderTree()");
+ if (suspended_) return;
+
const scoped_refptr<dom::Document>& document = window_->document();
if (!document->html()) {
@@ -280,5 +312,8 @@
LayoutManager::~LayoutManager() {}
+void LayoutManager::Suspend() { impl_->Suspend(); }
+void LayoutManager::Resume() { impl_->Resume(); }
+
} // namespace layout
} // namespace cobalt
diff --git a/src/cobalt/layout/layout_manager.h b/src/cobalt/layout/layout_manager.h
index 3c60206..5d2e189 100644
--- a/src/cobalt/layout/layout_manager.h
+++ b/src/cobalt/layout/layout_manager.h
@@ -68,6 +68,9 @@
LayoutStatTracker* layout_stat_tracker);
~LayoutManager();
+ void Suspend();
+ void Resume();
+
private:
class Impl;
const scoped_ptr<Impl> impl_;
diff --git a/src/cobalt/layout/replaced_box.cc b/src/cobalt/layout/replaced_box.cc
index 1b1c865..1be9e1a 100644
--- a/src/cobalt/layout/replaced_box.cc
+++ b/src/cobalt/layout/replaced_box.cc
@@ -20,7 +20,9 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "cobalt/cssom/filter_function_list_value.h"
#include "cobalt/cssom/keyword_value.h"
+#include "cobalt/cssom/mtm_function.h"
#include "cobalt/layout/container_box.h"
#include "cobalt/layout/letterboxed_image.h"
#include "cobalt/layout/used_style.h"
@@ -42,10 +44,11 @@
using render_tree::CompositionNode;
using render_tree::FilterNode;
using render_tree::ImageNode;
+using render_tree::MapToMeshFilter;
+using render_tree::Node;
using render_tree::PunchThroughVideoNode;
using render_tree::RectNode;
using render_tree::SolidColorBrush;
-using render_tree::MapToMeshFilter;
namespace {
@@ -259,9 +262,14 @@
composition_node, base::Bind(AnimateCB, replace_image_cb_, set_bounds_cb_,
content_box_size()));
- // TODO: Apply map to mesh filter if present.
+ Node* animate_node = new AnimateNode(animate_node_builder, composition_node);
+
+ const cssom::MTMFunction* mtm_filter_function =
+ cssom::MTMFunction::ExtractFromFilterList(computed_style()->filter());
+
border_node_builder->AddChild(
- new AnimateNode(animate_node_builder, composition_node));
+ mtm_filter_function ? new FilterNode(MapToMeshFilter(), animate_node)
+ : animate_node);
}
void ReplacedBox::UpdateContentSizeAndMargins(
diff --git a/src/cobalt/loader/decoder.h b/src/cobalt/loader/decoder.h
index 31ede20..f307097 100644
--- a/src/cobalt/loader/decoder.h
+++ b/src/cobalt/loader/decoder.h
@@ -44,6 +44,8 @@
// This is called when all data are sent in and decoding should be finalized.
virtual void Finish() = 0;
+
+ virtual void Abort() { NOTREACHED() << "Abort not supported."; }
};
} // namespace loader
diff --git a/src/cobalt/loader/font/remote_typeface_cache.h b/src/cobalt/loader/font/remote_typeface_cache.h
index 692e4e3..7a694c8 100644
--- a/src/cobalt/loader/font/remote_typeface_cache.h
+++ b/src/cobalt/loader/font/remote_typeface_cache.h
@@ -19,8 +19,9 @@
#include <string>
-#include "cobalt/loader/font/typeface_decoder.h"
+#include "cobalt/loader/loader_factory.h"
#include "cobalt/loader/resource_cache.h"
+#include "cobalt/render_tree/typeface.h"
namespace cobalt {
@@ -33,33 +34,10 @@
namespace loader {
namespace font {
-// |RemoteTypefaceDecoderProvider| provides a mechanism for |ResourceCache| to
-// create typeface decoders, without requiring it to know anything about the
-// render_tree.
-struct RemoteTypefaceDecoderProvider {
- public:
- explicit RemoteTypefaceDecoderProvider(
- render_tree::ResourceProvider* resource_provider)
- : resource_provider_(resource_provider) {}
-
- scoped_ptr<Decoder> CreateDecoder(
- const TypefaceDecoder::SuccessCallback& success_callback,
- const TypefaceDecoder::FailureCallback& failure_callback,
- const TypefaceDecoder::ErrorCallback& error_callback) const {
- return make_scoped_ptr<Decoder>(
- new TypefaceDecoder(resource_provider_, success_callback,
- failure_callback, error_callback));
- }
-
- private:
- render_tree::ResourceProvider* resource_provider_;
-};
-
// |RemoteTypefaceResourceCacheType| provides the types and implements the
// functions required by |ResourceCache<CacheType>|
struct RemoteTypefaceResourceCacheType {
typedef render_tree::Typeface ResourceType;
- typedef RemoteTypefaceDecoderProvider DecoderProviderType;
static uint32 GetEstimatedSizeInBytes(
const scoped_refptr<ResourceType>& resource) {
@@ -76,17 +54,14 @@
typedef ResourceCache<RemoteTypefaceResourceCacheType> RemoteTypefaceCache;
// CreateTypefaceCache() provides a mechanism for creating a remote typeface
-// cache, without requiring the caller to deal with the typeface decoder
-// provider
+// cache.
inline static scoped_ptr<RemoteTypefaceCache> CreateRemoteTypefaceCache(
const std::string& name, uint32 cache_capacity,
- render_tree::ResourceProvider* resource_provider,
- loader::FetcherFactory* fetcher_factory) {
+ loader::LoaderFactory* loader_factory) {
return make_scoped_ptr<RemoteTypefaceCache>(new RemoteTypefaceCache(
name, cache_capacity,
- make_scoped_ptr<RemoteTypefaceDecoderProvider>(
- new RemoteTypefaceDecoderProvider(resource_provider)),
- fetcher_factory));
+ base::Bind(&loader::LoaderFactory::CreateTypefaceLoader,
+ base::Unretained(loader_factory))));
}
} // namespace font
diff --git a/src/cobalt/loader/font/typeface_decoder.cc b/src/cobalt/loader/font/typeface_decoder.cc
index a0a57f4..2f7556d 100644
--- a/src/cobalt/loader/font/typeface_decoder.cc
+++ b/src/cobalt/loader/font/typeface_decoder.cc
@@ -28,7 +28,8 @@
: resource_provider_(resource_provider),
success_callback_(success_callback),
error_callback_(error_callback),
- is_raw_data_too_large_(false) {
+ is_raw_data_too_large_(false),
+ aborted_(false) {
UNREFERENCED_PARAMETER(failure_callback);
DCHECK(resource_provider_);
@@ -69,6 +70,17 @@
return;
}
+ if (aborted_) {
+ error_callback_.Run(
+ "TypefaceDecoder's ResourceProvider has been externally aborted.");
+ return;
+ }
+ if (!resource_provider_) {
+ error_callback_.Run(
+ "No resource provider was passed to the TypefaceDecoder.");
+ return;
+ }
+
std::string error_string;
scoped_refptr<render_tree::Typeface> decoded_typeface =
resource_provider_->CreateTypefaceFromRawData(raw_data_.Pass(),
@@ -83,6 +95,8 @@
void TypefaceDecoder::ReleaseRawData() { raw_data_.reset(); }
+void TypefaceDecoder::Abort() { aborted_ = true; }
+
} // namespace font
} // namespace loader
} // namespace cobalt
diff --git a/src/cobalt/loader/font/typeface_decoder.h b/src/cobalt/loader/font/typeface_decoder.h
index 90f5b1b..4af8965 100644
--- a/src/cobalt/loader/font/typeface_decoder.h
+++ b/src/cobalt/loader/font/typeface_decoder.h
@@ -48,6 +48,8 @@
void DecodeChunk(const char* data, size_t size) OVERRIDE;
void Finish() OVERRIDE;
+ void Abort() OVERRIDE;
+
private:
void ReleaseRawData();
@@ -57,6 +59,8 @@
scoped_ptr<render_tree::ResourceProvider::RawTypefaceDataVector> raw_data_;
bool is_raw_data_too_large_;
+
+ bool aborted_;
};
} // namespace font
diff --git a/src/cobalt/loader/image/image_cache.h b/src/cobalt/loader/image/image_cache.h
index 78a64a1..b99677c 100644
--- a/src/cobalt/loader/image/image_cache.h
+++ b/src/cobalt/loader/image/image_cache.h
@@ -19,39 +19,18 @@
#include <string>
-#include "cobalt/loader/image/image_decoder.h"
+#include "cobalt/loader/loader_factory.h"
#include "cobalt/loader/resource_cache.h"
+#include "cobalt/render_tree/image.h"
namespace cobalt {
namespace loader {
namespace image {
-// |ImageDecoderProvider| provides a mechanism for |ResourceCache| to create
-// decoders, without requiring it to know anything about the render_tree.
-struct ImageDecoderProvider {
- public:
- explicit ImageDecoderProvider(
- render_tree::ResourceProvider* resource_provider)
- : resource_provider_(resource_provider) {}
-
- scoped_ptr<Decoder> CreateDecoder(
- const ImageDecoder::SuccessCallback& success_callback,
- const ImageDecoder::FailureCallback& failure_callback,
- const ImageDecoder::ErrorCallback& error_callback) const {
- return make_scoped_ptr<Decoder>(
- new ImageDecoder(resource_provider_, success_callback, failure_callback,
- error_callback));
- }
-
- private:
- render_tree::ResourceProvider* resource_provider_;
-};
-
// |ImageResourceCacheType| provides the types and implements the functions
// required by |ResourceCache<ImageResourceCacheType>|
struct ImageResourceCacheType {
typedef render_tree::Image ResourceType;
- typedef ImageDecoderProvider DecoderProviderType;
static uint32 GetEstimatedSizeInBytes(
const scoped_refptr<ResourceType>& resource) {
@@ -67,16 +46,14 @@
typedef ResourceCache<ImageResourceCacheType> ImageCache;
-// CreateImageCache() provides a mechanism for creating an |ImageCache|, without
-// requiring the caller to deal with the |ImageDecoderProvider|
+// CreateImageCache() provides a mechanism for creating an |ImageCache|.
inline static scoped_ptr<ImageCache> CreateImageCache(
const std::string& name, uint32 cache_capacity,
- render_tree::ResourceProvider* resource_provider,
- loader::FetcherFactory* fetcher_factory) {
- return make_scoped_ptr<ImageCache>(new ImageCache(
- name, cache_capacity, make_scoped_ptr<ImageDecoderProvider>(
- new ImageDecoderProvider(resource_provider)),
- fetcher_factory));
+ loader::LoaderFactory* loader_factory) {
+ return make_scoped_ptr<ImageCache>(
+ new ImageCache(name, cache_capacity,
+ base::Bind(&loader::LoaderFactory::CreateImageLoader,
+ base::Unretained(loader_factory))));
}
// The ReducedCacheCapacityManager is a helper class that manages state which
diff --git a/src/cobalt/loader/image/image_decoder.cc b/src/cobalt/loader/image/image_decoder.cc
index f9f3ee9..24a8f9b 100644
--- a/src/cobalt/loader/image/image_decoder.cc
+++ b/src/cobalt/loader/image/image_decoder.cc
@@ -62,7 +62,9 @@
state_(kWaitingForHeader) {
signature_cache_.position = 0;
- DCHECK(resource_provider_);
+ if (!resource_provider_) {
+ state_ = kNoResourceProvider;
+ }
}
LoadResponseType ImageDecoder::OnResponseStarted(
@@ -132,6 +134,12 @@
case kUnsupportedImageFormat:
error_callback_.Run("Unsupported image format.");
break;
+ case kNoResourceProvider:
+ failure_callback_.Run("No resource provider was passed to the decoder.");
+ break;
+ case kAborted:
+ error_callback_.Run("ImageDecoder received an external signal to abort.");
+ break;
case kNotApplicable:
// no image is available.
failure_callback_.Run(failure_message_);
@@ -139,6 +147,16 @@
}
}
+void ImageDecoder::Abort() {
+ if (state_ == kDecoding) {
+ DCHECK(decoder_);
+ decoder_.reset();
+ state_ = kAborted;
+ } else if (state_ == kWaitingForHeader) {
+ state_ = kAborted;
+ }
+}
+
void ImageDecoder::DecodeChunkInternal(const uint8* input_bytes, size_t size) {
switch (state_) {
case kWaitingForHeader: {
@@ -164,6 +182,8 @@
} break;
case kNotApplicable:
case kUnsupportedImageFormat:
+ case kAborted:
+ case kNoResourceProvider:
default: {
// Do not attempt to continue processing data.
DCHECK(!decoder_);
diff --git a/src/cobalt/loader/image/image_decoder.h b/src/cobalt/loader/image/image_decoder.h
index fea43d4..be6e056 100644
--- a/src/cobalt/loader/image/image_decoder.h
+++ b/src/cobalt/loader/image/image_decoder.h
@@ -53,6 +53,8 @@
void DecodeChunk(const char* data, size_t size) OVERRIDE;
void Finish() OVERRIDE;
+ void Abort() OVERRIDE;
+
// Call this function to use the StubImageDecoder which produces a small image
// without decoding.
static void UseStubImageDecoder();
@@ -63,6 +65,8 @@
kDecoding,
kNotApplicable,
kUnsupportedImageFormat,
+ kNoResourceProvider,
+ kAborted,
};
// The current longest signature is WEBP signature.
diff --git a/src/cobalt/loader/loader.cc b/src/cobalt/loader/loader.cc
index 0dba924..90e6bfe 100644
--- a/src/cobalt/loader/loader.cc
+++ b/src/cobalt/loader/loader.cc
@@ -69,14 +69,15 @@
// Loader
//////////////////////////////////////////////////////////////////
-Loader::Loader(
- base::Callback<scoped_ptr<Fetcher>(Fetcher::Handler*)> fetcher_creator,
- scoped_ptr<Decoder> decoder,
- base::Callback<void(const std::string&)> error_callback)
+Loader::Loader(const FetcherCreator& fetcher_creator,
+ scoped_ptr<Decoder> decoder,
+ const base::Callback<void(const std::string&)>& error_callback,
+ const OnDestructionFunction& on_destruction)
: decoder_(decoder.Pass()),
fetcher_to_decoder_adaptor_(
new FetcherToDecoderAdapter(decoder_.get(), error_callback)),
- fetcher_(fetcher_creator.Run(fetcher_to_decoder_adaptor_.get())) {
+ fetcher_(fetcher_creator.Run(fetcher_to_decoder_adaptor_.get())),
+ on_destruction_(on_destruction) {
DCHECK(decoder_);
DCHECK(!error_callback.is_null());
DCHECK(!fetcher_creator.is_null());
@@ -92,9 +93,15 @@
}
Loader::~Loader() {
+ if (!on_destruction_.is_null()) {
+ on_destruction_.Run(this);
+ }
+
DCHECK(thread_checker_.CalledOnValidThread());
fetcher_creator_error_closure_.Cancel();
}
+void Loader::Abort() { decoder_->Abort(); }
+
} // namespace loader
} // namespace cobalt
diff --git a/src/cobalt/loader/loader.gyp b/src/cobalt/loader/loader.gyp
index 0b6698f..c0a7f79 100644
--- a/src/cobalt/loader/loader.gyp
+++ b/src/cobalt/loader/loader.gyp
@@ -49,6 +49,8 @@
'image/webp_image_decoder.h',
'loader.cc',
'loader.h',
+ 'loader_factory.cc',
+ 'loader_factory.h',
'loader_types.h',
'net_fetcher.cc',
'net_fetcher.h',
diff --git a/src/cobalt/loader/loader.h b/src/cobalt/loader/loader.h
index 313210d..43da425 100644
--- a/src/cobalt/loader/loader.h
+++ b/src/cobalt/loader/loader.h
@@ -36,17 +36,22 @@
// TODO: Migrate Loader design doc to markdown in this directory.
class Loader {
public:
+ typedef base::Callback<scoped_ptr<Fetcher>(Fetcher::Handler*)> FetcherCreator;
+ typedef base::Callback<void(Loader*)> OnDestructionFunction;
+
// The construction of Loader initiates the loading. It takes the ownership
// of a Decoder and creates and manages a Fetcher using the given creation
// method.
// The fetcher creator, decoder and error callback shouldn't be NULL.
// It is allowed to destroy the loader in the error callback.
- Loader(base::Callback<scoped_ptr<Fetcher>(Fetcher::Handler*)> fetcher_creator,
- scoped_ptr<Decoder> decoder,
- base::Callback<void(const std::string&)> error_callback);
+ Loader(const FetcherCreator& fetcher_creator, scoped_ptr<Decoder> decoder,
+ const base::Callback<void(const std::string&)>& error_callback,
+ const OnDestructionFunction& on_destruction = OnDestructionFunction());
~Loader();
+ void Abort();
+
private:
class FetcherToDecoderAdapter;
@@ -57,6 +62,8 @@
base::CancelableClosure fetcher_creator_error_closure_;
base::ThreadChecker thread_checker_;
+ OnDestructionFunction on_destruction_;
+
DISALLOW_COPY_AND_ASSIGN(Loader);
};
diff --git a/src/cobalt/loader/loader_factory.cc b/src/cobalt/loader/loader_factory.cc
new file mode 100644
index 0000000..9356c00
--- /dev/null
+++ b/src/cobalt/loader/loader_factory.cc
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "cobalt/loader/loader_factory.h"
+
+namespace cobalt {
+namespace loader {
+
+LoaderFactory::LoaderFactory(FetcherFactory* fetcher_factory,
+ render_tree::ResourceProvider* resource_provider)
+ : fetcher_factory_(fetcher_factory),
+ resource_provider_(resource_provider) {}
+
+scoped_ptr<Loader> LoaderFactory::CreateImageLoader(
+ const GURL& url, const csp::SecurityCallback& url_security_callback,
+ const image::ImageDecoder::SuccessCallback& success_callback,
+ const image::ImageDecoder::FailureCallback& failure_callback,
+ const image::ImageDecoder::ErrorCallback& error_callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ scoped_ptr<Loader> loader(new Loader(
+ MakeFetcherCreator(url, url_security_callback),
+ scoped_ptr<Decoder>(
+ new image::ImageDecoder(resource_provider_, success_callback,
+ failure_callback, error_callback)),
+ error_callback,
+ base::Bind(&LoaderFactory::OnLoaderDestroyed, base::Unretained(this))));
+ OnLoaderCreated(loader.get());
+ return loader.Pass();
+}
+
+scoped_ptr<Loader> LoaderFactory::CreateTypefaceLoader(
+ const GURL& url, const csp::SecurityCallback& url_security_callback,
+ const font::TypefaceDecoder::SuccessCallback& success_callback,
+ const font::TypefaceDecoder::FailureCallback& failure_callback,
+ const font::TypefaceDecoder::ErrorCallback& error_callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ scoped_ptr<Loader> loader(new Loader(
+ MakeFetcherCreator(url, url_security_callback),
+ scoped_ptr<Decoder>(
+ new font::TypefaceDecoder(resource_provider_, success_callback,
+ failure_callback, error_callback)),
+ error_callback,
+ base::Bind(&LoaderFactory::OnLoaderDestroyed, base::Unretained(this))));
+ OnLoaderCreated(loader.get());
+ return loader.Pass();
+}
+
+Loader::FetcherCreator LoaderFactory::MakeFetcherCreator(
+ const GURL& url, const csp::SecurityCallback& url_security_callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ return base::Bind(&FetcherFactory::CreateSecureFetcher,
+ base::Unretained(fetcher_factory_), url,
+ url_security_callback);
+}
+
+void LoaderFactory::Suspend() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(resource_provider_);
+
+ resource_provider_ = NULL;
+ for (LoaderSet::const_iterator iter = active_loaders_.begin();
+ iter != active_loaders_.end(); ++iter) {
+ (*iter)->Abort();
+ }
+}
+
+void LoaderFactory::Resume(render_tree::ResourceProvider* resource_provider) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(resource_provider);
+ DCHECK(!resource_provider_);
+
+ resource_provider_ = resource_provider;
+}
+
+void LoaderFactory::OnLoaderCreated(Loader* loader) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(active_loaders_.find(loader) == active_loaders_.end());
+ active_loaders_.insert(loader);
+}
+
+void LoaderFactory::OnLoaderDestroyed(Loader* loader) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(active_loaders_.find(loader) != active_loaders_.end());
+ active_loaders_.erase(loader);
+}
+
+} // namespace loader
+} // namespace cobalt
diff --git a/src/cobalt/loader/loader_factory.h b/src/cobalt/loader/loader_factory.h
new file mode 100644
index 0000000..000e7ad
--- /dev/null
+++ b/src/cobalt/loader/loader_factory.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COBALT_LOADER_LOADER_FACTORY_H_
+#define COBALT_LOADER_LOADER_FACTORY_H_
+
+#include <set>
+
+#include "cobalt/csp/content_security_policy.h"
+#include "cobalt/loader/fetcher_factory.h"
+#include "cobalt/loader/font/typeface_decoder.h"
+#include "cobalt/loader/image/image_decoder.h"
+#include "cobalt/loader/loader.h"
+#include "cobalt/render_tree/resource_provider.h"
+#include "googleurl/src/gurl.h"
+
+namespace cobalt {
+namespace loader {
+
+// The LoaderFactory provides a central loader creator object from which clients
+// can request the creation of loaders of various types. The LoaderFactory
+// maintains all context necessary to create the various resource types.
+class LoaderFactory {
+ public:
+ LoaderFactory(FetcherFactory* fetcher_factory,
+ render_tree::ResourceProvider* resource_provider);
+
+ // Creates a loader that fetches and decodes a render_tree::Image.
+ scoped_ptr<Loader> CreateImageLoader(
+ const GURL& url, const csp::SecurityCallback& url_security_callback,
+ const image::ImageDecoder::SuccessCallback& success_callback,
+ const image::ImageDecoder::FailureCallback& failure_callback,
+ const image::ImageDecoder::ErrorCallback& error_callback);
+
+ // Creates a loader that fetches and decodes a render_tree::Typeface.
+ scoped_ptr<Loader> CreateTypefaceLoader(
+ const GURL& url, const csp::SecurityCallback& url_security_callback,
+ const font::TypefaceDecoder::SuccessCallback& success_callback,
+ const font::TypefaceDecoder::FailureCallback& failure_callback,
+ const font::TypefaceDecoder::ErrorCallback& error_callback);
+
+ // Clears out the loader factory's resource provider, aborting any in-progress
+ // loads.
+ void Suspend();
+ // Resets a new resource provider for this loader factory to use. The
+ // previous resource provider must have been cleared before this method is
+ // called.
+ void Resume(render_tree::ResourceProvider* resource_provider);
+
+ private:
+ void OnLoaderCreated(Loader* loader);
+ void OnLoaderDestroyed(Loader* loader);
+
+ Loader::FetcherCreator MakeFetcherCreator(
+ const GURL& url, const csp::SecurityCallback& url_security_callback);
+
+ // Ensures that the LoaderFactory methods are only called from the same
+ // thread.
+ base::ThreadChecker thread_checker_;
+
+ // Used to create the Fetcher component of the loaders.
+ FetcherFactory* fetcher_factory_;
+
+ // Used to create render_tree resources.
+ render_tree::ResourceProvider* resource_provider_;
+
+ // Keeps track of all active loaders so that if a suspend event occurs they
+ // can be aborted.
+ typedef std::set<Loader*> LoaderSet;
+ LoaderSet active_loaders_;
+};
+
+} // namespace loader
+} // namespace cobalt
+
+#endif // COBALT_LOADER_LOADER_FACTORY_H_
diff --git a/src/cobalt/loader/net_fetcher.cc b/src/cobalt/loader/net_fetcher.cc
index 4ba9d17..0f60e72 100644
--- a/src/cobalt/loader/net_fetcher.cc
+++ b/src/cobalt/loader/net_fetcher.cc
@@ -21,12 +21,46 @@
#include "base/stringprintf.h"
#include "cobalt/network/network_module.h"
#include "net/url_request/url_fetcher.h"
+#if defined(OS_STARBOARD)
+#include "starboard/configuration.h"
+#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
+#define HANDLE_CORE_DUMP
+#include "base/lazy_instance.h"
+#include "starboard/ps4/core_dump_handler.h"
+#endif // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
+#endif // OS_STARBOARD
namespace cobalt {
namespace loader {
namespace {
+#if defined(HANDLE_CORE_DUMP)
+
+class NetFetcherLog {
+ public:
+ NetFetcherLog() : total_fetched_bytes_(0) {
+ SbCoreDumpRegisterHandler(CoreDumpHandler, this);
+ }
+ ~NetFetcherLog() { SbCoreDumpUnregisterHandler(CoreDumpHandler, this); }
+
+ static void CoreDumpHandler(void* context) {
+ SbCoreDumpLogInteger(
+ "NetFetcher total fetched bytes",
+ static_cast<NetFetcherLog*>(context)->total_fetched_bytes_);
+ }
+
+ void IncrementFetchedBytes(int length) { total_fetched_bytes_ += length; }
+
+ private:
+ int total_fetched_bytes_;
+ DISALLOW_COPY_AND_ASSIGN(NetFetcherLog);
+};
+
+base::LazyInstance<NetFetcherLog> net_fetcher_log = LAZY_INSTANCE_INITIALIZER;
+
+#endif // defined(HANDLE_CORE_DUMP)
+
bool IsResponseCodeSuccess(int response_code) {
// NetFetcher only considers success to be if the network request
// was successful *and* we get a 2xx response back.
@@ -118,6 +152,10 @@
void NetFetcher::OnURLFetchDownloadData(const net::URLFetcher* source,
scoped_ptr<std::string> download_data) {
if (IsResponseCodeSuccess(source->GetResponseCode())) {
+#if defined(HANDLE_CORE_DUMP)
+ net_fetcher_log.Get().IncrementFetchedBytes(
+ static_cast<int>(download_data->length()));
+#endif
handler()->OnReceived(this, download_data->data(), download_data->length());
}
}
diff --git a/src/cobalt/loader/resource_cache.h b/src/cobalt/loader/resource_cache.h
index f522f5b..2f4ce23 100644
--- a/src/cobalt/loader/resource_cache.h
+++ b/src/cobalt/loader/resource_cache.h
@@ -41,7 +41,6 @@
// CacheType must provide the following:
// typedef SpecificResourceType ResourceType;
-// typedef SpecificDecoderProviderType DecoderProviderType;
// static uint32 GetEstimatedSizeInBytes(
// const scoped_refptr<ResourceType>& resource);
@@ -61,7 +60,12 @@
public:
typedef ResourceCache<CacheType> ResourceCacheType;
typedef typename CacheType::ResourceType ResourceType;
- typedef typename CacheType::DecoderProviderType DecoderProviderType;
+
+ typedef base::Callback<scoped_ptr<Loader>(
+ const GURL&, const csp::SecurityCallback&,
+ const base::Callback<void(const scoped_refptr<ResourceType>&)>&,
+ const base::Callback<void(const std::string&)>&,
+ const base::Callback<void(const std::string&)>&)> CreateLoaderFunction;
// This class can be used to attach success, failure, or error callbacks to
// CachedResource objects that are executed when the resource finishes
@@ -95,8 +99,7 @@
// Request fetching and decoding a single resource based on the url.
CachedResource(const GURL& url,
const csp::SecurityCallback& security_callback,
- const DecoderProviderType* decoder_provider,
- loader::FetcherFactory* fetcher_factory,
+ const CreateLoaderFunction& create_loader_function,
ResourceCacheType* resource_cache);
// Resource is available. CachedResource is a wrapper of the resource
@@ -148,6 +151,7 @@
void RunCallbacks(CallbackType type);
const GURL url_;
+
scoped_refptr<ResourceType> resource_;
ResourceCacheType* const resource_cache_;
scoped_ptr<Loader> loader_;
@@ -218,20 +222,16 @@
template <typename CacheType>
CachedResource<CacheType>::CachedResource(
const GURL& url, const csp::SecurityCallback& security_callback,
- const DecoderProviderType* decoder_provider,
- loader::FetcherFactory* fetcher_factory, ResourceCacheType* resource_cache)
+ const CreateLoaderFunction& create_loader_function,
+ ResourceCacheType* resource_cache)
: url_(url), resource_cache_(resource_cache) {
DCHECK(cached_resource_thread_checker_.CalledOnValidThread());
- scoped_ptr<Decoder> decoder = decoder_provider->CreateDecoder(
+ loader_ = create_loader_function.Run(
+ url, security_callback,
base::Bind(&CachedResource::OnLoadingSuccess, base::Unretained(this)),
base::Bind(&CachedResource::OnLoadingFailure, base::Unretained(this)),
base::Bind(&CachedResource::OnLoadingError, base::Unretained(this)));
- loader_ = make_scoped_ptr(new Loader(
- base::Bind(&FetcherFactory::CreateSecureFetcher,
- base::Unretained(fetcher_factory), url, security_callback),
- decoder.Pass(),
- base::Bind(&CachedResource::OnLoadingError, base::Unretained(this))));
}
template <typename CacheType>
@@ -387,11 +387,12 @@
public:
typedef CachedResource<CacheType> CachedResourceType;
typedef typename CacheType::ResourceType ResourceType;
- typedef typename CacheType::DecoderProviderType DecoderProviderType;
+
+ typedef
+ typename CachedResourceType::CreateLoaderFunction CreateLoaderFunction;
ResourceCache(const std::string& name, uint32 cache_capacity,
- scoped_ptr<DecoderProviderType> decoder_provider,
- loader::FetcherFactory* fetcher_factory);
+ const CreateLoaderFunction& create_loader_function);
// |CreateCachedResource| returns CachedResource. If the CachedResource is not
// in |cached_resource_map_| or its resource is not in
@@ -443,8 +444,8 @@
uint32 cache_capacity_;
- scoped_ptr<DecoderProviderType> decoder_provider_;
- loader::FetcherFactory* const fetcher_factory_;
+ CreateLoaderFunction create_loader_function_;
+
csp::SecurityCallback security_callback_;
// |cached_resource_map_| stores the cached resources that are currently
@@ -471,12 +472,10 @@
template <typename CacheType>
ResourceCache<CacheType>::ResourceCache(
const std::string& name, uint32 cache_capacity,
- scoped_ptr<DecoderProviderType> decoder_provider,
- loader::FetcherFactory* fetcher_factory)
+ const CreateLoaderFunction& create_loader_function)
: name_(name),
cache_capacity_(cache_capacity),
- decoder_provider_(decoder_provider.release()),
- fetcher_factory_(fetcher_factory),
+ create_loader_function_(create_loader_function),
size_in_bytes_(base::StringPrintf("%s.Size", name_.c_str()), 0,
"Total number of bytes currently used by the cache."),
capacity_in_bytes_(base::StringPrintf("%s.Capacity", name_.c_str()),
@@ -485,8 +484,7 @@
"Exceeding this results in *unused* resources being "
"purged.") {
DCHECK(resource_cache_thread_checker_.CalledOnValidThread());
- DCHECK(decoder_provider_.get());
- DCHECK(fetcher_factory_);
+ DCHECK(!create_loader_function_.is_null());
}
template <typename CacheType>
@@ -516,9 +514,8 @@
// If the resource doesn't exist, create a cached resource and fetch the
// resource based on the url.
- scoped_refptr<CachedResourceType> cached_resource(
- new CachedResourceType(url, security_callback_, decoder_provider_.get(),
- fetcher_factory_, this));
+ scoped_refptr<CachedResourceType> cached_resource(new CachedResourceType(
+ url, security_callback_, create_loader_function_, this));
cached_resource_map_.insert(
std::make_pair(url.spec(), cached_resource.get()));
return cached_resource;
diff --git a/src/cobalt/renderer/rasterizer/blitter/image.cc b/src/cobalt/renderer/rasterizer/blitter/image.cc
index 3e8ece5..5932ddd 100644
--- a/src/cobalt/renderer/rasterizer/blitter/image.cc
+++ b/src/cobalt/renderer/rasterizer/blitter/image.cc
@@ -65,7 +65,7 @@
CHECK(SbBlitterIsSurfaceValid(surface_));
}
-void SinglePlaneImage::EnsureInitialized() {}
+bool SinglePlaneImage::EnsureInitialized() { return false; }
const SkBitmap& SinglePlaneImage::GetBitmap() const {
// This function will only ever get called if the Skia software renderer needs
diff --git a/src/cobalt/renderer/rasterizer/blitter/image.h b/src/cobalt/renderer/rasterizer/blitter/image.h
index 7275225..605cabe 100644
--- a/src/cobalt/renderer/rasterizer/blitter/image.h
+++ b/src/cobalt/renderer/rasterizer/blitter/image.h
@@ -77,7 +77,7 @@
SbBlitterSurface surface() const { return surface_; }
// Overrides from skia::SinglePlaneImage.
- void EnsureInitialized() OVERRIDE;
+ bool EnsureInitialized() OVERRIDE;
// When GetBitmap() is called on a blitter::SinglePlaneImage for the first
// time, we do a one-time download of the pixel data from the Blitter API
diff --git a/src/cobalt/renderer/rasterizer/skia/hardware_image.cc b/src/cobalt/renderer/rasterizer/skia/hardware_image.cc
index f8096b0..0300dd6 100644
--- a/src/cobalt/renderer/rasterizer/skia/hardware_image.cc
+++ b/src/cobalt/renderer/rasterizer/skia/hardware_image.cc
@@ -210,12 +210,14 @@
return backend_image_->GetBitmap();
}
-void HardwareFrontendImage::EnsureInitialized() {
+bool HardwareFrontendImage::EnsureInitialized() {
DCHECK_EQ(rasterizer_message_loop_, MessageLoop::current());
if (!initialize_backend_image_.is_null()) {
initialize_backend_image_.Run();
initialize_backend_image_.Reset();
+ return true;
}
+ return false;
}
void HardwareFrontendImage::InitializeBackendImageFromImageData(
@@ -257,16 +259,18 @@
HardwareMultiPlaneImage::~HardwareMultiPlaneImage() {}
-void HardwareMultiPlaneImage::EnsureInitialized() {
+bool HardwareMultiPlaneImage::EnsureInitialized() {
// A multi-plane image is not considered backend-initialized until all its
// single-plane images are backend-initialized, thus we ensure that all
// the component images are backend-initialized.
+ bool initialized = false;
for (int i = 0; i < render_tree::MultiPlaneImageDataDescriptor::kMaxPlanes;
++i) {
if (planes_[i]) {
- planes_[i]->EnsureInitialized();
+ initialized |= planes_[i]->EnsureInitialized();
}
}
+ return initialized;
}
} // namespace skia
diff --git a/src/cobalt/renderer/rasterizer/skia/hardware_image.h b/src/cobalt/renderer/rasterizer/skia/hardware_image.h
index 15c318e..1590567 100644
--- a/src/cobalt/renderer/rasterizer/skia/hardware_image.h
+++ b/src/cobalt/renderer/rasterizer/skia/hardware_image.h
@@ -100,7 +100,7 @@
// restraint should always be satisfied naturally.
const SkBitmap& GetBitmap() const OVERRIDE;
- void EnsureInitialized() OVERRIDE;
+ bool EnsureInitialized() OVERRIDE;
private:
~HardwareFrontendImage() OVERRIDE;
@@ -164,7 +164,7 @@
return planes_[plane_index]->GetBitmap();
}
- void EnsureInitialized() OVERRIDE;
+ bool EnsureInitialized() OVERRIDE;
private:
~HardwareMultiPlaneImage() OVERRIDE;
diff --git a/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc b/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc
index 20ddfd5..1c55dc0 100644
--- a/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc
+++ b/src/cobalt/renderer/rasterizer/skia/hardware_rasterizer.cc
@@ -70,6 +70,8 @@
scoped_ptr<RenderTreeNodeVisitor::ScratchSurface> CreateScratchSurface(
const math::Size& size);
+ void ResetSkiaState();
+
base::ThreadChecker thread_checker_;
backend::GraphicsContextEGL* graphics_context_;
@@ -238,6 +240,8 @@
base::Unretained(this));
RenderTreeNodeVisitor visitor(
canvas, &create_scratch_surface_function,
+ base::Bind(&HardwareRasterizer::Impl::ResetSkiaState,
+ base::Unretained(this)),
surface_cache_delegate_ ? &surface_cache_delegate_.value() : NULL,
surface_cache_ ? &surface_cache_.value() : NULL);
render_tree->Accept(&visitor);
@@ -304,6 +308,8 @@
}
}
+void HardwareRasterizer::Impl::ResetSkiaState() { gr_context_->resetContext(); }
+
HardwareRasterizer::HardwareRasterizer(
backend::GraphicsContext* graphics_context, int skia_cache_size_in_bytes,
int scratch_surface_cache_size_in_bytes, int surface_cache_size_in_bytes)
diff --git a/src/cobalt/renderer/rasterizer/skia/image.h b/src/cobalt/renderer/rasterizer/skia/image.h
index cd2e907..bb696aa 100644
--- a/src/cobalt/renderer/rasterizer/skia/image.h
+++ b/src/cobalt/renderer/rasterizer/skia/image.h
@@ -41,7 +41,8 @@
// to be referenced in a render tree before then, and thus this function will
// fast-track the initialization of the backend object if it has not yet
// executed.
- virtual void EnsureInitialized() = 0;
+ // Returns true if an initialization actually took place.
+ virtual bool EnsureInitialized() = 0;
// Mechanism to allow dynamic type checking on Image objects.
virtual base::TypeId GetTypeId() const = 0;
diff --git a/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc b/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
index ab9fc7d..748aefd 100644
--- a/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
+++ b/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.cc
@@ -72,13 +72,15 @@
RenderTreeNodeVisitor::RenderTreeNodeVisitor(
SkCanvas* render_target,
const CreateScratchSurfaceFunction* create_scratch_surface_function,
+ const base::Closure& reset_skia_context_function,
SurfaceCacheDelegate* surface_cache_delegate,
common::SurfaceCache* surface_cache, Type visitor_type)
: draw_state_(render_target),
create_scratch_surface_function_(create_scratch_surface_function),
surface_cache_delegate_(surface_cache_delegate),
surface_cache_(surface_cache),
- visitor_type_(visitor_type) {
+ visitor_type_(visitor_type),
+ reset_skia_context_function_(reset_skia_context_function) {
DCHECK_EQ(surface_cache_delegate_ == NULL, surface_cache_ == NULL);
if (surface_cache_delegate_) {
// Update our surface cache delegate to point to this render tree node
@@ -264,9 +266,9 @@
// Render our source sub-tree into the offscreen surface.
{
- RenderTreeNodeVisitor sub_visitor(canvas, create_scratch_surface_function_,
- surface_cache_delegate_, surface_cache_,
- kType_SubVisitor);
+ RenderTreeNodeVisitor sub_visitor(
+ canvas, create_scratch_surface_function_, reset_skia_context_function_,
+ surface_cache_delegate_, surface_cache_, kType_SubVisitor);
filter_node.source->Accept(&sub_visitor);
}
@@ -622,7 +624,14 @@
// This should be a quick operation, and it needs to happen eventually, so
// if it is not done now, it will be done in the next frame, or the one after
// that.
- image->EnsureInitialized();
+ if (image->EnsureInitialized()) {
+ // EnsureInitialized() may make a number of GL calls that results in GL
+ // state being modified behind Skia's back, therefore we have Skia reset its
+ // state in this case.
+ if (!reset_skia_context_function_.is_null()) {
+ reset_skia_context_function_.Run();
+ }
+ }
// We issue different skia rasterization commands to render the image
// depending on whether it's single or multi planed.
diff --git a/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.h b/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.h
index 3efa3c6..65dac0e 100644
--- a/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.h
+++ b/src/cobalt/renderer/rasterizer/skia/render_tree_node_visitor.h
@@ -73,6 +73,7 @@
RenderTreeNodeVisitor(
SkCanvas* render_target,
const CreateScratchSurfaceFunction* create_scratch_surface_function,
+ const base::Closure& reset_skia_context_function,
SurfaceCacheDelegate* surface_cache_delegate,
common::SurfaceCache* surface_cache, Type visitor_type = kType_Normal);
@@ -104,6 +105,8 @@
base::optional<SurfaceCacheDelegate::ScopedContext>
surface_cache_scoped_context_;
+ base::Closure reset_skia_context_function_;
+
DISALLOW_COPY_AND_ASSIGN(RenderTreeNodeVisitor);
};
diff --git a/src/cobalt/renderer/rasterizer/skia/software_image.h b/src/cobalt/renderer/rasterizer/skia/software_image.h
index 37bd1ad..63afe6a 100644
--- a/src/cobalt/renderer/rasterizer/skia/software_image.h
+++ b/src/cobalt/renderer/rasterizer/skia/software_image.h
@@ -55,7 +55,7 @@
const SkBitmap& GetBitmap() const OVERRIDE { return bitmap_; }
- void EnsureInitialized() OVERRIDE {}
+ bool EnsureInitialized() OVERRIDE { return false; }
private:
void Initialize(uint8_t* source_data,
@@ -95,7 +95,7 @@
return planes_[plane_index]->GetBitmap();
}
- void EnsureInitialized() OVERRIDE {}
+ bool EnsureInitialized() OVERRIDE { return false; }
private:
math::Size size_;
diff --git a/src/cobalt/renderer/rasterizer/skia/software_rasterizer.cc b/src/cobalt/renderer/rasterizer/skia/software_rasterizer.cc
index d1cafc6..884db9e 100644
--- a/src/cobalt/renderer/rasterizer/skia/software_rasterizer.cc
+++ b/src/cobalt/renderer/rasterizer/skia/software_rasterizer.cc
@@ -120,7 +120,7 @@
RenderTreeNodeVisitor::CreateScratchSurfaceFunction
create_scratch_surface_function = base::Bind(&CreateScratchSurface);
RenderTreeNodeVisitor visitor(
- render_target, &create_scratch_surface_function,
+ render_target, &create_scratch_surface_function, base::Closure(),
surface_cache_delegate_ ? &surface_cache_delegate_.value() : NULL,
surface_cache_ ? &surface_cache_.value() : NULL);
diff --git a/src/cobalt/renderer/renderer_module.cc b/src/cobalt/renderer/renderer_module.cc
index ebe8531..23ee70e 100644
--- a/src/cobalt/renderer/renderer_module.cc
+++ b/src/cobalt/renderer/renderer_module.cc
@@ -30,9 +30,26 @@
}
RendererModule::RendererModule(system_window::SystemWindow* system_window,
- const Options& options) {
+ const Options& options)
+ : system_window_(system_window), options_(options) {
TRACE_EVENT0("cobalt::renderer", "RendererModule::RendererModule()");
+ Resume();
+}
+
+RendererModule::~RendererModule() {}
+
+void RendererModule::Suspend() {
+ TRACE_EVENT0("cobalt::renderer", "RendererModule::Suspend()");
+ pipeline_.reset();
+ graphics_context_.reset();
+ display_.reset();
+ graphics_system_.reset();
+}
+
+void RendererModule::Resume() {
+ TRACE_EVENT0("cobalt::renderer", "RendererModule::Resume()");
+
// Load up the platform's default graphics system.
{
TRACE_EVENT0("cobalt::renderer", "backend::CreateDefaultGraphicsSystem()");
@@ -43,8 +60,8 @@
// specified in the constructor args to get the render target.
{
TRACE_EVENT0("cobalt::renderer", "GraphicsSystem::CreateDisplay()");
- DCHECK(system_window);
- display_ = graphics_system_->CreateDisplay(system_window);
+ DCHECK(system_window_);
+ display_ = graphics_system_->CreateDisplay(system_window_);
}
// Create a graphics context associated with the default display's render
@@ -60,15 +77,12 @@
{
TRACE_EVENT0("cobalt::renderer", "new renderer::Pipeline()");
pipeline_ = make_scoped_ptr(new renderer::Pipeline(
- base::Bind(options.create_rasterizer_function, graphics_context_.get(),
- options),
+ base::Bind(options_.create_rasterizer_function, graphics_context_.get(),
+ options_),
display_->GetRenderTarget(), graphics_context_.get(),
- options.submit_even_if_render_tree_is_unchanged));
+ options_.submit_even_if_render_tree_is_unchanged));
}
}
-RendererModule::~RendererModule() {
-}
-
} // namespace renderer
} // namespace cobalt
diff --git a/src/cobalt/renderer/renderer_module.h b/src/cobalt/renderer/renderer_module.h
index fab4b63..44099d6 100644
--- a/src/cobalt/renderer/renderer_module.h
+++ b/src/cobalt/renderer/renderer_module.h
@@ -76,12 +76,18 @@
const Options& options);
~RendererModule();
+ void Suspend();
+ void Resume();
+
renderer::Pipeline* pipeline() { return pipeline_.get(); }
const scoped_refptr<renderer::backend::RenderTarget> render_target() {
return display_->GetRenderTarget();
}
private:
+ system_window::SystemWindow* system_window_;
+ Options options_;
+
scoped_ptr<renderer::backend::GraphicsSystem> graphics_system_;
scoped_ptr<renderer::backend::Display> display_;
scoped_ptr<renderer::backend::GraphicsContext> graphics_context_;
diff --git a/src/cobalt/script/mozjs/wrapper_factory.cc b/src/cobalt/script/mozjs/wrapper_factory.cc
index 72b2edb..d533458 100644
--- a/src/cobalt/script/mozjs/wrapper_factory.cc
+++ b/src/cobalt/script/mozjs/wrapper_factory.cc
@@ -79,8 +79,14 @@
new MozjsWrapperHandle(wrapper_private));
}
-bool WrapperFactory::DoesObjectImplementInterface(JSObject* object,
+bool WrapperFactory::DoesObjectImplementInterface(JS::HandleObject object,
base::TypeId type_id) const {
+ // If the object doesn't have a wrapper private which means it is not a
+ // platform object, so the object doesn't implement the interface.
+ if (!WrapperPrivate::HasWrapperPrivate(context_, object)) {
+ return false;
+ }
+
WrappableTypeFunctionsHashMap::const_iterator it =
wrappable_type_functions_.find(type_id);
if (it == wrappable_type_functions_.end()) {
diff --git a/src/cobalt/script/mozjs/wrapper_factory.h b/src/cobalt/script/mozjs/wrapper_factory.h
index 828bdac..79be1b7 100644
--- a/src/cobalt/script/mozjs/wrapper_factory.h
+++ b/src/cobalt/script/mozjs/wrapper_factory.h
@@ -51,7 +51,8 @@
// Returns true if this JSObject is a Wrapper object.
bool IsWrapper(JS::HandleObject wrapper) const;
- bool DoesObjectImplementInterface(JSObject*, base::TypeId) const;
+ bool DoesObjectImplementInterface(JS::HandleObject object,
+ base::TypeId id) const;
private:
struct WrappableTypeFunctions {
diff --git a/src/cobalt/script/mozjs/wrapper_private.cc b/src/cobalt/script/mozjs/wrapper_private.cc
index 7dc1410..1bf15ca 100644
--- a/src/cobalt/script/mozjs/wrapper_private.cc
+++ b/src/cobalt/script/mozjs/wrapper_private.cc
@@ -20,6 +20,7 @@
#include "cobalt/script/mozjs/proxy_handler.h"
#include "cobalt/script/mozjs/referenced_object_map.h"
#include "third_party/mozjs/js/src/jsapi.h"
+#include "third_party/mozjs/js/src/jsobj.h"
#include "third_party/mozjs/js/src/jsproxy.h"
namespace cobalt {
@@ -65,6 +66,17 @@
}
// static
+bool WrapperPrivate::HasWrapperPrivate(JSContext* context,
+ JS::HandleObject object) {
+ if (js::IsProxy(object)) {
+ JS::RootedObject target_object(context, js::GetProxyTargetObject(object));
+ return WrapperPrivate::HasWrapperPrivate(context, target_object);
+ }
+
+ return object->hasPrivate();
+}
+
+// static
WrapperPrivate* WrapperPrivate::GetFromWrappable(
const scoped_refptr<Wrappable>& wrappable, JSContext* context,
WrapperFactory* wrapper_factory) {
diff --git a/src/cobalt/script/mozjs/wrapper_private.h b/src/cobalt/script/mozjs/wrapper_private.h
index d7ebfb1..ae0286d 100644
--- a/src/cobalt/script/mozjs/wrapper_private.h
+++ b/src/cobalt/script/mozjs/wrapper_private.h
@@ -69,6 +69,9 @@
GetReachableWrappablesFunction());
}
+ // Return true if the object has wrapper private.
+ static bool HasWrapperPrivate(JSContext* context, JS::HandleObject object);
+
// Get the WrapperPrivate associated with the given Wrappable. A new JSObject
// and WrapperPrivate object may be created.
static WrapperPrivate* GetFromWrappable(
diff --git a/src/cobalt/script/script_runner.cc b/src/cobalt/script/script_runner.cc
index d680966..3900885 100644
--- a/src/cobalt/script/script_runner.cc
+++ b/src/cobalt/script/script_runner.cc
@@ -19,12 +19,51 @@
#include "base/logging.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/source_code.h"
+#if defined(OS_STARBOARD)
+#include "starboard/configuration.h"
+#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
+#define HANDLE_CORE_DUMP
+#include "base/lazy_instance.h"
+#include "starboard/ps4/core_dump_handler.h"
+#endif // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
+#endif // defined(OS_STARBOARD)
namespace cobalt {
namespace script {
namespace {
+#if defined(HANDLE_CORE_DUMP)
+
+class ScriptRunnerLog {
+ public:
+ ScriptRunnerLog() : success_count_(0), fail_count_(0) {
+ SbCoreDumpRegisterHandler(CoreDumpHandler, this);
+ }
+ ~ScriptRunnerLog() { SbCoreDumpUnregisterHandler(CoreDumpHandler, this); }
+
+ static void CoreDumpHandler(void* context) {
+ SbCoreDumpLogInteger(
+ "ScriptRunner successful executions",
+ static_cast<ScriptRunnerLog*>(context)->success_count_);
+ SbCoreDumpLogInteger("ScriptRunner failed executions",
+ static_cast<ScriptRunnerLog*>(context)->fail_count_);
+ }
+
+ void IncrementSuccessCount() { success_count_++; }
+ void IncrementFailCount() { fail_count_++; }
+
+ private:
+ int success_count_;
+ int fail_count_;
+ DISALLOW_COPY_AND_ASSIGN(ScriptRunnerLog);
+};
+
+base::LazyInstance<ScriptRunnerLog> script_runner_log =
+ LAZY_INSTANCE_INITIALIZER;
+
+#endif // defined(HANDLE_CORE_DUMP)
+
class ScriptRunnerImpl : public ScriptRunner {
public:
explicit ScriptRunnerImpl(
@@ -53,8 +92,14 @@
std::string result;
if (!global_environment_->EvaluateScript(source_code, &result)) {
DLOG(WARNING) << "Failed to execute JavaScript: " << result;
+#if defined(HANDLE_CORE_DUMP)
+ script_runner_log.Get().IncrementFailCount();
+#endif
return "";
}
+#if defined(HANDLE_CORE_DUMP)
+ script_runner_log.Get().IncrementSuccessCount();
+#endif
return result;
}
diff --git a/src/cobalt/speech/chunked_byte_buffer.cc b/src/cobalt/speech/chunked_byte_buffer.cc
new file mode 100644
index 0000000..43772df
--- /dev/null
+++ b/src/cobalt/speech/chunked_byte_buffer.cc
@@ -0,0 +1,136 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cobalt/speech/chunked_byte_buffer.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+namespace {
+
+static const size_t kHeaderLength = sizeof(uint32_t);
+
+COMPILE_ASSERT(sizeof(size_t) >= kHeaderLength,
+ chunked_byte_buffer_not_supported_on_this_architecture);
+
+uint32_t ReadBigEndian32(const uint8_t* buffer) {
+ return (static_cast<uint32_t>(buffer[3])) |
+ (static_cast<uint32_t>(buffer[2]) << 8) |
+ (static_cast<uint32_t>(buffer[1]) << 16) |
+ (static_cast<uint32_t>(buffer[0]) << 24);
+}
+
+} // namespace
+
+namespace cobalt {
+namespace speech {
+
+ChunkedByteBuffer::ChunkedByteBuffer()
+ : partial_chunk_(new Chunk()),
+ total_bytes_stored_(0) {
+}
+
+ChunkedByteBuffer::~ChunkedByteBuffer() {
+ Clear();
+}
+
+void ChunkedByteBuffer::Append(const uint8_t* start, size_t length) {
+ size_t remaining_bytes = length;
+ const uint8_t* next_data = start;
+
+ while (remaining_bytes > 0) {
+ DCHECK(partial_chunk_ != NULL);
+ size_t insert_length = 0;
+ bool header_completed = false;
+ bool content_completed = false;
+ std::vector<uint8_t>* insert_target;
+
+ if (partial_chunk_->header.size() < kHeaderLength) {
+ const size_t bytes_to_complete_header =
+ kHeaderLength - partial_chunk_->header.size();
+ insert_length = std::min(bytes_to_complete_header, remaining_bytes);
+ insert_target = &partial_chunk_->header;
+ header_completed = (remaining_bytes >= bytes_to_complete_header);
+ } else {
+ DCHECK_LT(partial_chunk_->content->size(),
+ partial_chunk_->ExpectedContentLength());
+ const size_t bytes_to_complete_chunk =
+ partial_chunk_->ExpectedContentLength() -
+ partial_chunk_->content->size();
+ insert_length = std::min(bytes_to_complete_chunk, remaining_bytes);
+ insert_target = partial_chunk_->content.get();
+ content_completed = (remaining_bytes >= bytes_to_complete_chunk);
+ }
+
+ DCHECK_GT(insert_length, 0U);
+ DCHECK_LE(insert_length, remaining_bytes);
+ DCHECK_LE(next_data + insert_length, start + length);
+ insert_target->insert(insert_target->end(),
+ next_data,
+ next_data + insert_length);
+ next_data += insert_length;
+ remaining_bytes -= insert_length;
+
+ if (header_completed) {
+ DCHECK_EQ(partial_chunk_->header.size(), kHeaderLength);
+ if (partial_chunk_->ExpectedContentLength() == 0) {
+ // Handle zero-byte chunks.
+ chunks_.push_back(partial_chunk_.release());
+ partial_chunk_.reset(new Chunk());
+ } else {
+ partial_chunk_->content->reserve(
+ partial_chunk_->ExpectedContentLength());
+ }
+ } else if (content_completed) {
+ DCHECK_EQ(partial_chunk_->content->size(),
+ partial_chunk_->ExpectedContentLength());
+ chunks_.push_back(partial_chunk_.release());
+ partial_chunk_.reset(new Chunk());
+ }
+ }
+ DCHECK_EQ(next_data, start + length);
+ total_bytes_stored_ += length;
+}
+
+void ChunkedByteBuffer::Append(const std::string& string) {
+ Append(reinterpret_cast<const uint8_t*>(string.data()), string.size());
+}
+
+bool ChunkedByteBuffer::HasChunks() const {
+ return !chunks_.empty();
+}
+
+scoped_ptr<std::vector<uint8_t> > ChunkedByteBuffer::PopChunk() {
+ if (chunks_.empty())
+ return scoped_ptr<std::vector<uint8_t> >().Pass();
+ scoped_ptr<Chunk> chunk(*chunks_.begin());
+ chunks_.weak_erase(chunks_.begin());
+ DCHECK_EQ(chunk->header.size(), kHeaderLength);
+ DCHECK_EQ(chunk->content->size(), chunk->ExpectedContentLength());
+ total_bytes_stored_ -= chunk->content->size();
+ total_bytes_stored_ -= kHeaderLength;
+ return chunk->content.Pass();
+}
+
+void ChunkedByteBuffer::Clear() {
+ chunks_.clear();
+ partial_chunk_.reset(new Chunk());
+ total_bytes_stored_ = 0;
+}
+
+ChunkedByteBuffer::Chunk::Chunk() : content(new std::vector<uint8_t>()) {}
+
+ChunkedByteBuffer::Chunk::~Chunk() {
+}
+
+size_t ChunkedByteBuffer::Chunk::ExpectedContentLength() const {
+ DCHECK_EQ(header.size(), kHeaderLength);
+ return static_cast<size_t>(ReadBigEndian32(&header[0]));
+}
+
+} // namespace speech
+} // namespace cobalt
diff --git a/src/cobalt/speech/chunked_byte_buffer.h b/src/cobalt/speech/chunked_byte_buffer.h
new file mode 100644
index 0000000..f69dec9
--- /dev/null
+++ b/src/cobalt/speech/chunked_byte_buffer.h
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COBALT_SPEECH_CHUNKED_BYTE_BUFFER_H_
+#define COBALT_SPEECH_CHUNKED_BYTE_BUFFER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+
+namespace cobalt {
+namespace speech {
+
+// Models a chunk-oriented byte buffer. The term chunk is herein defined as an
+// arbitrary sequence of bytes that is preceeded by N header bytes, indicating
+// its size. Data may be appended to the buffer with no particular respect of
+// chunks boundaries. However, chunks can be extracted (FIFO) only when their
+// content (according to their header) is fully available in the buffer.
+// The current implementation support only 4 byte Big Endian headers.
+// Empty chunks (i.e. the sequence 00 00 00 00) are NOT allowed.
+//
+// E.g. 00 00 00 04 xx xx xx xx 00 00 00 02 yy yy 00 00 00 04 zz zz zz zz
+// [----- CHUNK 1 -------] [--- CHUNK 2 ---] [------ CHUNK 3 ------]
+class ChunkedByteBuffer {
+ public:
+ ChunkedByteBuffer();
+ ~ChunkedByteBuffer();
+
+ // Appends |length| bytes starting from |start| to the buffer.
+ void Append(const uint8_t* start, size_t length);
+
+ // Appends bytes contained in the |string| to the buffer.
+ void Append(const std::string& string);
+
+ // Checks whether one or more complete chunks are available in the buffer.
+ bool HasChunks() const;
+
+ // If enough data is available, reads and removes the first complete chunk
+ // from the buffer. Returns a NULL pointer if no complete chunk is available.
+ scoped_ptr<std::vector<uint8_t> > PopChunk();
+
+ // Clears all the content of the buffer.
+ void Clear();
+
+ // Returns the number of raw bytes (including headers) present.
+ size_t GetTotalLength() const { return total_bytes_stored_; }
+
+ private:
+ struct Chunk {
+ Chunk();
+ ~Chunk();
+
+ std::vector<uint8_t> header;
+ scoped_ptr<std::vector<uint8_t> > content;
+ size_t ExpectedContentLength() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Chunk);
+ };
+
+ ScopedVector<Chunk> chunks_;
+ scoped_ptr<Chunk> partial_chunk_;
+ size_t total_bytes_stored_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChunkedByteBuffer);
+};
+
+} // namespace speech
+} // namespace cobalt
+
+#endif // COBALT_SPEECH_CHUNKED_BYTE_BUFFER_H_
diff --git a/src/cobalt/speech/chunked_byte_buffer_unittest.cc b/src/cobalt/speech/chunked_byte_buffer_unittest.cc
new file mode 100644
index 0000000..0db0acd
--- /dev/null
+++ b/src/cobalt/speech/chunked_byte_buffer_unittest.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <vector>
+
+#include "cobalt/speech/chunked_byte_buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cobalt {
+namespace speech {
+
+typedef std::vector<uint8_t> ByteVector;
+
+TEST(ChunkedByteBufferTest, BasicTest) {
+ ChunkedByteBuffer buffer;
+
+ const uint8_t kChunks[] = {
+ 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, // Chunk 1: 4 bytes
+ 0x00, 0x00, 0x00, 0x02, 0x05, 0x06, // Chunk 2: 2 bytes
+ 0x00, 0x00, 0x00, 0x01, 0x07 // Chunk 3: 1 bytes
+ };
+
+ EXPECT_EQ(0U, buffer.GetTotalLength());
+ EXPECT_FALSE(buffer.HasChunks());
+
+ // Append partially chunk 1.
+ buffer.Append(kChunks, 2);
+ EXPECT_EQ(2U, buffer.GetTotalLength());
+ EXPECT_FALSE(buffer.HasChunks());
+
+ // Complete chunk 1.
+ buffer.Append(kChunks + 2, 6);
+ EXPECT_EQ(8U, buffer.GetTotalLength());
+ EXPECT_TRUE(buffer.HasChunks());
+
+ // Append fully chunk 2.
+ buffer.Append(kChunks + 8, 6);
+ EXPECT_EQ(14U, buffer.GetTotalLength());
+ EXPECT_TRUE(buffer.HasChunks());
+
+ // Remove and check chunk 1.
+ scoped_ptr<ByteVector> chunk;
+ chunk = buffer.PopChunk().Pass();
+ EXPECT_TRUE(chunk != NULL);
+ EXPECT_EQ(4U, chunk->size());
+ EXPECT_EQ(0, std::char_traits<uint8_t>::compare(kChunks + 4, &(*chunk)[0],
+ chunk->size()));
+ EXPECT_EQ(6U, buffer.GetTotalLength());
+ EXPECT_TRUE(buffer.HasChunks());
+
+ // Read and check chunk 2.
+ chunk = buffer.PopChunk().Pass();
+ EXPECT_TRUE(chunk != NULL);
+ EXPECT_EQ(2U, chunk->size());
+ EXPECT_EQ(0, std::char_traits<uint8_t>::compare(kChunks + 12, &(*chunk)[0],
+ chunk->size()));
+ EXPECT_EQ(0U, buffer.GetTotalLength());
+ EXPECT_FALSE(buffer.HasChunks());
+
+ // Append fully chunk 3.
+ buffer.Append(kChunks + 14, 5);
+ EXPECT_EQ(5U, buffer.GetTotalLength());
+
+ // Remove and check chunk 3.
+ chunk = buffer.PopChunk().Pass();
+ EXPECT_TRUE(chunk != NULL);
+ EXPECT_EQ(1U, chunk->size());
+ EXPECT_EQ((*chunk)[0], kChunks[18]);
+ EXPECT_EQ(0U, buffer.GetTotalLength());
+ EXPECT_FALSE(buffer.HasChunks());
+}
+
+} // namespace speech
+} // namespace cobalt
diff --git a/src/cobalt/speech/google_streaming_api.pb.cc b/src/cobalt/speech/google_streaming_api.pb.cc
new file mode 100644
index 0000000..1d33d80
--- /dev/null
+++ b/src/cobalt/speech/google_streaming_api.pb.cc
@@ -0,0 +1,757 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+
+#include <algorithm>
+
+#include "google_streaming_api.pb.h"
+
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+// @@protoc_insertion_point(includes)
+
+namespace cobalt {
+namespace speech {
+namespace proto {
+
+void protobuf_ShutdownFile_google_5fstreaming_5fapi_2eproto() {
+ delete SpeechRecognitionEvent::default_instance_;
+ delete SpeechRecognitionResult::default_instance_;
+ delete SpeechRecognitionAlternative::default_instance_;
+}
+
+void protobuf_AddDesc_google_5fstreaming_5fapi_2eproto() {
+ static bool already_here = false;
+ if (already_here) return;
+ already_here = true;
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ SpeechRecognitionEvent::default_instance_ = new SpeechRecognitionEvent();
+ SpeechRecognitionResult::default_instance_ = new SpeechRecognitionResult();
+ SpeechRecognitionAlternative::default_instance_ = new SpeechRecognitionAlternative();
+ SpeechRecognitionEvent::default_instance_->InitAsDefaultInstance();
+ SpeechRecognitionResult::default_instance_->InitAsDefaultInstance();
+ SpeechRecognitionAlternative::default_instance_->InitAsDefaultInstance();
+ ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_5fstreaming_5fapi_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_google_5fstreaming_5fapi_2eproto {
+ StaticDescriptorInitializer_google_5fstreaming_5fapi_2eproto() {
+ protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
+ }
+} static_descriptor_initializer_google_5fstreaming_5fapi_2eproto_;
+
+
+// ===================================================================
+
+bool SpeechRecognitionEvent_StatusCode_IsValid(int value) {
+ switch(value) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_SUCCESS;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_NO_SPEECH;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_ABORTED;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_AUDIO_CAPTURE;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_NETWORK;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_NOT_ALLOWED;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_SERVICE_NOT_ALLOWED;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_BAD_GRAMMAR;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_LANGUAGE_NOT_SUPPORTED;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::StatusCode_MIN;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::StatusCode_MAX;
+const int SpeechRecognitionEvent::StatusCode_ARRAYSIZE;
+#endif // _MSC_VER
+bool SpeechRecognitionEvent_EndpointerEventType_IsValid(int value) {
+ switch(value) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::START_OF_SPEECH;
+const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::END_OF_SPEECH;
+const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::END_OF_AUDIO;
+const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::END_OF_UTTERANCE;
+const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::EndpointerEventType_MIN;
+const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::EndpointerEventType_MAX;
+const int SpeechRecognitionEvent::EndpointerEventType_ARRAYSIZE;
+#endif // _MSC_VER
+#ifndef _MSC_VER
+const int SpeechRecognitionEvent::kStatusFieldNumber;
+const int SpeechRecognitionEvent::kResultFieldNumber;
+const int SpeechRecognitionEvent::kEndpointFieldNumber;
+#endif // !_MSC_VER
+
+SpeechRecognitionEvent::SpeechRecognitionEvent()
+ : ::google::protobuf::MessageLite() {
+ SharedCtor();
+}
+
+void SpeechRecognitionEvent::InitAsDefaultInstance() {
+}
+
+SpeechRecognitionEvent::SpeechRecognitionEvent(const SpeechRecognitionEvent& from)
+ : ::google::protobuf::MessageLite() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void SpeechRecognitionEvent::SharedCtor() {
+ _cached_size_ = 0;
+ status_ = 0;
+ endpoint_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SpeechRecognitionEvent::~SpeechRecognitionEvent() {
+ SharedDtor();
+}
+
+void SpeechRecognitionEvent::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void SpeechRecognitionEvent::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const SpeechRecognitionEvent& SpeechRecognitionEvent::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_5fstreaming_5fapi_2eproto(); return *default_instance_;
+}
+
+SpeechRecognitionEvent* SpeechRecognitionEvent::default_instance_ = NULL;
+
+SpeechRecognitionEvent* SpeechRecognitionEvent::New() const {
+ return new SpeechRecognitionEvent;
+}
+
+void SpeechRecognitionEvent::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ status_ = 0;
+ endpoint_ = 0;
+ }
+ result_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+bool SpeechRecognitionEvent::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode_IsValid(value)) {
+ set_status(static_cast< ::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode >(value));
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_result;
+ break;
+ }
+
+ // repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_result:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_result()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_result;
+ if (input->ExpectTag(32)) goto parse_endpoint;
+ break;
+ }
+
+ // optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
+ case 4: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_endpoint:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType_IsValid(value)) {
+ set_endpoint(static_cast< ::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType >(value));
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void SpeechRecognitionEvent::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
+ if (has_status()) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 1, this->status(), output);
+ }
+
+ // repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
+ for (int i = 0; i < this->result_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessage(
+ 2, this->result(i), output);
+ }
+
+ // optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
+ if (has_endpoint()) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 4, this->endpoint(), output);
+ }
+
+}
+
+int SpeechRecognitionEvent::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
+ if (has_status()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+ }
+
+ // optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
+ if (has_endpoint()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->endpoint());
+ }
+
+ }
+ // repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
+ total_size += 1 * this->result_size();
+ for (int i = 0; i < this->result_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->result(i));
+ }
+
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void SpeechRecognitionEvent::CheckTypeAndMergeFrom(
+ const ::google::protobuf::MessageLite& from) {
+ MergeFrom(*::google::protobuf::down_cast<const SpeechRecognitionEvent*>(&from));
+}
+
+void SpeechRecognitionEvent::MergeFrom(const SpeechRecognitionEvent& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ result_.MergeFrom(from.result_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_status()) {
+ set_status(from.status());
+ }
+ if (from.has_endpoint()) {
+ set_endpoint(from.endpoint());
+ }
+ }
+}
+
+void SpeechRecognitionEvent::CopyFrom(const SpeechRecognitionEvent& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SpeechRecognitionEvent::IsInitialized() const {
+
+ return true;
+}
+
+void SpeechRecognitionEvent::Swap(SpeechRecognitionEvent* other) {
+ if (other != this) {
+ std::swap(status_, other->status_);
+ result_.Swap(&other->result_);
+ std::swap(endpoint_, other->endpoint_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::std::string SpeechRecognitionEvent::GetTypeName() const {
+ return "cobalt.speech.proto.SpeechRecognitionEvent";
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int SpeechRecognitionResult::kAlternativeFieldNumber;
+const int SpeechRecognitionResult::kFinalFieldNumber;
+const int SpeechRecognitionResult::kStabilityFieldNumber;
+#endif // !_MSC_VER
+
+SpeechRecognitionResult::SpeechRecognitionResult()
+ : ::google::protobuf::MessageLite() {
+ SharedCtor();
+}
+
+void SpeechRecognitionResult::InitAsDefaultInstance() {
+}
+
+SpeechRecognitionResult::SpeechRecognitionResult(const SpeechRecognitionResult& from)
+ : ::google::protobuf::MessageLite() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void SpeechRecognitionResult::SharedCtor() {
+ _cached_size_ = 0;
+ final_ = false;
+ stability_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SpeechRecognitionResult::~SpeechRecognitionResult() {
+ SharedDtor();
+}
+
+void SpeechRecognitionResult::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void SpeechRecognitionResult::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const SpeechRecognitionResult& SpeechRecognitionResult::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_5fstreaming_5fapi_2eproto(); return *default_instance_;
+}
+
+SpeechRecognitionResult* SpeechRecognitionResult::default_instance_ = NULL;
+
+SpeechRecognitionResult* SpeechRecognitionResult::New() const {
+ return new SpeechRecognitionResult;
+}
+
+void SpeechRecognitionResult::Clear() {
+ if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ final_ = false;
+ stability_ = 0;
+ }
+ alternative_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+bool SpeechRecognitionResult::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_alternative:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_alternative()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(10)) goto parse_alternative;
+ if (input->ExpectTag(16)) goto parse_final;
+ break;
+ }
+
+ // optional bool final = 2 [default = false];
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_final:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &final_)));
+ set_has_final();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(29)) goto parse_stability;
+ break;
+ }
+
+ // optional float stability = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
+ parse_stability:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+ input, &stability_)));
+ set_has_stability();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void SpeechRecognitionResult::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
+ for (int i = 0; i < this->alternative_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessage(
+ 1, this->alternative(i), output);
+ }
+
+ // optional bool final = 2 [default = false];
+ if (has_final()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->final(), output);
+ }
+
+ // optional float stability = 3;
+ if (has_stability()) {
+ ::google::protobuf::internal::WireFormatLite::WriteFloat(3, this->stability(), output);
+ }
+
+}
+
+int SpeechRecognitionResult::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ // optional bool final = 2 [default = false];
+ if (has_final()) {
+ total_size += 1 + 1;
+ }
+
+ // optional float stability = 3;
+ if (has_stability()) {
+ total_size += 1 + 4;
+ }
+
+ }
+ // repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
+ total_size += 1 * this->alternative_size();
+ for (int i = 0; i < this->alternative_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->alternative(i));
+ }
+
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void SpeechRecognitionResult::CheckTypeAndMergeFrom(
+ const ::google::protobuf::MessageLite& from) {
+ MergeFrom(*::google::protobuf::down_cast<const SpeechRecognitionResult*>(&from));
+}
+
+void SpeechRecognitionResult::MergeFrom(const SpeechRecognitionResult& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ alternative_.MergeFrom(from.alternative_);
+ if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ if (from.has_final()) {
+ set_final(from.final());
+ }
+ if (from.has_stability()) {
+ set_stability(from.stability());
+ }
+ }
+}
+
+void SpeechRecognitionResult::CopyFrom(const SpeechRecognitionResult& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SpeechRecognitionResult::IsInitialized() const {
+
+ return true;
+}
+
+void SpeechRecognitionResult::Swap(SpeechRecognitionResult* other) {
+ if (other != this) {
+ alternative_.Swap(&other->alternative_);
+ std::swap(final_, other->final_);
+ std::swap(stability_, other->stability_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::std::string SpeechRecognitionResult::GetTypeName() const {
+ return "cobalt.speech.proto.SpeechRecognitionResult";
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int SpeechRecognitionAlternative::kTranscriptFieldNumber;
+const int SpeechRecognitionAlternative::kConfidenceFieldNumber;
+#endif // !_MSC_VER
+
+SpeechRecognitionAlternative::SpeechRecognitionAlternative()
+ : ::google::protobuf::MessageLite() {
+ SharedCtor();
+}
+
+void SpeechRecognitionAlternative::InitAsDefaultInstance() {
+}
+
+SpeechRecognitionAlternative::SpeechRecognitionAlternative(const SpeechRecognitionAlternative& from)
+ : ::google::protobuf::MessageLite() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void SpeechRecognitionAlternative::SharedCtor() {
+ _cached_size_ = 0;
+ transcript_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ confidence_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SpeechRecognitionAlternative::~SpeechRecognitionAlternative() {
+ SharedDtor();
+}
+
+void SpeechRecognitionAlternative::SharedDtor() {
+ if (transcript_ != &::google::protobuf::internal::kEmptyString) {
+ delete transcript_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void SpeechRecognitionAlternative::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const SpeechRecognitionAlternative& SpeechRecognitionAlternative::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_5fstreaming_5fapi_2eproto(); return *default_instance_;
+}
+
+SpeechRecognitionAlternative* SpeechRecognitionAlternative::default_instance_ = NULL;
+
+SpeechRecognitionAlternative* SpeechRecognitionAlternative::New() const {
+ return new SpeechRecognitionAlternative;
+}
+
+void SpeechRecognitionAlternative::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_transcript()) {
+ if (transcript_ != &::google::protobuf::internal::kEmptyString) {
+ transcript_->clear();
+ }
+ }
+ confidence_ = 0;
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+bool SpeechRecognitionAlternative::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string transcript = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_transcript()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(21)) goto parse_confidence;
+ break;
+ }
+
+ // optional float confidence = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) {
+ parse_confidence:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
+ input, &confidence_)));
+ set_has_confidence();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void SpeechRecognitionAlternative::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string transcript = 1;
+ if (has_transcript()) {
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->transcript(), output);
+ }
+
+ // optional float confidence = 2;
+ if (has_confidence()) {
+ ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->confidence(), output);
+ }
+
+}
+
+int SpeechRecognitionAlternative::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string transcript = 1;
+ if (has_transcript()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->transcript());
+ }
+
+ // optional float confidence = 2;
+ if (has_confidence()) {
+ total_size += 1 + 4;
+ }
+
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void SpeechRecognitionAlternative::CheckTypeAndMergeFrom(
+ const ::google::protobuf::MessageLite& from) {
+ MergeFrom(*::google::protobuf::down_cast<const SpeechRecognitionAlternative*>(&from));
+}
+
+void SpeechRecognitionAlternative::MergeFrom(const SpeechRecognitionAlternative& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_transcript()) {
+ set_transcript(from.transcript());
+ }
+ if (from.has_confidence()) {
+ set_confidence(from.confidence());
+ }
+ }
+}
+
+void SpeechRecognitionAlternative::CopyFrom(const SpeechRecognitionAlternative& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SpeechRecognitionAlternative::IsInitialized() const {
+
+ return true;
+}
+
+void SpeechRecognitionAlternative::Swap(SpeechRecognitionAlternative* other) {
+ if (other != this) {
+ std::swap(transcript_, other->transcript_);
+ std::swap(confidence_, other->confidence_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::std::string SpeechRecognitionAlternative::GetTypeName() const {
+ return "cobalt.speech.proto.SpeechRecognitionAlternative";
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace proto
+} // namespace speech
+} // namespace cobalt
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/cobalt/speech/google_streaming_api.pb.h b/src/cobalt/speech/google_streaming_api.pb.h
new file mode 100644
index 0000000..b666423
--- /dev/null
+++ b/src/cobalt/speech/google_streaming_api.pb.h
@@ -0,0 +1,613 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google_streaming_api.proto
+
+#ifndef PROTOBUF_google_5fstreaming_5fapi_2eproto__INCLUDED
+#define PROTOBUF_google_5fstreaming_5fapi_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 2004002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+// @@protoc_insertion_point(includes)
+
+namespace cobalt {
+namespace speech {
+namespace proto {
+
+// Internal implementation detail -- do not call these.
+void protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
+void protobuf_AssignDesc_google_5fstreaming_5fapi_2eproto();
+void protobuf_ShutdownFile_google_5fstreaming_5fapi_2eproto();
+
+class SpeechRecognitionEvent;
+class SpeechRecognitionResult;
+class SpeechRecognitionAlternative;
+
+enum SpeechRecognitionEvent_StatusCode {
+ SpeechRecognitionEvent_StatusCode_STATUS_SUCCESS = 0,
+ SpeechRecognitionEvent_StatusCode_STATUS_NO_SPEECH = 1,
+ SpeechRecognitionEvent_StatusCode_STATUS_ABORTED = 2,
+ SpeechRecognitionEvent_StatusCode_STATUS_AUDIO_CAPTURE = 3,
+ SpeechRecognitionEvent_StatusCode_STATUS_NETWORK = 4,
+ SpeechRecognitionEvent_StatusCode_STATUS_NOT_ALLOWED = 5,
+ SpeechRecognitionEvent_StatusCode_STATUS_SERVICE_NOT_ALLOWED = 6,
+ SpeechRecognitionEvent_StatusCode_STATUS_BAD_GRAMMAR = 7,
+ SpeechRecognitionEvent_StatusCode_STATUS_LANGUAGE_NOT_SUPPORTED = 8
+};
+bool SpeechRecognitionEvent_StatusCode_IsValid(int value);
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent_StatusCode_StatusCode_MIN = SpeechRecognitionEvent_StatusCode_STATUS_SUCCESS;
+const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent_StatusCode_StatusCode_MAX = SpeechRecognitionEvent_StatusCode_STATUS_LANGUAGE_NOT_SUPPORTED;
+const int SpeechRecognitionEvent_StatusCode_StatusCode_ARRAYSIZE = SpeechRecognitionEvent_StatusCode_StatusCode_MAX + 1;
+
+enum SpeechRecognitionEvent_EndpointerEventType {
+ SpeechRecognitionEvent_EndpointerEventType_START_OF_SPEECH = 0,
+ SpeechRecognitionEvent_EndpointerEventType_END_OF_SPEECH = 1,
+ SpeechRecognitionEvent_EndpointerEventType_END_OF_AUDIO = 2,
+ SpeechRecognitionEvent_EndpointerEventType_END_OF_UTTERANCE = 3
+};
+bool SpeechRecognitionEvent_EndpointerEventType_IsValid(int value);
+const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent_EndpointerEventType_EndpointerEventType_MIN = SpeechRecognitionEvent_EndpointerEventType_START_OF_SPEECH;
+const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent_EndpointerEventType_EndpointerEventType_MAX = SpeechRecognitionEvent_EndpointerEventType_END_OF_UTTERANCE;
+const int SpeechRecognitionEvent_EndpointerEventType_EndpointerEventType_ARRAYSIZE = SpeechRecognitionEvent_EndpointerEventType_EndpointerEventType_MAX + 1;
+
+// ===================================================================
+
+class SpeechRecognitionEvent : public ::google::protobuf::MessageLite {
+ public:
+ SpeechRecognitionEvent();
+ virtual ~SpeechRecognitionEvent();
+
+ SpeechRecognitionEvent(const SpeechRecognitionEvent& from);
+
+ inline SpeechRecognitionEvent& operator=(const SpeechRecognitionEvent& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ static const SpeechRecognitionEvent& default_instance();
+
+ void Swap(SpeechRecognitionEvent* other);
+
+ // implements Message ----------------------------------------------
+
+ SpeechRecognitionEvent* New() const;
+ void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
+ void CopyFrom(const SpeechRecognitionEvent& from);
+ void MergeFrom(const SpeechRecognitionEvent& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::std::string GetTypeName() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef SpeechRecognitionEvent_StatusCode StatusCode;
+ static const StatusCode STATUS_SUCCESS = SpeechRecognitionEvent_StatusCode_STATUS_SUCCESS;
+ static const StatusCode STATUS_NO_SPEECH = SpeechRecognitionEvent_StatusCode_STATUS_NO_SPEECH;
+ static const StatusCode STATUS_ABORTED = SpeechRecognitionEvent_StatusCode_STATUS_ABORTED;
+ static const StatusCode STATUS_AUDIO_CAPTURE = SpeechRecognitionEvent_StatusCode_STATUS_AUDIO_CAPTURE;
+ static const StatusCode STATUS_NETWORK = SpeechRecognitionEvent_StatusCode_STATUS_NETWORK;
+ static const StatusCode STATUS_NOT_ALLOWED = SpeechRecognitionEvent_StatusCode_STATUS_NOT_ALLOWED;
+ static const StatusCode STATUS_SERVICE_NOT_ALLOWED = SpeechRecognitionEvent_StatusCode_STATUS_SERVICE_NOT_ALLOWED;
+ static const StatusCode STATUS_BAD_GRAMMAR = SpeechRecognitionEvent_StatusCode_STATUS_BAD_GRAMMAR;
+ static const StatusCode STATUS_LANGUAGE_NOT_SUPPORTED = SpeechRecognitionEvent_StatusCode_STATUS_LANGUAGE_NOT_SUPPORTED;
+ static inline bool StatusCode_IsValid(int value) {
+ return SpeechRecognitionEvent_StatusCode_IsValid(value);
+ }
+ static const StatusCode StatusCode_MIN =
+ SpeechRecognitionEvent_StatusCode_StatusCode_MIN;
+ static const StatusCode StatusCode_MAX =
+ SpeechRecognitionEvent_StatusCode_StatusCode_MAX;
+ static const int StatusCode_ARRAYSIZE =
+ SpeechRecognitionEvent_StatusCode_StatusCode_ARRAYSIZE;
+
+ typedef SpeechRecognitionEvent_EndpointerEventType EndpointerEventType;
+ static const EndpointerEventType START_OF_SPEECH = SpeechRecognitionEvent_EndpointerEventType_START_OF_SPEECH;
+ static const EndpointerEventType END_OF_SPEECH = SpeechRecognitionEvent_EndpointerEventType_END_OF_SPEECH;
+ static const EndpointerEventType END_OF_AUDIO = SpeechRecognitionEvent_EndpointerEventType_END_OF_AUDIO;
+ static const EndpointerEventType END_OF_UTTERANCE = SpeechRecognitionEvent_EndpointerEventType_END_OF_UTTERANCE;
+ static inline bool EndpointerEventType_IsValid(int value) {
+ return SpeechRecognitionEvent_EndpointerEventType_IsValid(value);
+ }
+ static const EndpointerEventType EndpointerEventType_MIN =
+ SpeechRecognitionEvent_EndpointerEventType_EndpointerEventType_MIN;
+ static const EndpointerEventType EndpointerEventType_MAX =
+ SpeechRecognitionEvent_EndpointerEventType_EndpointerEventType_MAX;
+ static const int EndpointerEventType_ARRAYSIZE =
+ SpeechRecognitionEvent_EndpointerEventType_EndpointerEventType_ARRAYSIZE;
+
+ // accessors -------------------------------------------------------
+
+ // optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
+ inline bool has_status() const;
+ inline void clear_status();
+ static const int kStatusFieldNumber = 1;
+ inline ::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode status() const;
+ inline void set_status(::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode value);
+
+ // repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
+ inline int result_size() const;
+ inline void clear_result();
+ static const int kResultFieldNumber = 2;
+ inline const ::cobalt::speech::proto::SpeechRecognitionResult& result(int index) const;
+ inline ::cobalt::speech::proto::SpeechRecognitionResult* mutable_result(int index);
+ inline ::cobalt::speech::proto::SpeechRecognitionResult* add_result();
+ inline const ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionResult >&
+ result() const;
+ inline ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionResult >*
+ mutable_result();
+
+ // optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
+ inline bool has_endpoint() const;
+ inline void clear_endpoint();
+ static const int kEndpointFieldNumber = 4;
+ inline ::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType endpoint() const;
+ inline void set_endpoint(::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType value);
+
+ // @@protoc_insertion_point(class_scope:cobalt.speech.proto.SpeechRecognitionEvent)
+ private:
+ inline void set_has_status();
+ inline void clear_has_status();
+ inline void set_has_endpoint();
+ inline void clear_has_endpoint();
+
+ ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionResult > result_;
+ int status_;
+ int endpoint_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+
+ friend void protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
+ friend void protobuf_AssignDesc_google_5fstreaming_5fapi_2eproto();
+ friend void protobuf_ShutdownFile_google_5fstreaming_5fapi_2eproto();
+
+ void InitAsDefaultInstance();
+ static SpeechRecognitionEvent* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class SpeechRecognitionResult : public ::google::protobuf::MessageLite {
+ public:
+ SpeechRecognitionResult();
+ virtual ~SpeechRecognitionResult();
+
+ SpeechRecognitionResult(const SpeechRecognitionResult& from);
+
+ inline SpeechRecognitionResult& operator=(const SpeechRecognitionResult& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ static const SpeechRecognitionResult& default_instance();
+
+ void Swap(SpeechRecognitionResult* other);
+
+ // implements Message ----------------------------------------------
+
+ SpeechRecognitionResult* New() const;
+ void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
+ void CopyFrom(const SpeechRecognitionResult& from);
+ void MergeFrom(const SpeechRecognitionResult& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::std::string GetTypeName() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
+ inline int alternative_size() const;
+ inline void clear_alternative();
+ static const int kAlternativeFieldNumber = 1;
+ inline const ::cobalt::speech::proto::SpeechRecognitionAlternative& alternative(int index) const;
+ inline ::cobalt::speech::proto::SpeechRecognitionAlternative* mutable_alternative(int index);
+ inline ::cobalt::speech::proto::SpeechRecognitionAlternative* add_alternative();
+ inline const ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionAlternative >&
+ alternative() const;
+ inline ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionAlternative >*
+ mutable_alternative();
+
+ // optional bool final = 2 [default = false];
+ inline bool has_final() const;
+ inline void clear_final();
+ static const int kFinalFieldNumber = 2;
+ inline bool final() const;
+ inline void set_final(bool value);
+
+ // optional float stability = 3;
+ inline bool has_stability() const;
+ inline void clear_stability();
+ static const int kStabilityFieldNumber = 3;
+ inline float stability() const;
+ inline void set_stability(float value);
+
+ // @@protoc_insertion_point(class_scope:cobalt.speech.proto.SpeechRecognitionResult)
+ private:
+ inline void set_has_final();
+ inline void clear_has_final();
+ inline void set_has_stability();
+ inline void clear_has_stability();
+
+ ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionAlternative > alternative_;
+ bool final_;
+ float stability_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+
+ friend void protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
+ friend void protobuf_AssignDesc_google_5fstreaming_5fapi_2eproto();
+ friend void protobuf_ShutdownFile_google_5fstreaming_5fapi_2eproto();
+
+ void InitAsDefaultInstance();
+ static SpeechRecognitionResult* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class SpeechRecognitionAlternative : public ::google::protobuf::MessageLite {
+ public:
+ SpeechRecognitionAlternative();
+ virtual ~SpeechRecognitionAlternative();
+
+ SpeechRecognitionAlternative(const SpeechRecognitionAlternative& from);
+
+ inline SpeechRecognitionAlternative& operator=(const SpeechRecognitionAlternative& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ static const SpeechRecognitionAlternative& default_instance();
+
+ void Swap(SpeechRecognitionAlternative* other);
+
+ // implements Message ----------------------------------------------
+
+ SpeechRecognitionAlternative* New() const;
+ void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
+ void CopyFrom(const SpeechRecognitionAlternative& from);
+ void MergeFrom(const SpeechRecognitionAlternative& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::std::string GetTypeName() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string transcript = 1;
+ inline bool has_transcript() const;
+ inline void clear_transcript();
+ static const int kTranscriptFieldNumber = 1;
+ inline const ::std::string& transcript() const;
+ inline void set_transcript(const ::std::string& value);
+ inline void set_transcript(const char* value);
+ inline void set_transcript(const char* value, size_t size);
+ inline ::std::string* mutable_transcript();
+ inline ::std::string* release_transcript();
+
+ // optional float confidence = 2;
+ inline bool has_confidence() const;
+ inline void clear_confidence();
+ static const int kConfidenceFieldNumber = 2;
+ inline float confidence() const;
+ inline void set_confidence(float value);
+
+ // @@protoc_insertion_point(class_scope:cobalt.speech.proto.SpeechRecognitionAlternative)
+ private:
+ inline void set_has_transcript();
+ inline void clear_has_transcript();
+ inline void set_has_confidence();
+ inline void clear_has_confidence();
+
+ ::std::string* transcript_;
+ float confidence_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
+
+ friend void protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
+ friend void protobuf_AssignDesc_google_5fstreaming_5fapi_2eproto();
+ friend void protobuf_ShutdownFile_google_5fstreaming_5fapi_2eproto();
+
+ void InitAsDefaultInstance();
+ static SpeechRecognitionAlternative* default_instance_;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+// SpeechRecognitionEvent
+
+// optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
+inline bool SpeechRecognitionEvent::has_status() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void SpeechRecognitionEvent::set_has_status() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void SpeechRecognitionEvent::clear_has_status() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void SpeechRecognitionEvent::clear_status() {
+ status_ = 0;
+ clear_has_status();
+}
+inline ::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::status() const {
+ return static_cast< ::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode >(status_);
+}
+inline void SpeechRecognitionEvent::set_status(::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode value) {
+ GOOGLE_DCHECK(::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode_IsValid(value));
+ set_has_status();
+ status_ = value;
+}
+
+// repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
+inline int SpeechRecognitionEvent::result_size() const {
+ return result_.size();
+}
+inline void SpeechRecognitionEvent::clear_result() {
+ result_.Clear();
+}
+inline const ::cobalt::speech::proto::SpeechRecognitionResult& SpeechRecognitionEvent::result(int index) const {
+ return result_.Get(index);
+}
+inline ::cobalt::speech::proto::SpeechRecognitionResult* SpeechRecognitionEvent::mutable_result(int index) {
+ return result_.Mutable(index);
+}
+inline ::cobalt::speech::proto::SpeechRecognitionResult* SpeechRecognitionEvent::add_result() {
+ return result_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionResult >&
+SpeechRecognitionEvent::result() const {
+ return result_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionResult >*
+SpeechRecognitionEvent::mutable_result() {
+ return &result_;
+}
+
+// optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
+inline bool SpeechRecognitionEvent::has_endpoint() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void SpeechRecognitionEvent::set_has_endpoint() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void SpeechRecognitionEvent::clear_has_endpoint() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void SpeechRecognitionEvent::clear_endpoint() {
+ endpoint_ = 0;
+ clear_has_endpoint();
+}
+inline ::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::endpoint() const {
+ return static_cast< ::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType >(endpoint_);
+}
+inline void SpeechRecognitionEvent::set_endpoint(::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType value) {
+ GOOGLE_DCHECK(::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType_IsValid(value));
+ set_has_endpoint();
+ endpoint_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// SpeechRecognitionResult
+
+// repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
+inline int SpeechRecognitionResult::alternative_size() const {
+ return alternative_.size();
+}
+inline void SpeechRecognitionResult::clear_alternative() {
+ alternative_.Clear();
+}
+inline const ::cobalt::speech::proto::SpeechRecognitionAlternative& SpeechRecognitionResult::alternative(int index) const {
+ return alternative_.Get(index);
+}
+inline ::cobalt::speech::proto::SpeechRecognitionAlternative* SpeechRecognitionResult::mutable_alternative(int index) {
+ return alternative_.Mutable(index);
+}
+inline ::cobalt::speech::proto::SpeechRecognitionAlternative* SpeechRecognitionResult::add_alternative() {
+ return alternative_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionAlternative >&
+SpeechRecognitionResult::alternative() const {
+ return alternative_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionAlternative >*
+SpeechRecognitionResult::mutable_alternative() {
+ return &alternative_;
+}
+
+// optional bool final = 2 [default = false];
+inline bool SpeechRecognitionResult::has_final() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void SpeechRecognitionResult::set_has_final() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void SpeechRecognitionResult::clear_has_final() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void SpeechRecognitionResult::clear_final() {
+ final_ = false;
+ clear_has_final();
+}
+inline bool SpeechRecognitionResult::final() const {
+ return final_;
+}
+inline void SpeechRecognitionResult::set_final(bool value) {
+ set_has_final();
+ final_ = value;
+}
+
+// optional float stability = 3;
+inline bool SpeechRecognitionResult::has_stability() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void SpeechRecognitionResult::set_has_stability() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void SpeechRecognitionResult::clear_has_stability() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void SpeechRecognitionResult::clear_stability() {
+ stability_ = 0;
+ clear_has_stability();
+}
+inline float SpeechRecognitionResult::stability() const {
+ return stability_;
+}
+inline void SpeechRecognitionResult::set_stability(float value) {
+ set_has_stability();
+ stability_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// SpeechRecognitionAlternative
+
+// optional string transcript = 1;
+inline bool SpeechRecognitionAlternative::has_transcript() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void SpeechRecognitionAlternative::set_has_transcript() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void SpeechRecognitionAlternative::clear_has_transcript() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void SpeechRecognitionAlternative::clear_transcript() {
+ if (transcript_ != &::google::protobuf::internal::kEmptyString) {
+ transcript_->clear();
+ }
+ clear_has_transcript();
+}
+inline const ::std::string& SpeechRecognitionAlternative::transcript() const {
+ return *transcript_;
+}
+inline void SpeechRecognitionAlternative::set_transcript(const ::std::string& value) {
+ set_has_transcript();
+ if (transcript_ == &::google::protobuf::internal::kEmptyString) {
+ transcript_ = new ::std::string;
+ }
+ transcript_->assign(value);
+}
+inline void SpeechRecognitionAlternative::set_transcript(const char* value) {
+ set_has_transcript();
+ if (transcript_ == &::google::protobuf::internal::kEmptyString) {
+ transcript_ = new ::std::string;
+ }
+ transcript_->assign(value);
+}
+inline void SpeechRecognitionAlternative::set_transcript(const char* value, size_t size) {
+ set_has_transcript();
+ if (transcript_ == &::google::protobuf::internal::kEmptyString) {
+ transcript_ = new ::std::string;
+ }
+ transcript_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* SpeechRecognitionAlternative::mutable_transcript() {
+ set_has_transcript();
+ if (transcript_ == &::google::protobuf::internal::kEmptyString) {
+ transcript_ = new ::std::string;
+ }
+ return transcript_;
+}
+inline ::std::string* SpeechRecognitionAlternative::release_transcript() {
+ clear_has_transcript();
+ if (transcript_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = transcript_;
+ transcript_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional float confidence = 2;
+inline bool SpeechRecognitionAlternative::has_confidence() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void SpeechRecognitionAlternative::set_has_confidence() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void SpeechRecognitionAlternative::clear_has_confidence() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void SpeechRecognitionAlternative::clear_confidence() {
+ confidence_ = 0;
+ clear_has_confidence();
+}
+inline float SpeechRecognitionAlternative::confidence() const {
+ return confidence_;
+}
+inline void SpeechRecognitionAlternative::set_confidence(float value) {
+ set_has_confidence();
+ confidence_ = value;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace proto
+} // namespace speech
+} // namespace cobalt
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_google_5fstreaming_5fapi_2eproto__INCLUDED
diff --git a/src/cobalt/speech/google_streaming_api.proto b/src/cobalt/speech/google_streaming_api.proto
new file mode 100644
index 0000000..b9b5db8
--- /dev/null
+++ b/src/cobalt/speech/google_streaming_api.proto
@@ -0,0 +1,79 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Command to generate google_streaming_api.pb.h and google_streaming_api.pb.cc
+// protoc --proto_path=. --cpp_out=. google_streaming_api.proto
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+// TODO(hans): Commented out due to compilation errors.
+// option cc_api_version = 2;
+
+package cobalt.speech.proto;
+
+// SpeechRecognitionEvent is the only message type sent to client.
+//
+// The first SpeechRecognitionEvent is an empty (default) message to indicate
+// as early as possible that the stream connection has been established.
+message SpeechRecognitionEvent {
+ enum StatusCode {
+ // Note: in JavaScript API SpeechRecognitionError 0 is "OTHER" error.
+ STATUS_SUCCESS = 0;
+ STATUS_NO_SPEECH = 1;
+ STATUS_ABORTED = 2;
+ STATUS_AUDIO_CAPTURE = 3;
+ STATUS_NETWORK = 4;
+ STATUS_NOT_ALLOWED = 5;
+ STATUS_SERVICE_NOT_ALLOWED = 6;
+ STATUS_BAD_GRAMMAR = 7;
+ STATUS_LANGUAGE_NOT_SUPPORTED = 8;
+ }
+ optional StatusCode status = 1 [default = STATUS_SUCCESS];
+
+ // May contain zero or one final=true result (the newly settled portion).
+ // May also contain zero or more final=false results.
+ // (Note that this differs from JavaScript API resultHistory in that no more
+ // than one final=true result is returned, so client must accumulate
+ // resultHistory by concatenating the final=true results.)
+ repeated SpeechRecognitionResult result = 2;
+
+ enum EndpointerEventType {
+ START_OF_SPEECH = 0;
+ END_OF_SPEECH = 1;
+ END_OF_AUDIO = 2; // End of audio stream has been reached.
+ // End of utterance indicates that no more speech segments are expected.
+ END_OF_UTTERANCE = 3;
+ }
+
+ optional EndpointerEventType endpoint = 4;
+};
+
+message SpeechRecognitionResult {
+ repeated SpeechRecognitionAlternative alternative = 1;
+
+ // True if this is the final time the speech service will return this
+ // particular SpeechRecognitionResult. If false, then this represents an
+ // interim result that could still be changed.
+ optional bool final = 2 [default = false];
+
+ // An estimate of the probability that the recognizer will not change its
+ // guess about this interim result. Values range from 0.0 (completely
+ // unstable) to 1.0 (completely stable). Note that this is not the same as
+ // "confidence", which estimate the probability that a recognition result
+ // is correct. This field is only provided for interim (final=false) results.
+ optional float stability = 3;
+};
+
+// Item in N-best list.
+message SpeechRecognitionAlternative {
+ // Spoken text.
+ optional string transcript = 1;
+
+ // The confidence estimate between 0.0 and 1.0. A higher number means the
+ // system is more confident that the recognition is correct.
+ // This field is typically provided only for the top hypothesis and only for
+ // final results.
+ optional float confidence = 2;
+}
diff --git a/src/cobalt/speech/speech.gyp b/src/cobalt/speech/speech.gyp
index 5a43669..264a7e2 100644
--- a/src/cobalt/speech/speech.gyp
+++ b/src/cobalt/speech/speech.gyp
@@ -20,9 +20,19 @@
{
'target_name': 'speech',
'type': 'static_library',
+ 'msvs_disabled_warnings': [
+ # Dereferencing NULL pointer in generated file
+ # google_streaming_api.pb.cc.
+ 6011,
+ ],
'sources': [
'audio_encoder_flac.cc',
'audio_encoder_flac.h',
+ 'chunked_byte_buffer.cc',
+ 'chunked_byte_buffer.h',
+ 'google_streaming_api.pb.cc',
+ 'google_streaming_api.pb.h',
+ 'google_streaming_api.pb.proto',
'mic.h',
'speech_recognition.cc',
'speech_recognition.h',
@@ -47,6 +57,10 @@
'<(DEPTH)/cobalt/dom/dom.gyp:dom',
'<(DEPTH)/third_party/flac/flac.gyp:libflac',
],
+ 'include_dirs': [
+ # Get protobuf headers from the chromium tree.
+ '<(DEPTH)/third_party/protobuf/src',
+ ],
'conditions': [
['OS=="starboard"', {
'sources': [
@@ -60,5 +74,29 @@
}],
],
},
+ {
+ 'target_name': 'speech_test',
+ 'type': '<(gtest_target_type)',
+ 'sources': [
+ 'chunked_byte_buffer_unittest.cc',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/base/base.gyp:run_all_unittests',
+ '<(DEPTH)/cobalt/speech/speech.gyp:speech',
+ '<(DEPTH)/testing/gtest.gyp:gtest',
+ ],
+ },
+
+ {
+ 'target_name': 'speech_test_deploy',
+ 'type': 'none',
+ 'dependencies': [
+ 'speech_test',
+ ],
+ 'variables': {
+ 'executable_name': 'speech_test',
+ },
+ 'includes': [ '../../starboard/build/deploy.gypi' ],
+ },
],
}
diff --git a/src/cobalt/webdriver/is_displayed_test.cc b/src/cobalt/webdriver/is_displayed_test.cc
index 37d366a..9a99abe 100644
--- a/src/cobalt/webdriver/is_displayed_test.cc
+++ b/src/cobalt/webdriver/is_displayed_test.cc
@@ -29,6 +29,7 @@
#include "cobalt/dom/html_collection.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom_parser/parser.h"
+#include "cobalt/loader/fetcher_factory.h"
#include "cobalt/loader/image/image_cache.h"
#include "cobalt/loader/loader.h"
#include "cobalt/render_tree/resource_provider_stub.h"
@@ -52,15 +53,18 @@
css_parser_(css_parser::Parser::Create()),
dom_parser_(new dom_parser::Parser()),
resource_provider_stub_(new render_tree::ResourceProviderStub()),
- image_cache_(loader::image::CreateImageCache(
- "WebdriverTest.ImageCache", kImageCacheCapacity,
- resource_provider_stub_.get(), &fetcher_factory_)),
+ loader_factory_(new loader::LoaderFactory(
+ &fetcher_factory_, resource_provider_stub_.get())),
+ image_cache_(loader::image::CreateImageCache("WebdriverTest.ImageCache",
+ kImageCacheCapacity,
+ loader_factory_.get())),
dom_stat_tracker_(new dom::DomStatTracker("IsDisplayedTest")),
+ resource_provider_(resource_provider_stub_.get()),
html_element_context_(
&fetcher_factory_, css_parser_.get(), dom_parser_.get(),
NULL /* can_play_type_handler */,
NULL /* web_media_player_factory */, &script_runner_,
- NULL /* media_source_registry */, resource_provider_stub_.get(),
+ NULL /* media_source_registry */, &resource_provider_,
image_cache_.get(), NULL /* reduced_image_cache_capacity_manager */,
NULL /* remote_font_cache */, dom_stat_tracker_.get(),
"" /* language */) {}
@@ -93,8 +97,10 @@
scoped_ptr<css_parser::Parser> css_parser_;
scoped_ptr<dom_parser::Parser> dom_parser_;
scoped_ptr<render_tree::ResourceProviderStub> resource_provider_stub_;
+ scoped_ptr<loader::LoaderFactory> loader_factory_;
scoped_ptr<loader::image::ImageCache> image_cache_;
scoped_ptr<dom::DomStatTracker> dom_stat_tracker_;
+ render_tree::ResourceProvider* resource_provider_;
dom::HTMLElementContext html_element_context_;
scoped_refptr<dom::Document> document_;
scoped_ptr<loader::Loader> document_loader_;
diff --git a/src/glimp/gles/buffer.cc b/src/glimp/gles/buffer.cc
index c0975cd..5e03c06 100644
--- a/src/glimp/gles/buffer.cc
+++ b/src/glimp/gles/buffer.cc
@@ -38,12 +38,7 @@
} // namespace
Buffer::Buffer(nb::scoped_ptr<BufferImpl> impl)
- : impl_(impl.Pass()), target_valid_(false), size_in_bytes_(0) {}
-
-void Buffer::SetTarget(GLenum target) {
- target_ = target;
- target_valid_ = true;
-}
+ : impl_(impl.Pass()), size_in_bytes_(0) {}
void Buffer::Allocate(GLenum usage, size_t size) {
size_in_bytes_ = size;
@@ -51,7 +46,6 @@
}
void Buffer::SetData(GLintptr offset, GLsizeiptr size, const GLvoid* data) {
- SB_DCHECK(target_valid());
SB_DCHECK(size_in_bytes_ >= offset + size);
SB_DCHECK(offset >= 0);
SB_DCHECK(size >= 0);
diff --git a/src/glimp/gles/buffer.h b/src/glimp/gles/buffer.h
index 71b18ce..85cb462 100644
--- a/src/glimp/gles/buffer.h
+++ b/src/glimp/gles/buffer.h
@@ -30,9 +30,6 @@
public:
explicit Buffer(nb::scoped_ptr<BufferImpl> impl);
- // Called when glBindBuffer() is called.
- void SetTarget(GLenum target);
-
// Allocates memory within this Buffer object.
void Allocate(GLenum usage, size_t size);
@@ -47,16 +44,6 @@
// Returns true if the buffer is currently mapped to the CPU address space.
bool is_mapped() const { return is_mapped_; }
- // Returns true if the target has been set (e.g. via glBindBuffer()).
- bool target_valid() const { return target_valid_; }
-
- // Returns the target (set via glBindBuffer()). Must be called only if
- // target_valid() is true.
- GLenum target() const {
- SB_DCHECK(target_valid_);
- return target_;
- }
-
GLsizeiptr size_in_bytes() const { return size_in_bytes_; }
BufferImpl* impl() const { return impl_.get(); }
@@ -67,13 +54,6 @@
nb::scoped_ptr<BufferImpl> impl_;
- // The target type this buffer was last bound as, set through a call to
- // glBindBuffer().
- GLenum target_;
-
- // Represents whether or not target_ as been initialized yet.
- bool target_valid_;
-
// The size of the allocated memory used by this buffer.
GLsizeiptr size_in_bytes_;
diff --git a/src/glimp/gles/context.cc b/src/glimp/gles/context.cc
index 608344f..65b7f47 100644
--- a/src/glimp/gles/context.cc
+++ b/src/glimp/gles/context.cc
@@ -694,10 +694,18 @@
buffer_object->Unmap();
}
- // If a bound buffer is deleted, set the bound buffer to NULL.
- if (buffer_object->target_valid()) {
- *GetBoundBufferForTarget(buffer_object->target()) =
- nb::scoped_refptr<Buffer>();
+ // If a bound buffer is deleted, set the bound buffer to NULL. The buffer
+ // may be bound to any target, therefore we must scan them all.
+ const GLenum buffer_targets[3] = {GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
+ GL_PIXEL_UNPACK_BUFFER};
+ for (int target_index = 0; target_index < SB_ARRAY_SIZE(buffer_targets);
+ ++target_index) {
+ GLenum target = buffer_targets[target_index];
+ nb::scoped_refptr<Buffer>* bound_buffer = GetBoundBufferForTarget(target);
+ SB_DCHECK(bound_buffer);
+ if ((*bound_buffer).get() == buffer_object.get()) {
+ *bound_buffer = NULL;
+ }
}
}
}
@@ -730,25 +738,20 @@
return;
}
- if (buffer == 0) {
- // Unbind the current buffer if 0 is passed in for buffer.
- *GetBoundBufferForTarget(target) = NULL;
- return;
+ nb::scoped_refptr<Buffer>* bound_buffer = GetBoundBufferForTarget(target);
+ SB_DCHECK(bound_buffer);
+ nb::scoped_refptr<Buffer> buffer_object;
+ if (buffer != 0) {
+ buffer_object = resource_manager_->GetBuffer(buffer);
+ if (!buffer_object) {
+ // The buffer to be bound is invalid.
+ SB_NOTIMPLEMENTED()
+ << "Creating buffers with glBindBuffer () not supported";
+ return;
+ }
}
- nb::scoped_refptr<Buffer> buffer_object =
- resource_manager_->GetBuffer(buffer);
-
- if (!buffer_object) {
- // According to the specification, no error is generated if the buffer is
- // invalid.
- // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindBuffer.xml
- SB_DLOG(WARNING) << "Could not glBindBuffer() to invalid buffer.";
- return;
- }
-
- buffer_object->SetTarget(target);
- *GetBoundBufferForTarget(target) = buffer_object;
+ *bound_buffer = buffer_object;
}
void Context::BufferData(GLenum target,
@@ -994,11 +997,12 @@
return NULL;
}
-nb::scoped_refptr<Texture>* Context::GetBoundTextureForTarget(GLenum target) {
+nb::scoped_refptr<Texture>* Context::GetBoundTextureForTarget(GLenum target,
+ GLenum texture) {
GLIMP_TRACE_EVENT0(__FUNCTION__);
switch (target) {
case GL_TEXTURE_2D:
- return &(texture_units_[active_texture_ - GL_TEXTURE0]);
+ return &(texture_units_[texture - GL_TEXTURE0]);
case GL_TEXTURE_CUBE_MAP:
SB_NOTREACHED() << "Currently unimplemented in glimp.";
return NULL;
@@ -1058,7 +1062,6 @@
// Silently ignore 0 textures.
continue;
}
-
nb::scoped_refptr<Texture> texture_object =
resource_manager_->DeregisterTexture(textures[i]);
@@ -1069,10 +1072,18 @@
return;
}
- // If a bound texture is deleted, set the bound texture to NULL.
- if (texture_object->target_valid()) {
- *GetBoundTextureForTarget(texture_object->target()) = NULL;
- enabled_textures_dirty_ = true;
+ // If a bound texture is deleted, set the bound texture to NULL. The texture
+ // may be bound to multiple texture units, including texture units that are
+ // not active, therefore we must scan them all.
+ for (int texture_index = 0;
+ texture_index < impl_->GetMaxFragmentTextureUnits(); ++texture_index) {
+ GLenum texture_unit = texture_index + GL_TEXTURE0;
+ nb::scoped_refptr<Texture>* bound_texture =
+ GetBoundTextureForTarget(GL_TEXTURE_2D, texture_unit);
+ if ((*bound_texture).get() == texture_object.get()) {
+ enabled_textures_dirty_ = true;
+ *bound_texture = NULL;
+ }
}
}
}
@@ -1095,25 +1106,26 @@
return;
}
- if (texture == 0) {
- // Unbind the current texture if 0 is passed in for texture.
- *GetBoundTextureForTarget(target) = NULL;
- enabled_textures_dirty_ = true;
- return;
+ nb::scoped_refptr<Texture>* bound_texture =
+ GetBoundTextureForTarget(target, active_texture_);
+ SB_DCHECK(bound_texture);
+ nb::scoped_refptr<Texture> texture_object;
+ if (texture != 0) {
+ texture_object = resource_manager_->GetTexture(texture);
+ if (!texture_object) {
+ // The texture to be bound is invalid.
+ SB_NOTIMPLEMENTED()
+ << "Creating textures with glBindTexture() not supported";
+ return;
+ }
}
- nb::scoped_refptr<Texture> texture_object =
- resource_manager_->GetTexture(texture);
-
- if (!texture_object) {
- // According to the specification, no error is generated if the texture is
- // invalid.
- // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glBindTexture.xml
+ if ((*bound_texture).get() == texture_object.get()) {
+ // The new texture being bound is the same as the already the bound
+ // texture.
return;
}
-
- texture_object->SetTarget(target);
- *GetBoundTextureForTarget(target) = texture_object;
+ *bound_texture = texture_object;
enabled_textures_dirty_ = true;
}
@@ -1164,8 +1176,8 @@
void Context::TexParameteri(GLenum target, GLenum pname, GLint param) {
GLIMP_TRACE_EVENT0(__FUNCTION__);
- Sampler* active_sampler =
- (*GetBoundTextureForTarget(target))->sampler_parameters();
+ Sampler* active_sampler = (*GetBoundTextureForTarget(target, active_texture_))
+ ->sampler_parameters();
switch (pname) {
case GL_TEXTURE_MAG_FILTER: {
@@ -1297,7 +1309,8 @@
SB_DCHECK(pixel_format != kPixelFormatInvalid)
<< "Pixel format not supported by glimp.";
- nb::scoped_refptr<Texture> texture_object = *GetBoundTextureForTarget(target);
+ nb::scoped_refptr<Texture> texture_object =
+ *GetBoundTextureForTarget(target, active_texture_);
if (!texture_object) {
// According to the specification, no error is generated if no texture
// is bound.
@@ -1365,7 +1378,8 @@
SB_DCHECK(pixel_format != kPixelFormatInvalid)
<< "Pixel format not supported by glimp.";
- nb::scoped_refptr<Texture> texture_object = *GetBoundTextureForTarget(target);
+ nb::scoped_refptr<Texture> texture_object =
+ *GetBoundTextureForTarget(target, active_texture_);
if (!texture_object) {
// According to the specification, no error is generated if no texture
// is bound.
@@ -2131,7 +2145,7 @@
SB_DCHECK(surface->GetTextureTarget() == EGL_TEXTURE_2D);
const nb::scoped_refptr<Texture>& current_texture =
- *GetBoundTextureForTarget(GL_TEXTURE_2D);
+ *GetBoundTextureForTarget(GL_TEXTURE_2D, active_texture_);
if (!current_texture) {
SB_DLOG(WARNING) << "No texture is currently bound during call to "
diff --git a/src/glimp/gles/context.h b/src/glimp/gles/context.h
index 7d2d919..018a2f2 100644
--- a/src/glimp/gles/context.h
+++ b/src/glimp/gles/context.h
@@ -234,15 +234,16 @@
void ReleaseContext();
void SetError(GLenum error) { error_ = error; }
- // Returns the bound buffer slot for the specific specified target.
+ // Returns the bound buffer for the specific specified target.
// This returns a pointer because it is used by glBindBuffer() which modifies
// what the returned scoped_refptr points to.
nb::scoped_refptr<Buffer>* GetBoundBufferForTarget(GLenum target);
- // Returns the bound texture slot for the specific specified target.
+ // Returns the bound texture for the specific specified target and slot.
// This returns a pointer because it is used by glBindTexture() which modifies
// what the returned scoped_refptr points to.
- nb::scoped_refptr<Texture>* GetBoundTextureForTarget(GLenum target);
+ nb::scoped_refptr<Texture>* GetBoundTextureForTarget(GLenum target,
+ GLenum texture);
void SetupExtensionsString();
diff --git a/src/glimp/gles/texture.cc b/src/glimp/gles/texture.cc
index a057f74..0e1ea8c 100644
--- a/src/glimp/gles/texture.cc
+++ b/src/glimp/gles/texture.cc
@@ -24,15 +24,9 @@
Texture::Texture(nb::scoped_ptr<TextureImpl> impl)
: impl_(impl.Pass()),
- target_valid_(false),
texture_allocated_(false),
bound_to_surface_(NULL) {}
-void Texture::SetTarget(GLenum target) {
- target_ = target;
- target_valid_ = true;
-}
-
void Texture::Initialize(GLint level,
PixelFormat pixel_format,
GLsizei width,
diff --git a/src/glimp/gles/texture.h b/src/glimp/gles/texture.h
index 1d4bcc5..9c530b4 100644
--- a/src/glimp/gles/texture.h
+++ b/src/glimp/gles/texture.h
@@ -34,9 +34,6 @@
public:
explicit Texture(nb::scoped_ptr<TextureImpl> impl);
- // Called when glBindTexture() is called.
- void SetTarget(GLenum target);
-
void Initialize(GLint level,
PixelFormat pixel_format,
GLsizei width,
@@ -82,16 +79,6 @@
// or not.
bool CanBeAttachedToFramebuffer() const;
- // Returns true if the target has been set (e.g. via glBindTexture()).
- bool target_valid() const { return target_valid_; }
-
- // Returns the target (set via glBindTexture()). Must be called only if
- // target_valid() is true.
- GLenum target() const {
- SB_DCHECK(target_valid_);
- return target_;
- }
-
TextureImpl* impl() const { return impl_.get(); }
// Returns whether the data has been set yet or not.
@@ -121,13 +108,6 @@
nb::scoped_ptr<TextureImpl> impl_;
- // The target type this texture was last bound as, set through a call to
- // glBindTexture().
- GLenum target_;
-
- // Represents whether or not target_ as been initialized yet.
- bool target_valid_;
-
// True if underlying texture data has been allocated yet or not (e.g.
// will be true after glTexImage2D() is called.)
bool texture_allocated_;
diff --git a/src/media/base/sbplayer_pipeline.cc b/src/media/base/sbplayer_pipeline.cc
index 9c09927..7c0f067 100644
--- a/src/media/base/sbplayer_pipeline.cc
+++ b/src/media/base/sbplayer_pipeline.cc
@@ -48,6 +48,36 @@
namespace {
+SbMediaAudioCodec SbMediaAudioCodecFromMediaAudioCodec(AudioCodec codec) {
+ if (codec == kCodecAAC) {
+ return kSbMediaAudioCodecAac;
+ } else if (codec == kCodecVorbis) {
+ return kSbMediaAudioCodecVorbis;
+ } else if (codec == kCodecOpus) {
+ return kSbMediaAudioCodecOpus;
+ }
+ DLOG(ERROR) << "Unsupported audio codec " << codec;
+ return kSbMediaAudioCodecNone;
+}
+
+SbMediaVideoCodec SbMediaVideoCodecFromMediaVideoCodec(VideoCodec codec) {
+ if (codec == kCodecH264) {
+ return kSbMediaVideoCodecH264;
+ } else if (codec == kCodecVC1) {
+ return kSbMediaVideoCodecVc1;
+ } else if (codec == kCodecMPEG2) {
+ return kSbMediaVideoCodecMpeg2;
+ } else if (codec == kCodecTheora) {
+ return kSbMediaVideoCodecTheora;
+ } else if (codec == kCodecVP8) {
+ return kSbMediaVideoCodecVp8;
+ } else if (codec == kCodecVP9) {
+ return kSbMediaVideoCodecVp9;
+ }
+ DLOG(ERROR) << "Unsupported video codec " << codec;
+ return kSbMediaVideoCodecNone;
+}
+
TimeDelta SbMediaTimeToTimeDelta(SbMediaTime timestamp) {
return TimeDelta::FromMicroseconds(timestamp * Time::kMicrosecondsPerSecond /
kSbMediaTimeSecond);
@@ -68,7 +98,11 @@
}
void FillDrmSampleInfo(const scoped_refptr<DecoderBuffer>& buffer,
- SbDrmSampleInfo* drm_info) {
+ SbDrmSampleInfo* drm_info,
+ SbDrmSubSampleMapping* subsample_mapping) {
+ DCHECK(drm_info);
+ DCHECK(subsample_mapping);
+
const DecryptConfig* config = buffer->GetDecryptConfig();
if (!config || config->iv().empty() || config->key_id().empty()) {
drm_info->initialization_vector_size = 0;
@@ -104,10 +138,9 @@
reinterpret_cast<const SbDrmSubSampleMapping*>(
&config->subsamples()[0]);
} else {
- // TODO: According to the SbDrm interface we have to provide a subsample
- // with exactly one element covering the whole sample. This needs
- // extra memory management.
- drm_info->subsample_mapping = NULL;
+ drm_info->subsample_mapping = subsample_mapping;
+ subsample_mapping->clear_byte_count = 0;
+ subsample_mapping->encrypted_byte_count = buffer->GetDataSize();
}
}
@@ -633,17 +666,36 @@
audio_header.bits_per_sample = audio_config.bits_per_channel();
audio_header.audio_specific_config_size = 0;
+ const VideoDecoderConfig& video_config =
+ demuxer_->GetStream(DemuxerStream::VIDEO)->video_decoder_config();
+
+ SbMediaAudioCodec audio_codec =
+ SbMediaAudioCodecFromMediaAudioCodec(audio_config.codec());
+ SbMediaVideoCodec video_codec =
+ SbMediaVideoCodecFromMediaVideoCodec(video_config.codec());
+
{
base::AutoLock auto_lock(lock_);
- player_ = SbPlayerCreate(window_, kSbMediaVideoCodecH264,
- kSbMediaAudioCodecAac, SB_PLAYER_NO_DURATION,
- drm_system, &audio_header, DeallocateSampleCB,
- DecoderStatusCB, PlayerStatusCB, this);
+ player_ =
+ SbPlayerCreate(window_, video_codec, audio_codec, SB_PLAYER_NO_DURATION,
+ drm_system, &audio_header, DeallocateSampleCB,
+ DecoderStatusCB, PlayerStatusCB, this);
SetPlaybackRateTask(playback_rate_);
SetVolumeTask(volume_);
}
- set_bounds_caller_->SetPlayer(player_);
+ if (SbPlayerIsValid(player_)) {
+ set_bounds_caller_->SetPlayer(player_);
+ return;
+ }
+
+ PipelineStatusCB seek_cb;
+ {
+ base::AutoLock auto_lock(lock_);
+ DCHECK(!seek_cb_.is_null());
+ seek_cb = base::ResetAndReturn(&seek_cb_);
+ }
+ seek_cb.Run(DECODER_ERROR_NOT_SUPPORTED);
}
void SbPlayerPipeline::SetDecryptor(Decryptor* decryptor) {
@@ -675,8 +727,6 @@
buffering_state_cb_.Run(kHaveMetadata);
- NOTIMPLEMENTED() << "Dynamically determinate codecs";
-
const AudioDecoderConfig& audio_config =
demuxer_->GetStream(DemuxerStream::AUDIO)->audio_decoder_config();
bool is_encrypted = audio_config.is_encrypted();
@@ -780,9 +830,10 @@
bool is_encrypted = IsEncrypted(stream);
SbDrmSampleInfo drm_info;
+ SbDrmSubSampleMapping subsample_mapping;
if (is_encrypted && !buffer->IsEndOfStream()) {
- FillDrmSampleInfo(buffer, &drm_info);
+ FillDrmSampleInfo(buffer, &drm_info, &subsample_mapping);
}
if (type == DemuxerStream::AUDIO) {
@@ -842,6 +893,7 @@
case kSbPlayerDecoderStateNeedsData:
break;
case kSbPlayerDecoderStateBufferFull:
+ DLOG(WARNING) << "kSbPlayerDecoderStateBufferFull has been deprecated.";
return;
case kSbPlayerDecoderStateDestroyed:
return;
diff --git a/src/net/socket/tcp_client_socket_starboard.cc b/src/net/socket/tcp_client_socket_starboard.cc
index 0a915a5..48d76b5 100644
--- a/src/net/socket/tcp_client_socket_starboard.cc
+++ b/src/net/socket/tcp_client_socket_starboard.cc
@@ -48,8 +48,10 @@
SbSocketSetTcpNoDelay(socket, true);
SbSocketSetTcpKeepAlive(socket, true, kTCPKeepAliveDuration);
SbSocketSetTcpWindowScaling(socket, true);
- SbSocketSetReceiveBufferSize(socket,
- TCPClientSocketStarboard::kReceiveBufferSize);
+ if (TCPClientSocketStarboard::kReceiveBufferSize != 0) {
+ SbSocketSetReceiveBufferSize(socket,
+ TCPClientSocketStarboard::kReceiveBufferSize);
+ }
return 0;
}
diff --git a/src/starboard/common/common.gyp b/src/starboard/common/common.gyp
new file mode 100644
index 0000000..b0bc5df
--- /dev/null
+++ b/src/starboard/common/common.gyp
@@ -0,0 +1,30 @@
+# Copyright 2016 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# The "common" target contains facilities provided by Starboard that are common
+# to all platforms.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'common',
+ 'type': 'none',
+ 'sources': [
+ 'move.h',
+ 'reset_and_return.h',
+ 'scoped_ptr.h',
+ ],
+ },
+ ],
+}
diff --git a/src/starboard/common/move.h b/src/starboard/common/move.h
new file mode 100644
index 0000000..aacd8e6
--- /dev/null
+++ b/src/starboard/common/move.h
@@ -0,0 +1,209 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef STARBOARD_COMMON_MOVE_H_
+#define STARBOARD_COMMON_MOVE_H_
+
+// Macro with the boilerplate that makes a type move-only in C++03.
+//
+// USAGE
+//
+// This macro should be used instead of DISALLOW_COPY_AND_ASSIGN to create
+// a "move-only" type. Unlike DISALLOW_COPY_AND_ASSIGN, this macro should be
+// the first line in a class declaration.
+//
+// A class using this macro must call .Pass() (or somehow be an r-value already)
+// before it can be:
+//
+// * Passed as a function argument
+// * Used as the right-hand side of an assignment
+// * Returned from a function
+//
+// Each class will still need to define their own "move constructor" and "move
+// operator=" to make this useful. Here's an example of the macro, the move
+// constructor, and the move operator= from the scoped_ptr class:
+//
+// template <typename T>
+// class scoped_ptr {
+// MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
+// public:
+// scoped_ptr(RValue& other) : ptr_(other.release()) { }
+// scoped_ptr& operator=(RValue& other) {
+// swap(other);
+// return *this;
+// }
+// };
+//
+// Note that the constructor must NOT be marked explicit.
+//
+// For consistency, the second parameter to the macro should always be RValue
+// unless you have a strong reason to do otherwise. It is only exposed as a
+// macro parameter so that the move constructor and move operator= don't look
+// like they're using a phantom type.
+//
+//
+// HOW THIS WORKS
+//
+// For a thorough explanation of this technique, see:
+//
+// http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Move_Constructor
+//
+// The summary is that we take advantage of 2 properties:
+//
+// 1) non-const references will not bind to r-values.
+// 2) C++ can apply one user-defined conversion when initializing a
+// variable.
+//
+// The first lets us disable the copy constructor and assignment operator
+// by declaring private version of them with a non-const reference parameter.
+//
+// For l-values, direct initialization still fails like in
+// DISALLOW_COPY_AND_ASSIGN because the copy constructor and assignment
+// operators are private.
+//
+// For r-values, the situation is different. The copy constructor and
+// assignment operator are not viable due to (1), so we are trying to call
+// a non-existent constructor and non-existing operator= rather than a private
+// one. Since we have not committed an error quite yet, we can provide an
+// alternate conversion sequence and a constructor. We add
+//
+// * a private struct named "RValue"
+// * a user-defined conversion "operator RValue()"
+// * a "move constructor" and "move operator=" that take the RValue& as
+// their sole parameter.
+//
+// Only r-values will trigger this sequence and execute our "move constructor"
+// or "move operator=." L-values will match the private copy constructor and
+// operator= first giving a "private in this context" error. This combination
+// gives us a move-only type.
+//
+// For signaling a destructive transfer of data from an l-value, we provide a
+// method named Pass() which creates an r-value for the current instance
+// triggering the move constructor or move operator=.
+//
+// Other ways to get r-values is to use the result of an expression like a
+// function call.
+//
+// Here's an example with comments explaining what gets triggered where:
+//
+// class Foo {
+// MOVE_ONLY_TYPE_FOR_CPP_03(Foo, RValue);
+//
+// public:
+// ... API ...
+// Foo(RValue other); // Move constructor.
+// Foo& operator=(RValue rhs); // Move operator=
+// };
+//
+// Foo MakeFoo(); // Function that returns a Foo.
+//
+// Foo f;
+// Foo f_copy(f); // ERROR: Foo(Foo&) is private in this context.
+// Foo f_assign;
+// f_assign = f; // ERROR: operator=(Foo&) is private in this context.
+//
+//
+// Foo f(MakeFoo()); // R-value so alternate conversion executed.
+// Foo f_copy(f.Pass()); // R-value so alternate conversion executed.
+// f = f_copy.Pass(); // R-value so alternate conversion executed.
+//
+//
+// IMPLEMENTATION SUBTLETIES WITH RValue
+//
+// The RValue struct is just a container for a pointer back to the original
+// object. It should only ever be created as a temporary, and no external
+// class should ever declare it or use it in a parameter.
+//
+// It is tempting to want to use the RValue type in function parameters, but
+// excluding the limited usage here for the move constructor and move
+// operator=, doing so would mean that the function could take both r-values
+// and l-values equially which is unexpected. See COMPARED To Boost.Move for
+// more details.
+//
+// An alternate, and incorrect, implementation of the RValue class used by
+// Boost.Move makes RValue a fieldless child of the move-only type. RValue&
+// is then used in place of RValue in the various operators. The RValue& is
+// "created" by doing *reinterpret_cast<RValue*>(this). This has the appeal
+// of never creating a temproary RValue struct even with optimizations
+// disabled. Also, by virtue of inheritance you can treat the RValue
+// reference as if it were the move-only type itself. Unfortuantely,
+// using the result of this reinterpret_cast<> is actually undefined behavior
+// due to C++98 5.2.10.7. In certain compilers (eg., NaCl) the optimizer
+// will generate non-working code.
+//
+// In optimized builds, both implementations generate the same assembly so we
+// choose the one that adheres to the standard.
+//
+//
+// COMPARED TO C++11
+//
+// In C++11, you would implement this functionality using an r-value reference
+// and our .Pass() method would be replaced with a call to std::move().
+//
+// This emulation also has a deficiency where it uses up the single
+// user-defined conversion allowed by C++ during initialization. This can
+// cause problems in some API edge cases. For instance, in scoped_ptr, it is
+// impossible to make an function "void Foo(scoped_ptr<Parent> p)" accept a
+// value of type scoped_ptr<Child> even if you add a constructor to
+// scoped_ptr<> that would make it look like it should work. C++11 does not
+// have this deficiency.
+//
+//
+// COMPARED TO Boost.Move
+//
+// Our implementation similar to Boost.Move, but we keep the RValue struct
+// private to the move-only type, and we don't use the reinterpret_cast<> hack.
+//
+// In Boost.Move, RValue is the boost::rv<> template. This type can be used
+// when writing APIs like:
+//
+// void MyFunc(boost::rv<Foo>& f)
+//
+// that can take advantage of rv<> to avoid extra copies of a type. However you
+// would still be able to call this version of MyFunc with an l-value:
+//
+// Foo f;
+// MyFunc(f); // Uh oh, we probably just destroyed |f| w/o calling Pass().
+//
+// unless someone is very careful to also declare a parallel override like:
+//
+// void MyFunc(const Foo& f)
+//
+// that would catch the l-values first. This was declared unsafe in C++11 and
+// a C++11 compiler will explicitly fail MyFunc(f). Unfortunately, we cannot
+// ensure this in C++03.
+//
+// Since we have no need for writing such APIs yet, our implementation keeps
+// RValue private and uses a .Pass() method to do the conversion instead of
+// trying to write a version of "std::move()." Writing an API like std::move()
+// would require the RValue structs to be public.
+//
+//
+// CAVEATS
+//
+// If you include a move-only type as a field inside a class that does not
+// explicitly declare a copy constructor, the containing class's implicit
+// copy constructor will change from Containing(const Containing&) to
+// Containing(Containing&). This can cause some unexpected errors.
+//
+// http://llvm.org/bugs/show_bug.cgi?id=11528
+//
+// The workaround is to explicitly declare your copy constructor.
+//
+#define MOVE_ONLY_TYPE_FOR_CPP_03(type, rvalue_type) \
+ private: \
+ struct rvalue_type { \
+ rvalue_type(type* object) : object(object) {} \
+ type* object; \
+ }; \
+ type(type&); \
+ void operator=(type&); \
+ \
+ public: \
+ operator rvalue_type() { return rvalue_type(this); } \
+ type Pass() { return type(rvalue_type(this)); } \
+ \
+ private:
+
+#endif // STARBOARD_COMMON_MOVE_H_
diff --git a/src/starboard/common/reset_and_return.h b/src/starboard/common/reset_and_return.h
new file mode 100644
index 0000000..c881e95
--- /dev/null
+++ b/src/starboard/common/reset_and_return.h
@@ -0,0 +1,31 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef STARBOARD_COMMON_RESET_AND_RETURN_H_
+#define STARBOARD_COMMON_RESET_AND_RETURN_H_
+
+namespace starboard {
+namespace common {
+
+template <typename T>
+T ResetAndReturn(T* t) {
+ T result(*t);
+ *t = T();
+ return result;
+}
+
+} // namespace common
+} // namespace starboard
+
+#endif // STARBOARD_COMMON_RESET_AND_RETURN_H_
diff --git a/src/starboard/common/scoped_ptr.h b/src/starboard/common/scoped_ptr.h
new file mode 100644
index 0000000..a762268
--- /dev/null
+++ b/src/starboard/common/scoped_ptr.h
@@ -0,0 +1,491 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Scopers help you manage ownership of a pointer, helping you easily manage the
+// a pointer within a scope, and automatically destroying the pointer at the
+// end of a scope. There are two main classes you will use, which correspond
+// to the operators new/delete and new[]/delete[].
+//
+// Example usage (scoped_ptr):
+// {
+// scoped_ptr<Foo> foo(new Foo("wee"));
+// } // foo goes out of scope, releasing the pointer with it.
+//
+// {
+// scoped_ptr<Foo> foo; // No pointer managed.
+// foo.reset(new Foo("wee")); // Now a pointer is managed.
+// foo.reset(new Foo("wee2")); // Foo("wee") was destroyed.
+// foo.reset(new Foo("wee3")); // Foo("wee2") was destroyed.
+// foo->Method(); // Foo::Method() called.
+// foo.get()->Method(); // Foo::Method() called.
+// SomeFunc(foo.release()); // SomeFunc takes ownership, foo no longer
+// // manages a pointer.
+// foo.reset(new Foo("wee4")); // foo manages a pointer again.
+// foo.reset(); // Foo("wee4") destroyed, foo no longer
+// // manages a pointer.
+// } // foo wasn't managing a pointer, so nothing was destroyed.
+//
+// Example usage (scoped_array):
+// {
+// scoped_array<Foo> foo(new Foo[100]);
+// foo.get()->Method(); // Foo::Method on the 0th element.
+// foo[10].Method(); // Foo::Method on the 10th element.
+// }
+//
+// These scopers also implement part of the functionality of C++11 unique_ptr
+// in that they are "movable but not copyable." You can use the scopers in
+// the parameter and return types of functions to signify ownership transfer
+// in to and out of a function. When calling a function that has a scoper
+// as the argument type, it must be called with the result of an analogous
+// scoper's Pass() function or another function that generates a temporary;
+// passing by copy will NOT work. Here is an example using scoped_ptr:
+//
+// void TakesOwnership(scoped_ptr<Foo> arg) {
+// // Do something with arg
+// }
+// scoped_ptr<Foo> CreateFoo() {
+// // No need for calling Pass() because we are constructing a temporary
+// // for the return value.
+// return scoped_ptr<Foo>(new Foo("new"));
+// }
+// scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) {
+// return arg.Pass();
+// }
+//
+// {
+// scoped_ptr<Foo> ptr(new Foo("yay")); // ptr manages Foo("yay").
+// TakesOwnership(ptr.Pass()); // ptr no longer owns Foo("yay").
+// scoped_ptr<Foo> ptr2 = CreateFoo(); // ptr2 owns the return Foo.
+// scoped_ptr<Foo> ptr3 = // ptr3 now owns what was in ptr2.
+// PassThru(ptr2.Pass()); // ptr2 is correspondingly NULL.
+// }
+//
+// Notice that if you do not call Pass() when returning from PassThru(), or
+// when invoking TakesOwnership(), the code will not compile because scopers
+// are not copyable; they only implement move semantics which require calling
+// the Pass() function to signify a destructive transfer of state. CreateFoo()
+// is different though because we are constructing a temporary on the return
+// line and thus can avoid needing to call Pass().
+//
+// Pass() properly handles upcast in assignment, i.e. you can assign
+// scoped_ptr<Child> to scoped_ptr<Parent>:
+//
+// scoped_ptr<Foo> foo(new Foo());
+// scoped_ptr<FooParent> parent = foo.Pass();
+//
+// PassAs<>() should be used to upcast return value in return statement:
+//
+// scoped_ptr<Foo> CreateFoo() {
+// scoped_ptr<FooChild> result(new FooChild());
+// return result.PassAs<Foo>();
+// }
+//
+// Note that PassAs<>() is implemented only for scoped_ptr, but not for
+// scoped_array. This is because casting array pointers may not be safe.
+
+#ifndef STARBOARD_COMMON_SCOPED_PTR_H_
+#define STARBOARD_COMMON_SCOPED_PTR_H_
+
+// This is an implementation designed to match the anticipated future TR2
+// implementation of the scoped_ptr class, and its closely-related brethren,
+// scoped_array, scoped_ptr_malloc.
+
+#include "starboard/log.h"
+#include "starboard/memory.h"
+#include "starboard/types.h"
+
+#include <algorithm>
+
+#include "starboard/common/move.h"
+
+namespace starboard {
+
+// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any).
+// That is, scoped_ptr<T> owns the T object that it points to.
+// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
+// Also like T*, scoped_ptr<T> is thread-compatible, and once you
+// dereference it, you get the thread safety guarantees of T.
+//
+// The size of a scoped_ptr is small:
+// sizeof(scoped_ptr<C>) == sizeof(C*)
+template <class C>
+class scoped_ptr {
+ MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr, RValue)
+
+ public:
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to initializing with NULL.
+ // There is no way to create an uninitialized scoped_ptr.
+ // The input parameter must be allocated with new.
+ explicit scoped_ptr(C* p = NULL) : ptr_(p) {}
+
+// The GHS compiler always chooses this copy constructor over the next one,
+// so disable this to promote the more important and frequently used constr.
+#if !defined(COMPILER_GHS)
+ // Constructor. Allows construction from a scoped_ptr rvalue for a
+ // convertible type.
+ template <typename U>
+ scoped_ptr(scoped_ptr<U> other)
+ : ptr_(other.release()) {}
+#endif
+
+ // Constructor. Move constructor for C++03 move emulation of this type.
+ scoped_ptr(RValue rvalue) : ptr_(rvalue.object->release()) {}
+
+ // Destructor. If there is a C object, delete it.
+ // We don't need to test ptr_ == NULL because C++ does that for us.
+ ~scoped_ptr() {
+ enum { type_must_be_complete = sizeof(C) };
+ delete ptr_;
+ }
+
+ // operator=. Allows assignment from a scoped_ptr rvalue for a convertible
+ // type.
+ template <typename U>
+ scoped_ptr& operator=(scoped_ptr<U> rhs) {
+ reset(rhs.release());
+ return *this;
+ }
+
+ // operator=. Move operator= for C++03 move emulation of this type.
+ scoped_ptr& operator=(RValue rhs) {
+ swap(*rhs->object);
+ return *this;
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (p != ptr_) {
+ enum { type_must_be_complete = sizeof(C) };
+ delete ptr_;
+ ptr_ = p;
+ }
+ }
+
+ // Accessors to get the owned object.
+ // operator* and operator-> will SB_DCHECK() if there is no current object.
+ C& operator*() const {
+ SB_DCHECK(ptr_ != NULL);
+ return *ptr_;
+ }
+ C* operator->() const {
+ SB_DCHECK(ptr_ != NULL);
+ return ptr_;
+ }
+ C* get() const { return ptr_; }
+
+ // Allow scoped_ptr<C> to be used in boolean expressions, but not
+ // implicitly convertible to a real bool (which is dangerous).
+ typedef C* scoped_ptr::*Testable;
+ operator Testable() const { return ptr_ ? &scoped_ptr::ptr_ : NULL; }
+
+ // Comparison operators.
+ // These return whether two scoped_ptr refer to the same object, not just to
+ // two different but equal objects.
+ bool operator==(C* p) const { return ptr_ == p; }
+ bool operator!=(C* p) const { return ptr_ != p; }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr& p2) {
+ C* tmp = ptr_;
+ ptr_ = p2.ptr_;
+ p2.ptr_ = tmp;
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() {
+ C* retVal = ptr_;
+ ptr_ = NULL;
+ return retVal;
+ }
+
+ template <typename PassAsType>
+ scoped_ptr<PassAsType> PassAs() {
+ return scoped_ptr<PassAsType>(release());
+ }
+
+ private:
+ C* ptr_;
+
+ // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't
+ // make sense, and if C2 == C, it still doesn't make sense because you should
+ // never have the same object owned by two different scoped_ptrs.
+ template <class C2>
+ bool operator==(scoped_ptr<C2> const& p2) const;
+ template <class C2>
+ bool operator!=(scoped_ptr<C2> const& p2) const;
+};
+
+// Free functions
+template <class C>
+void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) {
+ p1.swap(p2);
+}
+
+template <class C>
+bool operator==(C* p1, const scoped_ptr<C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+bool operator!=(C* p1, const scoped_ptr<C>& p2) {
+ return p1 != p2.get();
+}
+
+// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
+// with new [] and the destructor deletes objects with delete [].
+//
+// As with scoped_ptr<C>, a scoped_array<C> either points to an object
+// or is NULL. A scoped_array<C> owns the object that it points to.
+// scoped_array<T> is thread-compatible, and once you index into it,
+// the returned objects have only the thread safety guarantees of T.
+//
+// Size: sizeof(scoped_array<C>) == sizeof(C*)
+template <class C>
+class scoped_array {
+ MOVE_ONLY_TYPE_FOR_CPP_03(scoped_array, RValue)
+
+ public:
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to initializing with NULL.
+ // There is no way to create an uninitialized scoped_array.
+ // The input parameter must be allocated with new [].
+ explicit scoped_array(C* p = NULL) : array_(p) {}
+
+ // Constructor. Move constructor for C++03 move emulation of this type.
+ scoped_array(RValue rvalue) : array_(rvalue.object->release()) {}
+
+ // Destructor. If there is a C object, delete it.
+ // We don't need to test ptr_ == NULL because C++ does that for us.
+ ~scoped_array() {
+ enum { type_must_be_complete = sizeof(C) };
+ delete[] array_;
+ }
+
+ // operator=. Move operator= for C++03 move emulation of this type.
+ scoped_array& operator=(RValue rhs) {
+ swap(*rhs.object);
+ return *this;
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (p != array_) {
+ enum { type_must_be_complete = sizeof(C) };
+ delete[] array_;
+ array_ = p;
+ }
+ }
+
+ // Get one element of the current object.
+ // Will SB_DCHECK() if there is no current object, or index i is negative.
+ C& operator[](ptrdiff_t i) const {
+ SB_DCHECK(i >= 0);
+ SB_DCHECK(array_ != NULL);
+ return array_[i];
+ }
+
+ // Get a pointer to the zeroth element of the current object.
+ // If there is no current object, return NULL.
+ C* get() const { return array_; }
+
+ // Allow scoped_array<C> to be used in boolean expressions, but not
+ // implicitly convertible to a real bool (which is dangerous).
+ typedef C* scoped_array::*Testable;
+ operator Testable() const { return array_ ? &scoped_array::array_ : NULL; }
+
+ // Comparison operators.
+ // These return whether two scoped_array refer to the same object, not just to
+ // two different but equal objects.
+ bool operator==(C* p) const { return array_ == p; }
+ bool operator!=(C* p) const { return array_ != p; }
+
+ // Swap two scoped arrays.
+ void swap(scoped_array& p2) {
+ C* tmp = array_;
+ array_ = p2.array_;
+ p2.array_ = tmp;
+ }
+
+ // Release an array.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() {
+ C* retVal = array_;
+ array_ = NULL;
+ return retVal;
+ }
+
+ private:
+ C* array_;
+
+ // Forbid comparison of different scoped_array types.
+ template <class C2>
+ bool operator==(scoped_array<C2> const& p2) const;
+ template <class C2>
+ bool operator!=(scoped_array<C2> const& p2) const;
+};
+
+// Free functions
+template <class C>
+void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
+ p1.swap(p2);
+}
+
+template <class C>
+bool operator==(C* p1, const scoped_array<C>& p2) {
+ return p1 == p2.get();
+}
+
+template <class C>
+bool operator!=(C* p1, const scoped_array<C>& p2) {
+ return p1 != p2.get();
+}
+
+// This class wraps the c library function free() in a class that can be
+// passed as a template argument to scoped_ptr_malloc below.
+class ScopedPtrMallocFree {
+ public:
+ inline void operator()(void* x) const { SbMemoryFree(x); }
+};
+
+// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
+// second template argument, the functor used to free the object.
+
+template <class C, class FreeProc = ScopedPtrMallocFree>
+class scoped_ptr_malloc {
+ MOVE_ONLY_TYPE_FOR_CPP_03(scoped_ptr_malloc, RValue)
+
+ public:
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to initializing with NULL.
+ // There is no way to create an uninitialized scoped_ptr.
+ // The input parameter must be allocated with an allocator that matches the
+ // Free functor. For the default Free functor, this is malloc, calloc, or
+ // realloc.
+ explicit scoped_ptr_malloc(C* p = NULL) : ptr_(p) {}
+
+ // Constructor. Move constructor for C++03 move emulation of this type.
+ scoped_ptr_malloc(RValue rvalue) : ptr_(rvalue.object->release()) {}
+
+ // Destructor. If there is a C object, call the Free functor.
+ ~scoped_ptr_malloc() { reset(); }
+
+ // operator=. Move operator= for C++03 move emulation of this type.
+ scoped_ptr_malloc& operator=(RValue rhs) {
+ swap(*rhs.object);
+ return *this;
+ }
+
+ // Reset. Calls the Free functor on the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (ptr_ != p) {
+ FreeProc free_proc;
+ free_proc(ptr_);
+ ptr_ = p;
+ }
+ }
+
+ // Get the current object.
+ // operator* and operator-> will cause an SB_DCHECK() failure if there is
+ // no current object.
+ C& operator*() const {
+ SB_DCHECK(ptr_ != NULL);
+ return *ptr_;
+ }
+
+ C* operator->() const {
+ SB_DCHECK(ptr_ != NULL);
+ return ptr_;
+ }
+
+ C* get() const { return ptr_; }
+
+ // Allow scoped_ptr_malloc<C> to be used in boolean expressions, but not
+ // implicitly convertible to a real bool (which is dangerous).
+ typedef C* scoped_ptr_malloc::*Testable;
+ operator Testable() const { return ptr_ ? &scoped_ptr_malloc::ptr_ : NULL; }
+
+ // Comparison operators.
+ // These return whether a scoped_ptr_malloc and a plain pointer refer
+ // to the same object, not just to two different but equal objects.
+ // For compatibility with the boost-derived implementation, these
+ // take non-const arguments.
+ bool operator==(C* p) const { return ptr_ == p; }
+
+ bool operator!=(C* p) const { return ptr_ != p; }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr_malloc& b) {
+ C* tmp = b.ptr_;
+ b.ptr_ = ptr_;
+ ptr_ = tmp;
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() {
+ C* tmp = ptr_;
+ ptr_ = NULL;
+ return tmp;
+ }
+
+ private:
+ C* ptr_;
+
+ // no reason to use these: each scoped_ptr_malloc should have its own object
+ template <class C2, class GP>
+ bool operator==(scoped_ptr_malloc<C2, GP> const& p) const;
+ template <class C2, class GP>
+ bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
+};
+
+template <class C, class FP>
+inline void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
+ a.swap(b);
+}
+
+template <class C, class FP>
+inline bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) {
+ return p == b.get();
+}
+
+template <class C, class FP>
+inline bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) {
+ return p != b.get();
+}
+
+// A function to convert T* into scoped_ptr<T>
+// Doing e.g. make_scoped_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for scoped_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+scoped_ptr<T> make_scoped_ptr(T* ptr) {
+ return scoped_ptr<T>(ptr);
+}
+
+} // namespace starboard
+
+#endif // STARBOARD_COMMON_SCOPED_PTR_H_
diff --git a/src/starboard/linux/shared/configuration_public.h b/src/starboard/linux/shared/configuration_public.h
index 7d84890..20643e6 100644
--- a/src/starboard/linux/shared/configuration_public.h
+++ b/src/starboard/linux/shared/configuration_public.h
@@ -355,8 +355,19 @@
// --- Tuneable Parameters ---------------------------------------------------
-// Specifies the network receive buffer size.
-#define SB_NETWORK_RECEIVE_BUFFER_SIZE (16 * 1024)
+// Specifies the network receive buffer size in bytes, set via
+// SbSocketSetReceiveBufferSize().
+//
+// Setting this to 0 indicates that SbSocketSetReceiveBufferSize() should
+// not be called. Use this for OSs (such as Linux) where receive buffer
+// auto-tuning is better.
+//
+// On some platforms, this may affect max TCP window size which may
+// dramatically affect throughput in the presence of latency.
+//
+// If your platform does not have a good TCP auto-tuning mechanism,
+// a setting of (128 * 1024) here is recommended.
+#define SB_NETWORK_RECEIVE_BUFFER_SIZE (0)
// --- User Configuration ----------------------------------------------------
diff --git a/src/starboard/linux/x64directfb/starboard_platform.gyp b/src/starboard/linux/x64directfb/starboard_platform.gyp
index 331fd6c..f89ae85 100644
--- a/src/starboard/linux/x64directfb/starboard_platform.gyp
+++ b/src/starboard/linux/x64directfb/starboard_platform.gyp
@@ -268,9 +268,14 @@
'<(DEPTH)/starboard/shared/starboard/media/mime_parser.cc',
'<(DEPTH)/starboard/shared/starboard/media/mime_parser.h',
'<(DEPTH)/starboard/shared/starboard/new.cc',
- '<(DEPTH)/starboard/shared/starboard/player/audio_decoder_internal.h',
- '<(DEPTH)/starboard/shared/starboard/player/audio_renderer_internal.cc',
- '<(DEPTH)/starboard/shared/starboard/player/audio_renderer_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_decoder_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_renderer_internal.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_renderer_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_decoder_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_renderer_internal.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_renderer_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/input_buffer_internal.cc',
'<(DEPTH)/starboard/shared/starboard/player/input_buffer_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/player_create.cc',
@@ -286,11 +291,8 @@
'<(DEPTH)/starboard/shared/starboard/player/player_worker.h',
'<(DEPTH)/starboard/shared/starboard/player/player_write_end_of_stream.cc',
'<(DEPTH)/starboard/shared/starboard/player/player_write_sample.cc',
- '<(DEPTH)/starboard/shared/starboard/player/video_decoder_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/video_frame_internal.cc',
'<(DEPTH)/starboard/shared/starboard/player/video_frame_internal.h',
- '<(DEPTH)/starboard/shared/starboard/player/video_renderer_internal.cc',
- '<(DEPTH)/starboard/shared/starboard/player/video_renderer_internal.h',
'<(DEPTH)/starboard/shared/starboard/queue_application.cc',
'<(DEPTH)/starboard/shared/starboard/string_concat.cc',
'<(DEPTH)/starboard/shared/starboard/string_concat_wide.cc',
@@ -322,6 +324,7 @@
'STARBOARD_IMPLEMENTATION',
],
'dependencies': [
+ '<(DEPTH)/starboard/common/common.gyp:common',
'<(DEPTH)/third_party/dlmalloc/dlmalloc.gyp:dlmalloc',
'<(DEPTH)/third_party/libevent/libevent.gyp:libevent',
'starboard_base_symbolize',
diff --git a/src/starboard/linux/x64x11/starboard_platform.gyp b/src/starboard/linux/x64x11/starboard_platform.gyp
index 761a55d..6f9e3f8 100644
--- a/src/starboard/linux/x64x11/starboard_platform.gyp
+++ b/src/starboard/linux/x64x11/starboard_platform.gyp
@@ -229,9 +229,14 @@
'<(DEPTH)/starboard/shared/starboard/media/mime_parser.cc',
'<(DEPTH)/starboard/shared/starboard/media/mime_parser.h',
'<(DEPTH)/starboard/shared/starboard/new.cc',
- '<(DEPTH)/starboard/shared/starboard/player/audio_decoder_internal.h',
- '<(DEPTH)/starboard/shared/starboard/player/audio_renderer_internal.cc',
- '<(DEPTH)/starboard/shared/starboard/player/audio_renderer_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_decoder_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_renderer_internal.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_renderer_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_decoder_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_renderer_internal.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_renderer_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/input_buffer_internal.cc',
'<(DEPTH)/starboard/shared/starboard/player/input_buffer_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/player_create.cc',
@@ -247,11 +252,8 @@
'<(DEPTH)/starboard/shared/starboard/player/player_worker.h',
'<(DEPTH)/starboard/shared/starboard/player/player_write_end_of_stream.cc',
'<(DEPTH)/starboard/shared/starboard/player/player_write_sample.cc',
- '<(DEPTH)/starboard/shared/starboard/player/video_decoder_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/video_frame_internal.cc',
'<(DEPTH)/starboard/shared/starboard/player/video_frame_internal.h',
- '<(DEPTH)/starboard/shared/starboard/player/video_renderer_internal.cc',
- '<(DEPTH)/starboard/shared/starboard/player/video_renderer_internal.h',
'<(DEPTH)/starboard/shared/starboard/queue_application.cc',
'<(DEPTH)/starboard/shared/starboard/string_concat.cc',
'<(DEPTH)/starboard/shared/starboard/string_concat_wide.cc',
@@ -286,6 +288,7 @@
'STARBOARD_IMPLEMENTATION',
],
'dependencies': [
+ '<(DEPTH)/starboard/common/common.gyp:common',
'<(DEPTH)/third_party/dlmalloc/dlmalloc.gyp:dlmalloc',
'<(DEPTH)/third_party/libevent/libevent.gyp:libevent',
'starboard_base_symbolize',
diff --git a/src/starboard/player.h b/src/starboard/player.h
index 236f3f6..333c9dd 100644
--- a/src/starboard/player.h
+++ b/src/starboard/player.h
@@ -35,13 +35,12 @@
// An indicator of whether the decoder can accept more samples.
typedef enum SbPlayerDecoderState {
- // The decoder is ready for and eager to receive more samples. Note that
- // once the decoder notifies the user with kSbPlayerDecoderStateNeedsData,
- // it cannot enter kSbPlayerDecoderStateBufferFull before SbPlayerWriteSample
- // or SbPlayerWriteEndOfStream is called.
+ // The decoder is asking for one more sample.
kSbPlayerDecoderStateNeedsData,
// The decoder is not ready for any more samples, so do not send them.
+ // Note that this enum value has been deprecated and the SbPlayer
+ // implementation should no longer use this value.
kSbPlayerDecoderStateBufferFull,
// The player has been destroyed, and will send no more callbacks.
@@ -61,7 +60,8 @@
kSbPlayerStatePrerolling,
// The player is presenting media, and it is either actively playing in
- // real-time, or it is paused.
+ // real-time, or it is paused. Note that the implementation should use this
+ // state to signal that the preroll has been finished.
kSbPlayerStatePresenting,
// The player is presenting media, but it is paused at the end of the stream.
@@ -124,7 +124,11 @@
// this callback was dispatched. This is to distinguish status callbacks for
// interrupting seeks. These callbacks will happen on a different thread than
// the calling thread, and it is not valid to call SbPlayer functions from
-// within this callback.
+// within this callback. After an update with kSbPlayerDecoderStateNeedsData,
+// the user of the player will make at most one call to SbPlayerWriteSample() or
+// SbPlayerWriteEndOfStream(). The player implementation should update the
+// decoder status again after such call to notify its user to continue writing
+// more frames.
typedef void (*SbPlayerDecoderStatusFunc)(SbPlayer player,
void* context,
SbMediaType type,
@@ -207,8 +211,8 @@
// |context| will be passed back into all callbacks, and is generally used to
// point at a class or struct that contains state associated with the player.
//
-// The associated decoder of the returned player should be assumed to be in
-// kSbPlayerDecoderStateBufferFull until SbPlayerSeek() has been called on it.
+// The associated decoder of the returned player should be assumed to be not in
+// kSbPlayerDecoderStateNeedsData until SbPlayerSeek() has been called on it.
//
// It is expected that the thread that calls SbPlayerCreate is the same thread
// that calls the other SbPlayer functions for that player, or that there is a
diff --git a/src/starboard/raspi/1/starboard_platform.gyp b/src/starboard/raspi/1/starboard_platform.gyp
index 6d8c257..b866ee7 100644
--- a/src/starboard/raspi/1/starboard_platform.gyp
+++ b/src/starboard/raspi/1/starboard_platform.gyp
@@ -236,9 +236,14 @@
'<(DEPTH)/starboard/shared/starboard/media/mime_parser.cc',
'<(DEPTH)/starboard/shared/starboard/media/mime_parser.h',
'<(DEPTH)/starboard/shared/starboard/new.cc',
- '<(DEPTH)/starboard/shared/starboard/player/audio_decoder_internal.h',
- '<(DEPTH)/starboard/shared/starboard/player/audio_renderer_internal.cc',
- '<(DEPTH)/starboard/shared/starboard/player/audio_renderer_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_decoder_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_renderer_internal.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/audio_renderer_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_decoder_internal.h',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_renderer_internal.cc',
+ '<(DEPTH)/starboard/shared/starboard/player/filter/video_renderer_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/input_buffer_internal.cc',
'<(DEPTH)/starboard/shared/starboard/player/input_buffer_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/player_create.cc',
@@ -254,11 +259,8 @@
'<(DEPTH)/starboard/shared/starboard/player/player_worker.h',
'<(DEPTH)/starboard/shared/starboard/player/player_write_end_of_stream.cc',
'<(DEPTH)/starboard/shared/starboard/player/player_write_sample.cc',
- '<(DEPTH)/starboard/shared/starboard/player/video_decoder_internal.h',
'<(DEPTH)/starboard/shared/starboard/player/video_frame_internal.cc',
'<(DEPTH)/starboard/shared/starboard/player/video_frame_internal.h',
- '<(DEPTH)/starboard/shared/starboard/player/video_renderer_internal.cc',
- '<(DEPTH)/starboard/shared/starboard/player/video_renderer_internal.h',
'<(DEPTH)/starboard/shared/starboard/queue_application.cc',
'<(DEPTH)/starboard/shared/starboard/string_concat.cc',
'<(DEPTH)/starboard/shared/starboard/string_concat_wide.cc',
@@ -287,6 +289,7 @@
'STARBOARD_IMPLEMENTATION',
],
'dependencies': [
+ '<(DEPTH)/starboard/common/common.gyp:common',
'<(DEPTH)/third_party/dlmalloc/dlmalloc.gyp:dlmalloc',
'<(DEPTH)/third_party/libevent/libevent.gyp:libevent',
'starboard_base_symbolize',
diff --git a/src/starboard/raspi/shared/configuration_public.h b/src/starboard/raspi/shared/configuration_public.h
index 942feef..15c18ca 100644
--- a/src/starboard/raspi/shared/configuration_public.h
+++ b/src/starboard/raspi/shared/configuration_public.h
@@ -352,8 +352,19 @@
// --- Tuneable Parameters ---------------------------------------------------
-// Specifies the network receive buffer size.
-#define SB_NETWORK_RECEIVE_BUFFER_SIZE (16 * 1024)
+// Specifies the network receive buffer size in bytes, set via
+// SbSocketSetReceiveBufferSize().
+//
+// Setting this to 0 indicates that SbSocketSetReceiveBufferSize() should
+// not be called. Use this for OSs (such as Linux) where receive buffer
+// auto-tuning is better.
+//
+// On some platforms, this may affect max TCP window size which may
+// dramatically affect throughput in the presence of latency.
+//
+// If your platform does not have a good TCP auto-tuning mechanism,
+// a setting of (128 * 1024) here is recommended.
+#define SB_NETWORK_RECEIVE_BUFFER_SIZE (0)
// --- User Configuration ----------------------------------------------------
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.cc b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.cc
index 00e98e6..618b9e3 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.cc
+++ b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.cc
@@ -190,6 +190,7 @@
namespace starboard {
namespace player {
+namespace filter {
// static
AudioDecoder* AudioDecoder::Create(SbMediaAudioCodec audio_codec,
@@ -203,6 +204,7 @@
return NULL;
}
+} // namespace filter
} // namespace player
} // namespace starboard
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.h b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.h
index eac65a2..3eda447 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.h
+++ b/src/starboard/shared/ffmpeg/ffmpeg_audio_decoder.h
@@ -20,13 +20,13 @@
#include "starboard/media.h"
#include "starboard/shared/ffmpeg/ffmpeg_common.h"
#include "starboard/shared/internal_only.h"
-#include "starboard/shared/starboard/player/audio_decoder_internal.h"
+#include "starboard/shared/starboard/player/filter/audio_decoder_internal.h"
namespace starboard {
namespace shared {
namespace ffmpeg {
-class AudioDecoder : public starboard::player::AudioDecoder {
+class AudioDecoder : public starboard::player::filter::AudioDecoder {
public:
typedef starboard::player::InputBuffer InputBuffer;
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
index eafff4c..d60f480 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
+++ b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.cc
@@ -292,6 +292,7 @@
namespace starboard {
namespace player {
+namespace filter {
// static
VideoDecoder* VideoDecoder::Create(SbMediaVideoCodec video_codec) {
@@ -303,6 +304,7 @@
return NULL;
}
+} // namespace filter
} // namespace player
} // namespace starboard
diff --git a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.h b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.h
index 6bcd6d3..8c5e99a 100644
--- a/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.h
+++ b/src/starboard/shared/ffmpeg/ffmpeg_video_decoder.h
@@ -20,8 +20,8 @@
#include "starboard/queue.h"
#include "starboard/shared/ffmpeg/ffmpeg_common.h"
#include "starboard/shared/internal_only.h"
+#include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
#include "starboard/shared/starboard/player/input_buffer_internal.h"
-#include "starboard/shared/starboard/player/video_decoder_internal.h"
#include "starboard/shared/starboard/player/video_frame_internal.h"
#include "starboard/thread.h"
@@ -29,7 +29,7 @@
namespace shared {
namespace ffmpeg {
-class VideoDecoder : public starboard::player::VideoDecoder {
+class VideoDecoder : public starboard::player::filter::VideoDecoder {
public:
typedef starboard::player::InputBuffer InputBuffer;
typedef starboard::player::VideoFrame VideoFrame;
diff --git a/src/starboard/shared/signal/crash_signals.cc b/src/starboard/shared/signal/crash_signals.cc
index a3e9b2e..0d74011 100644
--- a/src/starboard/shared/signal/crash_signals.cc
+++ b/src/starboard/shared/signal/crash_signals.cc
@@ -28,21 +28,25 @@
namespace {
const int kCrashSignalsToTrap[] = {
- SIGABRT, SIGFPE, SIGILL, SIGSEGV,
+ SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS,
};
const int kStopSignalsToTrap[] = {
- SIGTERM, SIGINT,
+ SIGTERM, SIGINT, SIGHUP,
};
-void DumpStackSignalSafe(int signal_id) {
- LogSignalCaught(signal_id);
- SbLogRawDumpStack(1);
-
+void Crash(int signal_id) {
+ DumpStackSignalSafe(signal_id);
UninstallCrashSignalHandlers();
SbSystemBreakIntoDebugger();
}
+void Quit(int signal_id) {
+ DumpStackSignalSafe(signal_id);
+ ::signal(SIGQUIT, SIG_DFL);
+ ::raise(SIGQUIT);
+}
+
void Stop(int signal_id) {
LogSignalCaught(signal_id);
SbSystemRequestStop(0);
@@ -52,11 +56,12 @@
void InstallCrashSignalHandlers() {
for (int i = 0; i < SB_ARRAY_SIZE_INT(kCrashSignalsToTrap); ++i) {
- ::signal(kCrashSignalsToTrap[i], &DumpStackSignalSafe);
+ ::signal(kCrashSignalsToTrap[i], &Crash);
}
for (int i = 0; i < SB_ARRAY_SIZE_INT(kStopSignalsToTrap); ++i) {
::signal(kStopSignalsToTrap[i], &Stop);
}
+ ::signal(SIGQUIT, &Quit);
}
void UninstallCrashSignalHandlers() {
@@ -66,6 +71,7 @@
for (int i = 0; i < SB_ARRAY_SIZE_INT(kStopSignalsToTrap); ++i) {
::signal(kStopSignalsToTrap[i], SIG_DFL);
}
+ ::signal(SIGQUIT, SIG_DFL);
}
} // namespace signal
diff --git a/src/starboard/shared/signal/crash_signals_sigaction.cc b/src/starboard/shared/signal/crash_signals_sigaction.cc
index 4bf5b59..5273ab1 100644
--- a/src/starboard/shared/signal/crash_signals_sigaction.cc
+++ b/src/starboard/shared/signal/crash_signals_sigaction.cc
@@ -28,11 +28,11 @@
namespace {
const int kCrashSignalsToTrap[] = {
- SIGABRT, SIGFPE, SIGILL, SIGSEGV,
+ SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS,
};
const int kStopSignalsToTrap[] = {
- SIGTERM, SIGINT,
+ SIGTERM, SIGINT, SIGHUP,
};
void SetSignalHandler(int signal_id, SignalHandlerFunction handler) {
@@ -45,15 +45,18 @@
::sigaction(signal_id, &action, NULL);
}
-void DumpStackSignalSafe(int signal_id) {
- LogSignalCaught(signal_id);
- SbLogFlush();
- SbLogRawDumpStack(1);
-
+void Crash(int signal_id) {
+ DumpStackSignalSafe(signal_id);
UninstallCrashSignalHandlers();
SbSystemBreakIntoDebugger();
}
+void Quit(int signal_id) {
+ DumpStackSignalSafe(signal_id);
+ SetSignalHandler(SIGQUIT, SIG_DFL);
+ ::raise(SIGQUIT);
+}
+
void Stop(int signal_id) {
LogSignalCaught(signal_id);
SbSystemRequestStop(0);
@@ -63,11 +66,12 @@
void InstallCrashSignalHandlers() {
for (int i = 0; i < SB_ARRAY_SIZE_INT(kCrashSignalsToTrap); ++i) {
- SetSignalHandler(kCrashSignalsToTrap[i], &DumpStackSignalSafe);
+ SetSignalHandler(kCrashSignalsToTrap[i], &Crash);
}
for (int i = 0; i < SB_ARRAY_SIZE_INT(kStopSignalsToTrap); ++i) {
SetSignalHandler(kStopSignalsToTrap[i], &Stop);
}
+ SetSignalHandler(SIGQUIT, &Quit);
}
void UninstallCrashSignalHandlers() {
@@ -77,6 +81,7 @@
for (int i = 0; i < SB_ARRAY_SIZE_INT(kStopSignalsToTrap); ++i) {
SetSignalHandler(kStopSignalsToTrap[i], SIG_DFL);
}
+ SetSignalHandler(SIGQUIT, SIG_DFL);
}
} // namespace signal
diff --git a/src/starboard/shared/signal/signal_internal.h b/src/starboard/shared/signal/signal_internal.h
index f511ab0..0d2ec54 100644
--- a/src/starboard/shared/signal/signal_internal.h
+++ b/src/starboard/shared/signal/signal_internal.h
@@ -28,22 +28,32 @@
switch (signal_id) {
case SIGABRT:
return "SIGABRT";
+ case SIGBUS:
+ return "SIGBUS";
case SIGCONT:
return "SIGCONT";
case SIGFPE:
return "SIGFPE";
+ case SIGHUP:
+ return "SIGHUP";
case SIGILL:
return "SIGILL";
case SIGINT:
return "SIGINT";
+ case SIGPIPE:
+ return "SIGPIPE";
+ case SIGQUIT:
+ return "SIGQUIT";
case SIGSEGV:
return "SIGSEGV";
+ case SIGSYS:
+ return "SIGSYS";
case SIGTSTP:
return "SIGTSTP";
case SIGTERM:
return "SIGTERM";
default:
- return "UNKNOWN SIGNAL";
+ return "UNKNOWN";
}
}
@@ -53,6 +63,12 @@
SbLogFlush();
}
+inline void DumpStackSignalSafe(int signal_id) {
+ LogSignalCaught(signal_id);
+ SbLogRawDumpStack(2);
+ SbLogFlush();
+}
+
typedef void (*SignalHandlerFunction)(int);
} // namespace signal
diff --git a/src/starboard/shared/signal/suspend_signals.cc b/src/starboard/shared/signal/suspend_signals.cc
index a3cbeea..6bb42d8 100644
--- a/src/starboard/shared/signal/suspend_signals.cc
+++ b/src/starboard/shared/signal/suspend_signals.cc
@@ -63,17 +63,27 @@
starboard::Application::Get()->Unpause(NULL, NULL);
}
+void Ignore(int signal_id) {
+ LogSignalCaught(signal_id);
+ SbLogRawDumpStack(1);
+ SbLogFlush();
+}
+
} // namespace
void InstallSuspendSignalHandlers() {
SetSignalHandler(SIGTSTP, &Suspend);
UnblockSignal(SIGTSTP);
SetSignalHandler(SIGCONT, &Resume);
+
+ // We might receive SIGPIPE after resuming. We should not terminate.
+ SetSignalHandler(SIGPIPE, &Ignore);
}
void UninstallSuspendSignalHandlers() {
SetSignalHandler(SIGCONT, SIG_DFL);
SetSignalHandler(SIGTSTP, SIG_DFL);
+ SetSignalHandler(SIGPIPE, SIG_DFL);
}
} // namespace signal
diff --git a/src/starboard/shared/starboard/player/audio_decoder_internal.h b/src/starboard/shared/starboard/player/filter/audio_decoder_internal.h
similarity index 88%
rename from src/starboard/shared/starboard/player/audio_decoder_internal.h
rename to src/starboard/shared/starboard/player/filter/audio_decoder_internal.h
index 000a22c..b8bdafe 100644
--- a/src/starboard/shared/starboard/player/audio_decoder_internal.h
+++ b/src/starboard/shared/starboard/player/filter/audio_decoder_internal.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_AUDIO_DECODER_INTERNAL_H_
-#define STARBOARD_SHARED_STARBOARD_PLAYER_AUDIO_DECODER_INTERNAL_H_
+#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_AUDIO_DECODER_INTERNAL_H_
+#define STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_AUDIO_DECODER_INTERNAL_H_
#include <vector>
@@ -25,6 +25,7 @@
namespace shared {
namespace starboard {
namespace player {
+namespace filter {
// This class decodes encoded audio stream into playable audio data.
class AudioDecoder {
@@ -53,9 +54,10 @@
const SbMediaAudioHeader& audio_header);
};
+} // namespace filter
} // namespace player
} // namespace starboard
} // namespace shared
} // namespace starboard
-#endif // STARBOARD_SHARED_STARBOARD_PLAYER_AUDIO_DECODER_INTERNAL_H_
+#endif // STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_AUDIO_DECODER_INTERNAL_H_
diff --git a/src/starboard/shared/starboard/player/audio_renderer_internal.cc b/src/starboard/shared/starboard/player/filter/audio_renderer_internal.cc
similarity index 96%
rename from src/starboard/shared/starboard/player/audio_renderer_internal.cc
rename to src/starboard/shared/starboard/player/filter/audio_renderer_internal.cc
index c761c09..3a53533 100644
--- a/src/starboard/shared/starboard/player/audio_renderer_internal.cc
+++ b/src/starboard/shared/starboard/player/filter/audio_renderer_internal.cc
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "starboard/shared/starboard/player/audio_renderer_internal.h"
+#include "starboard/shared/starboard/player/filter/audio_renderer_internal.h"
#include <algorithm>
@@ -22,6 +22,7 @@
namespace shared {
namespace starboard {
namespace player {
+namespace filter {
namespace {
// TODO: This should be retrieved from the decoder.
@@ -29,7 +30,7 @@
const int kMaxFramesPerAccessUnit = 1024 * 2;
} // namespace
-AudioRenderer::AudioRenderer(AudioDecoder* decoder,
+AudioRenderer::AudioRenderer(scoped_ptr<AudioDecoder> decoder,
const SbMediaAudioHeader& audio_header)
: channels_(audio_header.number_of_channels),
paused_(true),
@@ -40,7 +41,7 @@
offset_in_frames_(0),
frames_consumed_(0),
end_of_stream_reached_(false),
- decoder_(decoder),
+ decoder_(decoder.Pass()),
audio_sink_(kSbAudioSinkInvalid) {
SB_DCHECK(decoder_ != NULL);
frame_buffers_[0] = &frame_buffer_[0];
@@ -50,7 +51,6 @@
if (audio_sink_ != kSbAudioSinkInvalid) {
SbAudioSinkDestroy(audio_sink_);
}
- delete decoder_;
}
void AudioRenderer::WriteSample(const InputBuffer& input_buffer) {
@@ -240,6 +240,7 @@
frames_in_buffer_ += frames_to_append;
}
+} // namespace filter
} // namespace player
} // namespace starboard
} // namespace shared
diff --git a/src/starboard/shared/starboard/player/audio_renderer_internal.h b/src/starboard/shared/starboard/player/filter/audio_renderer_internal.h
similarity index 84%
rename from src/starboard/shared/starboard/player/audio_renderer_internal.h
rename to src/starboard/shared/starboard/player/filter/audio_renderer_internal.h
index cbc68c8..c85f1fe 100644
--- a/src/starboard/shared/starboard/player/audio_renderer_internal.h
+++ b/src/starboard/shared/starboard/player/filter/audio_renderer_internal.h
@@ -12,27 +12,30 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_AUDIO_RENDERER_INTERNAL_H_
-#define STARBOARD_SHARED_STARBOARD_PLAYER_AUDIO_RENDERER_INTERNAL_H_
+#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_AUDIO_RENDERER_INTERNAL_H_
+#define STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_AUDIO_RENDERER_INTERNAL_H_
#include <vector>
#include "starboard/audio_sink.h"
+#include "starboard/common/scoped_ptr.h"
#include "starboard/log.h"
#include "starboard/media.h"
#include "starboard/mutex.h"
#include "starboard/shared/internal_only.h"
-#include "starboard/shared/starboard/player/audio_decoder_internal.h"
+#include "starboard/shared/starboard/player/filter/audio_decoder_internal.h"
#include "starboard/shared/starboard/player/input_buffer_internal.h"
namespace starboard {
namespace shared {
namespace starboard {
namespace player {
+namespace filter {
class AudioRenderer {
public:
- AudioRenderer(AudioDecoder* decoder, const SbMediaAudioHeader& audio_header);
+ AudioRenderer(scoped_ptr<AudioDecoder> decoder,
+ const SbMediaAudioHeader& audio_header);
~AudioRenderer();
bool is_valid() const { return true; }
@@ -90,13 +93,14 @@
int frames_consumed_;
bool end_of_stream_reached_;
- AudioDecoder* decoder_;
+ scoped_ptr<AudioDecoder> decoder_;
SbAudioSink audio_sink_;
};
+} // namespace filter
} // namespace player
} // namespace starboard
} // namespace shared
} // namespace starboard
-#endif // STARBOARD_SHARED_STARBOARD_PLAYER_AUDIO_RENDERER_INTERNAL_H_
+#endif // STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_AUDIO_RENDERER_INTERNAL_H_
diff --git a/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
new file mode 100644
index 0000000..54477cf
--- /dev/null
+++ b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.cc
@@ -0,0 +1,242 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h"
+
+#include "starboard/log.h"
+#include "starboard/shared/starboard/application.h"
+#include "starboard/shared/starboard/drm/drm_system_internal.h"
+#include "starboard/shared/starboard/player/filter/audio_decoder_internal.h"
+#include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
+#include "starboard/shared/starboard/player/input_buffer_internal.h"
+#include "starboard/shared/starboard/player/video_frame_internal.h"
+#include "starboard/time.h"
+
+namespace starboard {
+namespace shared {
+namespace starboard {
+namespace player {
+namespace filter {
+
+FilterBasedPlayerWorkerHandler::FilterBasedPlayerWorkerHandler(
+ SbMediaVideoCodec video_codec,
+ SbMediaAudioCodec audio_codec,
+ SbDrmSystem drm_system,
+ const SbMediaAudioHeader& audio_header)
+ : player_worker_(NULL),
+ player_(kSbPlayerInvalid),
+ update_media_time_cb_(NULL),
+ get_player_state_cb_(NULL),
+ update_player_state_cb_(NULL),
+ video_codec_(video_codec),
+ audio_codec_(audio_codec),
+ drm_system_(drm_system),
+ audio_header_(audio_header),
+ paused_(false) {}
+
+void FilterBasedPlayerWorkerHandler::Setup(
+ PlayerWorker* player_worker,
+ SbPlayer player,
+ UpdateMediaTimeCB update_media_time_cb,
+ GetPlayerStateCB get_player_state_cb,
+ UpdatePlayerStateCB update_player_state_cb) {
+ // This function should only be called once.
+ SB_DCHECK(player_worker_ == NULL);
+
+ // All parameters has to be valid.
+ SB_DCHECK(player_worker);
+ SB_DCHECK(SbPlayerIsValid(player));
+ SB_DCHECK(update_media_time_cb);
+ SB_DCHECK(get_player_state_cb);
+ SB_DCHECK(update_player_state_cb);
+
+ player_worker_ = player_worker;
+ player_ = player;
+ update_media_time_cb_ = update_media_time_cb;
+ get_player_state_cb_ = get_player_state_cb;
+ update_player_state_cb_ = update_player_state_cb;
+}
+
+bool FilterBasedPlayerWorkerHandler::ProcessInitEvent() {
+ scoped_ptr<AudioDecoder> audio_decoder(
+ AudioDecoder::Create(audio_codec_, audio_header_));
+ scoped_ptr<VideoDecoder> video_decoder(VideoDecoder::Create(video_codec_));
+
+ if (!audio_decoder || !video_decoder) {
+ return false;
+ }
+
+ audio_renderer_.reset(new AudioRenderer(audio_decoder.Pass(), audio_header_));
+ video_renderer_.reset(new VideoRenderer(video_decoder.Pass()));
+ if (audio_renderer_->is_valid() && video_renderer_->is_valid()) {
+ return true;
+ }
+
+ audio_renderer_.reset(NULL);
+ video_renderer_.reset(NULL);
+ return false;
+}
+
+bool FilterBasedPlayerWorkerHandler::ProcessSeekEvent(
+ const SeekEventData& data) {
+ SbMediaTime seek_to_pts = data.seek_to_pts;
+ if (seek_to_pts < 0) {
+ SB_DLOG(ERROR) << "Try to seek to negative timestamp " << seek_to_pts;
+ seek_to_pts = 0;
+ }
+
+ audio_renderer_->Pause();
+ audio_renderer_->Seek(seek_to_pts);
+ video_renderer_->Seek(seek_to_pts);
+ return true;
+}
+
+bool FilterBasedPlayerWorkerHandler::ProcessWriteSampleEvent(
+ const WriteSampleEventData& data,
+ bool* written) {
+ SB_DCHECK(written != NULL);
+
+ *written = true;
+
+ if (data.sample_type == kSbMediaTypeAudio) {
+ if (audio_renderer_->IsEndOfStreamWritten()) {
+ SB_LOG(WARNING) << "Try to write audio sample after EOS is reached";
+ } else {
+ if (!audio_renderer_->CanAcceptMoreData()) {
+ *written = false;
+ return true;
+ }
+
+ if (data.input_buffer->drm_info()) {
+ if (!SbDrmSystemIsValid(drm_system_)) {
+ return false;
+ }
+ if (drm_system_->Decrypt(data.input_buffer) ==
+ SbDrmSystemPrivate::kRetry) {
+ *written = false;
+ return true;
+ }
+ }
+ audio_renderer_->WriteSample(*data.input_buffer);
+ }
+ } else {
+ SB_DCHECK(data.sample_type == kSbMediaTypeVideo);
+ if (video_renderer_->IsEndOfStreamWritten()) {
+ SB_LOG(WARNING) << "Try to write video sample after EOS is reached";
+ } else {
+ if (!video_renderer_->CanAcceptMoreData()) {
+ *written = false;
+ return true;
+ }
+ if (data.input_buffer->drm_info()) {
+ if (!SbDrmSystemIsValid(drm_system_)) {
+ return false;
+ }
+ if (drm_system_->Decrypt(data.input_buffer) ==
+ SbDrmSystemPrivate::kRetry) {
+ *written = false;
+ return true;
+ }
+ }
+ video_renderer_->WriteSample(*data.input_buffer);
+ }
+ }
+
+ return true;
+}
+
+bool FilterBasedPlayerWorkerHandler::ProcessWriteEndOfStreamEvent(
+ const WriteEndOfStreamEventData& data) {
+ if (data.stream_type == kSbMediaTypeAudio) {
+ if (audio_renderer_->IsEndOfStreamWritten()) {
+ SB_LOG(WARNING) << "Try to write audio EOS after EOS is enqueued";
+ } else {
+ SB_LOG(INFO) << "Audio EOS enqueued";
+ audio_renderer_->WriteEndOfStream();
+ }
+ } else {
+ if (video_renderer_->IsEndOfStreamWritten()) {
+ SB_LOG(WARNING) << "Try to write video EOS after EOS is enqueued";
+ } else {
+ SB_LOG(INFO) << "Video EOS enqueued";
+ video_renderer_->WriteEndOfStream();
+ }
+ }
+
+ return true;
+}
+
+bool FilterBasedPlayerWorkerHandler::ProcessSetPauseEvent(
+ const SetPauseEventData& data) {
+ paused_ = data.pause;
+
+ if (data.pause) {
+ audio_renderer_->Pause();
+ SB_DLOG(INFO) << "Playback paused.";
+ } else {
+ audio_renderer_->Play();
+ SB_DLOG(INFO) << "Playback started.";
+ }
+
+ return true;
+}
+
+bool FilterBasedPlayerWorkerHandler::ProcessUpdateEvent(
+ const SetBoundsEventData& data) {
+ if ((*player_worker_.*get_player_state_cb_)() == kSbPlayerStatePrerolling) {
+ if (!audio_renderer_->IsSeekingInProgress() &&
+ !video_renderer_->IsSeekingInProgress()) {
+ (*player_worker_.*update_player_state_cb_)(kSbPlayerStatePresenting);
+ if (!paused_) {
+ audio_renderer_->Play();
+ }
+ }
+ }
+
+ if ((*player_worker_.*get_player_state_cb_)() == kSbPlayerStatePresenting) {
+ if (audio_renderer_->IsEndOfStreamPlayed() &&
+ video_renderer_->IsEndOfStreamPlayed()) {
+ (*player_worker_.*update_player_state_cb_)(kSbPlayerStateEndOfStream);
+ }
+
+ const VideoFrame& frame =
+ video_renderer_->GetCurrentFrame(audio_renderer_->GetCurrentTime());
+
+#if SB_IS(PLAYER_PUNCHED_OUT)
+ shared::starboard::Application::Get()->HandleFrame(
+ player_, frame, data.x, data.y, data.width, data.height);
+#endif // SB_IS(PLAYER_PUNCHED_OUT)
+
+ (*player_worker_.*update_media_time_cb_)(audio_renderer_->GetCurrentTime());
+ }
+
+ return true;
+}
+
+void FilterBasedPlayerWorkerHandler::ProcessStopEvent() {
+ audio_renderer_.reset();
+ video_renderer_.reset();
+
+#if SB_IS(PLAYER_PUNCHED_OUT)
+ // Clear the video frame as we terminate.
+ shared::starboard::Application::Get()->HandleFrame(player_, VideoFrame(), 0,
+ 0, 0, 0);
+#endif // SB_IS(PLAYER_PUNCHED_OUT)
+}
+
+} // namespace filter
+} // namespace player
+} // namespace starboard
+} // namespace shared
+} // namespace starboard
diff --git a/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h
new file mode 100644
index 0000000..cde0391
--- /dev/null
+++ b/src/starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h
@@ -0,0 +1,80 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_FILTER_BASED_PLAYER_WORKER_HANDLER_H_
+#define STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_FILTER_BASED_PLAYER_WORKER_HANDLER_H_
+
+#include "starboard/common/scoped_ptr.h"
+#include "starboard/configuration.h"
+#include "starboard/media.h"
+#include "starboard/player.h"
+#include "starboard/shared/starboard/player/filter/audio_renderer_internal.h"
+#include "starboard/shared/starboard/player/filter/video_renderer_internal.h"
+#include "starboard/shared/starboard/player/input_buffer_internal.h"
+#include "starboard/shared/starboard/player/player_worker.h"
+#include "starboard/time.h"
+
+namespace starboard {
+namespace shared {
+namespace starboard {
+namespace player {
+namespace filter {
+
+class FilterBasedPlayerWorkerHandler : public PlayerWorker::Handler {
+ public:
+ FilterBasedPlayerWorkerHandler(SbMediaVideoCodec video_codec,
+ SbMediaAudioCodec audio_codec,
+ SbDrmSystem drm_system,
+ const SbMediaAudioHeader& audio_header);
+
+ private:
+ void Setup(PlayerWorker* player_worker,
+ SbPlayer player,
+ UpdateMediaTimeCB update_media_time_cb,
+ GetPlayerStateCB get_player_state_cb,
+ UpdatePlayerStateCB update_player_state_cb) SB_OVERRIDE;
+ bool ProcessInitEvent() SB_OVERRIDE;
+ bool ProcessSeekEvent(const SeekEventData& data) SB_OVERRIDE;
+ bool ProcessWriteSampleEvent(const WriteSampleEventData& data,
+ bool* written) SB_OVERRIDE;
+ bool ProcessWriteEndOfStreamEvent(const WriteEndOfStreamEventData& data)
+ SB_OVERRIDE;
+ bool ProcessSetPauseEvent(const SetPauseEventData& data) SB_OVERRIDE;
+ bool ProcessUpdateEvent(const SetBoundsEventData& data) SB_OVERRIDE;
+ void ProcessStopEvent() SB_OVERRIDE;
+
+ PlayerWorker* player_worker_;
+ SbPlayer player_;
+ UpdateMediaTimeCB update_media_time_cb_;
+ GetPlayerStateCB get_player_state_cb_;
+ UpdatePlayerStateCB update_player_state_cb_;
+
+ SbMediaVideoCodec video_codec_;
+ SbMediaAudioCodec audio_codec_;
+ SbDrmSystem drm_system_;
+ SbMediaAudioHeader audio_header_;
+
+ scoped_ptr<AudioRenderer> audio_renderer_;
+ scoped_ptr<VideoRenderer> video_renderer_;
+
+ bool paused_;
+};
+
+} // namespace filter
+} // namespace player
+} // namespace starboard
+} // namespace shared
+} // namespace starboard
+
+#endif // STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_FILTER_BASED_PLAYER_WORKER_HANDLER_H_
diff --git a/src/starboard/shared/starboard/player/video_decoder_internal.h b/src/starboard/shared/starboard/player/filter/video_decoder_internal.h
similarity index 90%
rename from src/starboard/shared/starboard/player/video_decoder_internal.h
rename to src/starboard/shared/starboard/player/filter/video_decoder_internal.h
index 444f049..fd32c9f 100644
--- a/src/starboard/shared/starboard/player/video_decoder_internal.h
+++ b/src/starboard/shared/starboard/player/filter/video_decoder_internal.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_DECODER_INTERNAL_H_
-#define STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_DECODER_INTERNAL_H_
+#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_VIDEO_DECODER_INTERNAL_H_
+#define STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_VIDEO_DECODER_INTERNAL_H_
#include "starboard/shared/internal_only.h"
#include "starboard/shared/starboard/player/input_buffer_internal.h"
@@ -23,6 +23,7 @@
namespace shared {
namespace starboard {
namespace player {
+namespace filter {
// This class decodes encoded video stream into video frames.
class VideoDecoder {
@@ -64,9 +65,10 @@
static VideoDecoder* Create(SbMediaVideoCodec video_codec);
};
+} // namespace filter
} // namespace player
} // namespace starboard
} // namespace shared
} // namespace starboard
-#endif // STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_DECODER_INTERNAL_H_
+#endif // STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_VIDEO_DECODER_INTERNAL_H_
diff --git a/src/starboard/shared/starboard/player/video_renderer_internal.cc b/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
similarity index 93%
rename from src/starboard/shared/starboard/player/video_renderer_internal.cc
rename to src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
index d3faa9f..3898af5 100644
--- a/src/starboard/shared/starboard/player/video_renderer_internal.cc
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_internal.cc
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "starboard/shared/starboard/player/video_renderer_internal.h"
+#include "starboard/shared/starboard/player/filter/video_renderer_internal.h"
#include <algorithm>
@@ -20,21 +20,18 @@
namespace shared {
namespace starboard {
namespace player {
+namespace filter {
-VideoRenderer::VideoRenderer(VideoDecoder* decoder)
+VideoRenderer::VideoRenderer(scoped_ptr<VideoDecoder> decoder)
: seeking_(false),
seeking_to_pts_(0),
end_of_stream_written_(false),
need_more_input_(true),
- decoder_(decoder) {
+ decoder_(decoder.Pass()) {
SB_DCHECK(decoder_ != NULL);
decoder_->SetHost(this);
}
-VideoRenderer::~VideoRenderer() {
- delete decoder_;
-}
-
void VideoRenderer::WriteSample(const InputBuffer& input_buffer) {
ScopedLock lock(mutex_);
@@ -132,6 +129,7 @@
need_more_input_ = (status == VideoDecoder::kNeedMoreInput);
}
+} // namespace filter
} // namespace player
} // namespace starboard
} // namespace shared
diff --git a/src/starboard/shared/starboard/player/video_renderer_internal.h b/src/starboard/shared/starboard/player/filter/video_renderer_internal.h
similarity index 84%
rename from src/starboard/shared/starboard/player/video_renderer_internal.h
rename to src/starboard/shared/starboard/player/filter/video_renderer_internal.h
index 0cf815a..43f899b 100644
--- a/src/starboard/shared/starboard/player/video_renderer_internal.h
+++ b/src/starboard/shared/starboard/player/filter/video_renderer_internal.h
@@ -12,28 +12,29 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_RENDERER_INTERNAL_H_
-#define STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_RENDERER_INTERNAL_H_
+#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_VIDEO_RENDERER_INTERNAL_H_
+#define STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_VIDEO_RENDERER_INTERNAL_H_
#include <list>
+#include "starboard/common/scoped_ptr.h"
#include "starboard/log.h"
#include "starboard/media.h"
#include "starboard/mutex.h"
#include "starboard/shared/internal_only.h"
+#include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
#include "starboard/shared/starboard/player/input_buffer_internal.h"
-#include "starboard/shared/starboard/player/video_decoder_internal.h"
#include "starboard/shared/starboard/player/video_frame_internal.h"
namespace starboard {
namespace shared {
namespace starboard {
namespace player {
+namespace filter {
class VideoRenderer : private VideoDecoder::Host {
public:
- explicit VideoRenderer(VideoDecoder* decoder);
- ~VideoRenderer();
+ explicit VideoRenderer(scoped_ptr<VideoDecoder> decoder);
bool is_valid() const { return true; }
@@ -80,12 +81,13 @@
bool end_of_stream_written_;
bool need_more_input_;
- VideoDecoder* decoder_;
+ scoped_ptr<VideoDecoder> decoder_;
};
+} // namespace filter
} // namespace player
} // namespace starboard
} // namespace shared
} // namespace starboard
-#endif // STARBOARD_SHARED_STARBOARD_PLAYER_VIDEO_RENDERER_INTERNAL_H_
+#endif // STARBOARD_SHARED_STARBOARD_PLAYER_FILTER_VIDEO_RENDERER_INTERNAL_H_
diff --git a/src/starboard/shared/starboard/player/player_create.cc b/src/starboard/shared/starboard/player/player_create.cc
index 8489cce..5581ca8 100644
--- a/src/starboard/shared/starboard/player/player_create.cc
+++ b/src/starboard/shared/starboard/player/player_create.cc
@@ -14,8 +14,15 @@
#include "starboard/player.h"
+#include "starboard/configuration.h"
#include "starboard/log.h"
+#include "starboard/shared/starboard/player/filter/filter_based_player_worker_handler.h"
#include "starboard/shared/starboard/player/player_internal.h"
+#include "starboard/shared/starboard/player/player_worker.h"
+
+using starboard::shared::starboard::player::filter::
+ FilterBasedPlayerWorkerHandler;
+using starboard::shared::starboard::player::PlayerWorker;
SbPlayer SbPlayerCreate(SbWindow window,
SbMediaVideoCodec video_codec,
@@ -27,6 +34,8 @@
SbPlayerDecoderStatusFunc decoder_status_func,
SbPlayerStatusFunc player_status_func,
void* context) {
+ SB_UNREFERENCED_PARAMETER(window);
+
if (audio_codec != kSbMediaAudioCodecAac) {
SB_LOG(ERROR) << "Unsupported audio codec " << audio_codec;
return kSbPlayerInvalid;
@@ -42,7 +51,10 @@
return kSbPlayerInvalid;
}
- return new SbPlayerPrivate(window, video_codec, audio_codec, duration_pts,
- drm_system, audio_header, sample_deallocate_func,
- decoder_status_func, player_status_func, context);
+ starboard::scoped_ptr<PlayerWorker::Handler> handler(
+ new FilterBasedPlayerWorkerHandler(video_codec, audio_codec, drm_system,
+ *audio_header));
+ return new SbPlayerPrivate(duration_pts, sample_deallocate_func,
+ decoder_status_func, player_status_func, context,
+ handler.Pass());
}
diff --git a/src/starboard/shared/starboard/player/player_internal.cc b/src/starboard/shared/starboard/player/player_internal.cc
index 0443b2f..bc9d74d 100644
--- a/src/starboard/shared/starboard/player/player_internal.cc
+++ b/src/starboard/shared/starboard/player/player_internal.cc
@@ -17,10 +17,11 @@
#include "starboard/log.h"
using starboard::shared::starboard::player::InputBuffer;
-using starboard::shared::starboard::player::PlayerWorker;
namespace {
+const SbTime kUpdateInterval = 5 * kSbTimeMillisecond;
+
SbMediaTime GetMediaTime(SbMediaTime media_pts,
SbTimeMonotonic media_pts_update_time) {
SbTimeMonotonic elapsed = SbTimeGetMonotonicNow() - media_pts_update_time;
@@ -30,16 +31,12 @@
} // namespace
SbPlayerPrivate::SbPlayerPrivate(
- SbWindow window,
- SbMediaVideoCodec video_codec,
- SbMediaAudioCodec audio_codec,
SbMediaTime duration_pts,
- SbDrmSystem drm_system,
- const SbMediaAudioHeader* audio_header,
SbPlayerDeallocateSampleFunc sample_deallocate_func,
SbPlayerDecoderStatusFunc decoder_status_func,
SbPlayerStatusFunc player_status_func,
- void* context)
+ void* context,
+ starboard::scoped_ptr<PlayerWorker::Handler> player_worker_handler)
: sample_deallocate_func_(sample_deallocate_func),
context_(context),
ticket_(SB_PLAYER_INITIAL_TICKET),
@@ -51,16 +48,13 @@
is_paused_(true),
volume_(1.0),
total_video_frames_(0),
- worker_(this,
- window,
- video_codec,
- audio_codec,
- drm_system,
- *audio_header,
- decoder_status_func,
- player_status_func,
- this,
- context) {}
+ worker_(new PlayerWorker(this,
+ player_worker_handler.Pass(),
+ decoder_status_func,
+ player_status_func,
+ this,
+ kUpdateInterval,
+ context)) {}
void SbPlayerPrivate::Seek(SbMediaTime seek_to_pts, int ticket) {
{
@@ -72,7 +66,7 @@
}
PlayerWorker::SeekEventData data = {seek_to_pts, ticket};
- worker_.EnqueueEvent(data);
+ worker_->EnqueueEvent(data);
}
void SbPlayerPrivate::WriteSample(
@@ -89,18 +83,18 @@
sample_deallocate_func_, this, context_, sample_buffer,
sample_buffer_size, sample_pts, video_sample_info, sample_drm_info);
PlayerWorker::WriteSampleEventData data = {sample_type, input_buffer};
- worker_.EnqueueEvent(data);
+ worker_->EnqueueEvent(data);
}
void SbPlayerPrivate::WriteEndOfStream(SbMediaType stream_type) {
PlayerWorker::WriteEndOfStreamEventData data = {stream_type};
- worker_.EnqueueEvent(data);
+ worker_->EnqueueEvent(data);
}
#if SB_IS(PLAYER_PUNCHED_OUT)
void SbPlayerPrivate::SetBounds(int x, int y, int width, int height) {
PlayerWorker::SetBoundsEventData data = {x, y, width, height};
- worker_.EnqueueEvent(data);
+ worker_->EnqueueEvent(data);
// TODO: Wait until a frame is rendered with the updated bounds.
}
#endif
@@ -127,7 +121,7 @@
void SbPlayerPrivate::SetPause(bool pause) {
PlayerWorker::SetPauseEventData data = {pause};
- worker_.EnqueueEvent(data);
+ worker_->EnqueueEvent(data);
}
void SbPlayerPrivate::SetVolume(double volume) {
diff --git a/src/starboard/shared/starboard/player/player_internal.h b/src/starboard/shared/starboard/player/player_internal.h
index 7ecc299..4a8a917 100644
--- a/src/starboard/shared/starboard/player/player_internal.h
+++ b/src/starboard/shared/starboard/player/player_internal.h
@@ -15,6 +15,7 @@
#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_PLAYER_INTERNAL_H_
#define STARBOARD_SHARED_STARBOARD_PLAYER_PLAYER_INTERNAL_H_
+#include "starboard/common/scoped_ptr.h"
#include "starboard/media.h"
#include "starboard/player.h"
#include "starboard/shared/internal_only.h"
@@ -22,20 +23,18 @@
#include "starboard/time.h"
#include "starboard/window.h"
-// TODO: Implement DRM support
struct SbPlayerPrivate
: starboard::shared::starboard::player::PlayerWorker::Host {
public:
- SbPlayerPrivate(SbWindow window,
- SbMediaVideoCodec video_codec,
- SbMediaAudioCodec audio_codec,
- SbMediaTime duration_pts,
- SbDrmSystem drm_system,
- const SbMediaAudioHeader* audio_header,
- SbPlayerDeallocateSampleFunc sample_deallocate_func,
- SbPlayerDecoderStatusFunc decoder_status_func,
- SbPlayerStatusFunc player_status_func,
- void* context);
+ typedef starboard::shared::starboard::player::PlayerWorker PlayerWorker;
+
+ SbPlayerPrivate(
+ SbMediaTime duration_pts,
+ SbPlayerDeallocateSampleFunc sample_deallocate_func,
+ SbPlayerDecoderStatusFunc decoder_status_func,
+ SbPlayerStatusFunc player_status_func,
+ void* context,
+ starboard::scoped_ptr<PlayerWorker::Handler> player_worker_handler);
void Seek(SbMediaTime seek_to_pts, int ticket);
void WriteSample(SbMediaType sample_type,
@@ -71,7 +70,7 @@
double volume_;
int total_video_frames_;
- starboard::shared::starboard::player::PlayerWorker worker_;
+ starboard::scoped_ptr<PlayerWorker> worker_;
};
#endif // STARBOARD_SHARED_STARBOARD_PLAYER_PLAYER_INTERNAL_H_
diff --git a/src/starboard/shared/starboard/player/player_worker.cc b/src/starboard/shared/starboard/player/player_worker.cc
index ddb425f..51c869d 100644
--- a/src/starboard/shared/starboard/player/player_worker.cc
+++ b/src/starboard/shared/starboard/player/player_worker.cc
@@ -14,15 +14,8 @@
#include "starboard/shared/starboard/player/player_worker.h"
-#include <algorithm>
-
+#include "starboard/common/reset_and_return.h"
#include "starboard/memory.h"
-#include "starboard/shared/starboard/application.h"
-#include "starboard/shared/starboard/drm/drm_system_internal.h"
-#include "starboard/shared/starboard/player/audio_decoder_internal.h"
-#include "starboard/shared/starboard/player/input_buffer_internal.h"
-#include "starboard/shared/starboard/player/video_decoder_internal.h"
-#include "starboard/shared/starboard/player/video_frame_internal.h"
namespace starboard {
namespace shared {
@@ -30,34 +23,34 @@
namespace player {
PlayerWorker::PlayerWorker(Host* host,
- SbWindow window,
- SbMediaVideoCodec video_codec,
- SbMediaAudioCodec audio_codec,
- SbDrmSystem drm_system,
- const SbMediaAudioHeader& audio_header,
+ scoped_ptr<Handler> handler,
SbPlayerDecoderStatusFunc decoder_status_func,
SbPlayerStatusFunc player_status_func,
SbPlayer player,
+ SbTime update_interval,
void* context)
- : host_(host),
- window_(window),
- video_codec_(video_codec),
- audio_codec_(audio_codec),
- drm_system_(drm_system),
- audio_header_(audio_header),
+ : thread_(kSbThreadInvalid),
+ host_(host),
+ handler_(handler.Pass()),
decoder_status_func_(decoder_status_func),
player_status_func_(player_status_func),
player_(player),
context_(context),
- audio_renderer_(NULL),
- video_renderer_(NULL),
- audio_decoder_state_(kSbPlayerDecoderStateBufferFull),
- video_decoder_state_(kSbPlayerDecoderStateBufferFull),
ticket_(SB_PLAYER_INITIAL_TICKET),
- paused_(true),
- player_state_(kSbPlayerStateInitialized) {
- SB_DCHECK(host != NULL);
+ player_state_(kSbPlayerStateInitialized),
+ update_interval_(update_interval) {
+ SB_DCHECK(host_ != NULL);
+ SB_DCHECK(handler_ != NULL);
+ SB_DCHECK(update_interval_ > 0);
+ handler_->Setup(this, player_, &PlayerWorker::UpdateMediaTime,
+ &PlayerWorker::player_state,
+ &PlayerWorker::UpdatePlayerState);
+
+ pending_audio_sample_.input_buffer = NULL;
+ pending_video_sample_.input_buffer = NULL;
+
+ SB_DCHECK(!SbThreadIsValid(thread_));
thread_ =
SbThreadCreate(0, kSbThreadPriorityHigh, kSbThreadNoAffinity, true,
"player_worker", &PlayerWorker::ThreadEntryPoint, this);
@@ -69,9 +62,41 @@
PlayerWorker::~PlayerWorker() {
queue_.Put(new Event(Event::kStop));
SbThreadJoin(thread_, NULL);
+ thread_ = kSbThreadInvalid;
+
// Now the whole pipeline has been torn down and no callback will be called.
// The caller can ensure that upon the return of SbPlayerDestroy() all side
// effects are gone.
+
+ // There can be events inside the queue that is not processed. Clean them up.
+ while (Event* event = queue_.GetTimed(0)) {
+ if (event->type == Event::kWriteSample) {
+ delete event->data.write_sample.input_buffer;
+ }
+ delete event;
+ }
+
+ if (pending_audio_sample_.input_buffer != NULL) {
+ delete pending_audio_sample_.input_buffer;
+ }
+
+ if (pending_video_sample_.input_buffer != NULL) {
+ delete pending_video_sample_.input_buffer;
+ }
+}
+
+void PlayerWorker::UpdateMediaTime(SbMediaTime time) {
+ host_->UpdateMediaTime(time, ticket_);
+}
+
+void PlayerWorker::UpdatePlayerState(SbPlayerState player_state) {
+ player_state_ = player_state;
+
+ if (!player_status_func_) {
+ return;
+ }
+
+ player_status_func_(player_, context_, player_state_, ticket_);
}
// static
@@ -86,41 +111,35 @@
SB_DCHECK(event != NULL);
SB_DCHECK(event->type == Event::kInit);
delete event;
- bool running = ProcessInitEvent();
+ bool running = DoInit();
SetBoundsEventData bounds = {0, 0, 0, 0};
while (running) {
- Event* event = queue_.GetTimed(kUpdateInterval);
+ Event* event = queue_.GetTimed(update_interval_);
if (event == NULL) {
- running &= ProcessUpdateEvent(bounds);
+ running &= DoUpdate(bounds);
continue;
}
SB_DCHECK(event->type != Event::kInit);
if (event->type == Event::kSeek) {
- running &= ProcessSeekEvent(event->data.seek);
+ running &= DoSeek(event->data.seek);
} else if (event->type == Event::kWriteSample) {
- bool retry;
- running &= ProcessWriteSampleEvent(event->data.write_sample, &retry);
- if (retry && running) {
- EnqueueEvent(event->data.write_sample);
- } else {
- delete event->data.write_sample.input_buffer;
- }
+ running &= DoWriteSample(event->data.write_sample);
} else if (event->type == Event::kWriteEndOfStream) {
- running &= ProcessWriteEndOfStreamEvent(event->data.write_end_of_stream);
+ running &= DoWriteEndOfStream(event->data.write_end_of_stream);
} else if (event->type == Event::kSetPause) {
- running &= ProcessSetPauseEvent(event->data.set_pause);
+ running &= handler_->ProcessSetPauseEvent(event->data.set_pause);
} else if (event->type == Event::kSetBounds) {
if (SbMemoryCompare(&bounds, &event->data.set_bounds, sizeof(bounds)) !=
0) {
bounds = event->data.set_bounds;
- ProcessUpdateEvent(bounds);
+ running &= DoUpdate(bounds);
}
} else if (event->type == Event::kStop) {
- ProcessStopEvent();
+ DoStop();
running = false;
} else {
SB_NOTREACHED() << "event type " << event->type;
@@ -129,34 +148,17 @@
}
}
-bool PlayerWorker::ProcessInitEvent() {
- AudioDecoder* audio_decoder =
- AudioDecoder::Create(audio_codec_, audio_header_);
- VideoDecoder* video_decoder = VideoDecoder::Create(video_codec_);
-
- if (!audio_decoder || !video_decoder) {
- delete audio_decoder;
- delete video_decoder;
- UpdatePlayerState(kSbPlayerStateError);
- return false;
- }
-
- audio_renderer_ = new AudioRenderer(audio_decoder, audio_header_);
- video_renderer_ = new VideoRenderer(video_decoder);
- if (audio_renderer_->is_valid() && video_renderer_->is_valid()) {
+bool PlayerWorker::DoInit() {
+ if (handler_->ProcessInitEvent()) {
UpdatePlayerState(kSbPlayerStateInitialized);
return true;
}
- delete audio_renderer_;
- audio_renderer_ = NULL;
- delete video_renderer_;
- video_renderer_ = NULL;
UpdatePlayerState(kSbPlayerStateError);
return false;
}
-bool PlayerWorker::ProcessSeekEvent(const SeekEventData& data) {
+bool PlayerWorker::DoSeek(const SeekEventData& data) {
SB_DCHECK(player_state_ != kSbPlayerStateDestroyed);
SB_DCHECK(player_state_ != kSbPlayerStateError);
SB_DCHECK(ticket_ != data.ticket);
@@ -164,106 +166,66 @@
SB_DLOG(INFO) << "Try to seek to timestamp "
<< data.seek_to_pts / kSbMediaTimeSecond;
- SbMediaTime seek_to_pts = data.seek_to_pts;
- if (seek_to_pts < 0) {
- SB_DLOG(ERROR) << "Try to seek to negative timestamp " << seek_to_pts;
- seek_to_pts = 0;
+ if (pending_audio_sample_.input_buffer != NULL) {
+ delete pending_audio_sample_.input_buffer;
+ pending_audio_sample_.input_buffer = NULL;
+ }
+ if (pending_video_sample_.input_buffer != NULL) {
+ delete pending_video_sample_.input_buffer;
+ pending_video_sample_.input_buffer = NULL;
}
- audio_renderer_->Pause();
- audio_decoder_state_ = kSbPlayerDecoderStateNeedsData;
- video_decoder_state_ = kSbPlayerDecoderStateNeedsData;
- audio_renderer_->Seek(seek_to_pts);
- video_renderer_->Seek(seek_to_pts);
+ if (!handler_->ProcessSeekEvent(data)) {
+ return false;
+ }
ticket_ = data.ticket;
UpdatePlayerState(kSbPlayerStatePrerolling);
- UpdateDecoderState(kSbMediaTypeAudio);
- UpdateDecoderState(kSbMediaTypeVideo);
+ UpdateDecoderState(kSbMediaTypeAudio, kSbPlayerDecoderStateNeedsData);
+ UpdateDecoderState(kSbMediaTypeVideo, kSbPlayerDecoderStateNeedsData);
+
return true;
}
-bool PlayerWorker::ProcessWriteSampleEvent(const WriteSampleEventData& data,
- bool* retry) {
- SB_DCHECK(retry != NULL);
+bool PlayerWorker::DoWriteSample(const WriteSampleEventData& data) {
SB_DCHECK(player_state_ != kSbPlayerStateDestroyed);
SB_DCHECK(player_state_ != kSbPlayerStateError);
- *retry = false;
-
if (player_state_ == kSbPlayerStateInitialized ||
player_state_ == kSbPlayerStateEndOfStream ||
player_state_ == kSbPlayerStateError) {
SB_LOG(ERROR) << "Try to write sample when |player_state_| is "
<< player_state_;
+ delete data.input_buffer;
// Return true so the pipeline will continue running with the particular
// call ignored.
return true;
}
if (data.sample_type == kSbMediaTypeAudio) {
- if (audio_renderer_->IsEndOfStreamWritten()) {
- SB_LOG(WARNING) << "Try to write audio sample after EOS is reached";
+ SB_DCHECK(pending_audio_sample_.input_buffer == NULL);
+ } else {
+ SB_DCHECK(pending_video_sample_.input_buffer == NULL);
+ }
+ bool written;
+ bool result = handler_->ProcessWriteSampleEvent(data, &written);
+ if (!written && result) {
+ if (data.sample_type == kSbMediaTypeAudio) {
+ pending_audio_sample_ = data;
} else {
- SB_DCHECK(audio_renderer_->CanAcceptMoreData());
-
- if (data.input_buffer->drm_info()) {
- if (!SbDrmSystemIsValid(drm_system_)) {
- return false;
- }
- if (drm_system_->Decrypt(data.input_buffer) ==
- SbDrmSystemPrivate::kRetry) {
- *retry = true;
- return true;
- }
- }
- audio_renderer_->WriteSample(*data.input_buffer);
- if (audio_renderer_->CanAcceptMoreData()) {
- audio_decoder_state_ = kSbPlayerDecoderStateNeedsData;
- } else {
- audio_decoder_state_ = kSbPlayerDecoderStateBufferFull;
- }
- UpdateDecoderState(kSbMediaTypeAudio);
+ pending_video_sample_ = data;
}
} else {
- SB_DCHECK(data.sample_type == kSbMediaTypeVideo);
- if (video_renderer_->IsEndOfStreamWritten()) {
- SB_LOG(WARNING) << "Try to write video sample after EOS is reached";
- } else {
- SB_DCHECK(video_renderer_->CanAcceptMoreData());
- if (data.input_buffer->drm_info()) {
- if (!SbDrmSystemIsValid(drm_system_)) {
- return false;
- }
- if (drm_system_->Decrypt(data.input_buffer) ==
- SbDrmSystemPrivate::kRetry) {
- *retry = true;
- return true;
- }
- }
- video_renderer_->WriteSample(*data.input_buffer);
- if (video_renderer_->CanAcceptMoreData()) {
- video_decoder_state_ = kSbPlayerDecoderStateNeedsData;
- } else {
- video_decoder_state_ = kSbPlayerDecoderStateBufferFull;
- }
- UpdateDecoderState(kSbMediaTypeVideo);
+ delete data.input_buffer;
+ if (result) {
+ UpdateDecoderState(data.sample_type, kSbPlayerDecoderStateNeedsData);
}
}
-
- if (player_state_ == kSbPlayerStatePrerolling) {
- if (!audio_renderer_->IsSeekingInProgress() &&
- !video_renderer_->IsSeekingInProgress()) {
- UpdatePlayerState(kSbPlayerStatePresenting);
- }
- }
-
- return true;
+ return result;
}
-bool PlayerWorker::ProcessWriteEndOfStreamEvent(
- const WriteEndOfStreamEventData& data) {
+bool PlayerWorker::DoWriteEndOfStream(const WriteEndOfStreamEventData& data) {
SB_DCHECK(player_state_ != kSbPlayerStateDestroyed);
if (player_state_ == kSbPlayerStateInitialized ||
@@ -277,124 +239,47 @@
}
if (data.stream_type == kSbMediaTypeAudio) {
- if (audio_renderer_->IsEndOfStreamWritten()) {
- SB_LOG(WARNING) << "Try to write audio EOS after EOS is enqueued";
- } else {
- SB_LOG(INFO) << "Audio EOS enqueued";
- audio_renderer_->WriteEndOfStream();
- }
- audio_decoder_state_ = kSbPlayerDecoderStateBufferFull;
- UpdateDecoderState(kSbMediaTypeAudio);
+ SB_DCHECK(pending_audio_sample_.input_buffer == NULL);
} else {
- if (video_renderer_->IsEndOfStreamWritten()) {
- SB_LOG(WARNING) << "Try to write video EOS after EOS is enqueued";
- } else {
- SB_LOG(INFO) << "Video EOS enqueued";
- video_renderer_->WriteEndOfStream();
- }
- video_decoder_state_ = kSbPlayerDecoderStateBufferFull;
- UpdateDecoderState(kSbMediaTypeVideo);
+ SB_DCHECK(pending_video_sample_.input_buffer == NULL);
}
- if (player_state_ == kSbPlayerStatePrerolling) {
- if (!audio_renderer_->IsSeekingInProgress() &&
- !video_renderer_->IsSeekingInProgress()) {
- UpdatePlayerState(kSbPlayerStatePresenting);
- }
- }
-
- if (player_state_ == kSbPlayerStatePresenting) {
- if (audio_renderer_->IsEndOfStreamPlayed() &&
- video_renderer_->IsEndOfStreamPlayed()) {
- UpdatePlayerState(kSbPlayerStateEndOfStream);
- }
+ if (!handler_->ProcessWriteEndOfStreamEvent(data)) {
+ return false;
}
return true;
}
-bool PlayerWorker::ProcessSetPauseEvent(const SetPauseEventData& data) {
- // TODO: Check valid
- paused_ = data.pause;
- if (data.pause) {
- audio_renderer_->Pause();
- SB_DLOG(INFO) << "Playback paused.";
- } else {
- audio_renderer_->Play();
- SB_DLOG(INFO) << "Playback started.";
+bool PlayerWorker::DoUpdate(const SetBoundsEventData& data) {
+ if (pending_audio_sample_.input_buffer != NULL) {
+ if (!DoWriteSample(common::ResetAndReturn(&pending_audio_sample_))) {
+ return false;
+ }
}
-
- return true;
+ if (pending_video_sample_.input_buffer != NULL) {
+ if (!DoWriteSample(common::ResetAndReturn(&pending_video_sample_))) {
+ return false;
+ }
+ }
+ return handler_->ProcessUpdateEvent(data);
}
-bool PlayerWorker::ProcessUpdateEvent(const SetBoundsEventData& bounds) {
- SB_DCHECK(player_state_ != kSbPlayerStateDestroyed);
+void PlayerWorker::DoStop() {
+ handler_->ProcessStopEvent();
- if (player_state_ == kSbPlayerStatePrerolling ||
- player_state_ == kSbPlayerStatePresenting) {
- if (audio_renderer_->IsEndOfStreamPlayed() &&
- video_renderer_->IsEndOfStreamPlayed()) {
- UpdatePlayerState(kSbPlayerStateEndOfStream);
- }
-
- const VideoFrame& frame =
- video_renderer_->GetCurrentFrame(audio_renderer_->GetCurrentTime());
-#if SB_IS(PLAYER_PUNCHED_OUT)
- shared::starboard::Application::Get()->HandleFrame(
- player_, frame, bounds.x, bounds.y, bounds.width, bounds.height);
-#endif // SB_IS(PLAYER_PUNCHED_OUT)
-
- if (audio_decoder_state_ == kSbPlayerDecoderStateBufferFull &&
- audio_renderer_->CanAcceptMoreData()) {
- audio_decoder_state_ = kSbPlayerDecoderStateNeedsData;
- UpdateDecoderState(kSbMediaTypeAudio);
- }
- if (video_decoder_state_ == kSbPlayerDecoderStateBufferFull &&
- video_renderer_->CanAcceptMoreData()) {
- video_decoder_state_ = kSbPlayerDecoderStateNeedsData;
- UpdateDecoderState(kSbMediaTypeVideo);
- }
-
- host_->UpdateMediaTime(audio_renderer_->GetCurrentTime(), ticket_);
- }
-
- return true;
-}
-
-void PlayerWorker::ProcessStopEvent() {
- delete audio_renderer_;
- audio_renderer_ = NULL;
- delete video_renderer_;
- video_renderer_ = NULL;
-#if SB_IS(PLAYER_PUNCHED_OUT)
- // Clear the video frame as we terminate.
- shared::starboard::Application::Get()->HandleFrame(player_, VideoFrame(), 0,
- 0, 0, 0);
-#endif // SB_IS(PLAYER_PUNCHED_OUT)
UpdatePlayerState(kSbPlayerStateDestroyed);
}
-void PlayerWorker::UpdateDecoderState(SbMediaType type) {
+void PlayerWorker::UpdateDecoderState(SbMediaType type,
+ SbPlayerDecoderState state) {
+ SB_DCHECK(type == kSbMediaTypeAudio || type == kSbMediaTypeVideo);
+
if (!decoder_status_func_) {
return;
}
- SB_DCHECK(type == kSbMediaTypeAudio || type == kSbMediaTypeVideo);
- decoder_status_func_(
- player_, context_, type,
- type == kSbMediaTypeAudio ? audio_decoder_state_ : video_decoder_state_,
- ticket_);
-}
-void PlayerWorker::UpdatePlayerState(SbPlayerState player_state) {
- if (!player_status_func_) {
- return;
- }
-
- player_state_ = player_state;
- if (player_state == kSbPlayerStatePresenting && !paused_) {
- audio_renderer_->Play();
- }
- player_status_func_(player_, context_, player_state_, ticket_);
+ decoder_status_func_(player_, context_, type, state, ticket_);
}
} // namespace player
diff --git a/src/starboard/shared/starboard/player/player_worker.h b/src/starboard/shared/starboard/player/player_worker.h
index 843806f..d8bbb70 100644
--- a/src/starboard/shared/starboard/player/player_worker.h
+++ b/src/starboard/shared/starboard/player/player_worker.h
@@ -15,13 +15,13 @@
#ifndef STARBOARD_SHARED_STARBOARD_PLAYER_PLAYER_WORKER_H_
#define STARBOARD_SHARED_STARBOARD_PLAYER_PLAYER_WORKER_H_
+#include "starboard/common/scoped_ptr.h"
#include "starboard/log.h"
#include "starboard/media.h"
#include "starboard/player.h"
#include "starboard/queue.h"
#include "starboard/shared/internal_only.h"
-#include "starboard/shared/starboard/player/audio_renderer_internal.h"
-#include "starboard/shared/starboard/player/video_renderer_internal.h"
+#include "starboard/shared/starboard/player/input_buffer_internal.h"
#include "starboard/thread.h"
#include "starboard/time.h"
#include "starboard/window.h"
@@ -31,6 +31,12 @@
namespace starboard {
namespace player {
+// This class creates a thread that executes events posted to an internally
+// created queue. This guarantees that all such events are processed on the same
+// thread.
+//
+// This class serves as the base class for platform specific PlayerWorkers so
+// they needn't maintain the thread and queue internally.
class PlayerWorker {
public:
class Host {
@@ -78,6 +84,9 @@
kStop,
};
+ // TODO: No longer use a union so individual members can have non trivial
+ // ctor and WriteSampleEventData::input_buffer no longer has to be a
+ // pointer.
union Data {
SeekEventData seek;
WriteSampleEventData write_sample;
@@ -116,63 +125,90 @@
Data data;
};
- static const SbTime kUpdateInterval = 5 * kSbTimeMillisecond;
+ class Handler {
+ public:
+ typedef void (PlayerWorker::*UpdateMediaTimeCB)(SbMediaTime media_time);
+ typedef SbPlayerState (PlayerWorker::*GetPlayerStateCB)() const;
+ typedef void (PlayerWorker::*UpdatePlayerStateCB)(
+ SbPlayerState player_state);
+
+ typedef PlayerWorker::SeekEventData SeekEventData;
+ typedef PlayerWorker::WriteSampleEventData WriteSampleEventData;
+ typedef PlayerWorker::WriteEndOfStreamEventData WriteEndOfStreamEventData;
+ typedef PlayerWorker::SetPauseEventData SetPauseEventData;
+ typedef PlayerWorker::SetBoundsEventData SetBoundsEventData;
+
+ virtual ~Handler() {}
+
+ // This function will be called once inside PlayerWorker's ctor to setup the
+ // callbacks required by the Handler.
+ virtual void Setup(PlayerWorker* player_worker,
+ SbPlayer player,
+ UpdateMediaTimeCB update_media_time_cb,
+ GetPlayerStateCB get_player_state_cb,
+ UpdatePlayerStateCB update_player_state_cb) = 0;
+
+ // All the Process* functions return false to signal a fatal error. The
+ // event processing loop in PlayerWorker will termimate in this case.
+ virtual bool ProcessInitEvent() = 0;
+ virtual bool ProcessSeekEvent(const SeekEventData& data) = 0;
+ virtual bool ProcessWriteSampleEvent(const WriteSampleEventData& data,
+ bool* written) = 0;
+ virtual bool ProcessWriteEndOfStreamEvent(
+ const WriteEndOfStreamEventData& data) = 0;
+ virtual bool ProcessSetPauseEvent(const SetPauseEventData& data) = 0;
+ virtual bool ProcessUpdateEvent(const SetBoundsEventData& data) = 0;
+ virtual void ProcessStopEvent() = 0;
+ };
PlayerWorker(Host* host,
- SbWindow window,
- SbMediaVideoCodec video_codec,
- SbMediaAudioCodec audio_codec,
- SbDrmSystem drm_system,
- const SbMediaAudioHeader& audio_header,
+ scoped_ptr<Handler> handler,
SbPlayerDecoderStatusFunc decoder_status_func,
SbPlayerStatusFunc player_status_func,
SbPlayer player,
+ SbTime update_interval,
void* context);
- ~PlayerWorker();
+ virtual ~PlayerWorker();
template <typename EventData>
void EnqueueEvent(const EventData& event_data) {
+ SB_DCHECK(SbThreadIsValid(thread_));
queue_.Put(new Event(event_data));
}
private:
+ void UpdateMediaTime(SbMediaTime time);
+
+ SbPlayerState player_state() const { return player_state_; }
+ void UpdatePlayerState(SbPlayerState player_state);
+
static void* ThreadEntryPoint(void* context);
void RunLoop();
+ bool DoInit();
+ bool DoSeek(const SeekEventData& data);
+ bool DoWriteSample(const WriteSampleEventData& data);
+ bool DoWriteEndOfStream(const WriteEndOfStreamEventData& data);
+ bool DoUpdate(const SetBoundsEventData& data);
+ void DoStop();
- bool ProcessInitEvent();
- bool ProcessSeekEvent(const SeekEventData& data);
- bool ProcessWriteSampleEvent(const WriteSampleEventData& data, bool* retry);
- bool ProcessWriteEndOfStreamEvent(const WriteEndOfStreamEventData& data);
- bool ProcessSetPauseEvent(const SetPauseEventData& data);
- bool ProcessUpdateEvent(const SetBoundsEventData& bounds);
- void ProcessStopEvent();
-
- void UpdateDecoderState(SbMediaType type);
- void UpdatePlayerState(SbPlayerState player_state);
+ void UpdateDecoderState(SbMediaType type, SbPlayerDecoderState state);
SbThread thread_;
Queue<Event*> queue_;
Host* host_;
+ scoped_ptr<Handler> handler_;
- SbWindow window_;
- SbMediaVideoCodec video_codec_;
- SbMediaAudioCodec audio_codec_;
- SbDrmSystem drm_system_;
- SbMediaAudioHeader audio_header_;
SbPlayerDecoderStatusFunc decoder_status_func_;
SbPlayerStatusFunc player_status_func_;
SbPlayer player_;
void* context_;
-
- AudioRenderer* audio_renderer_;
- VideoRenderer* video_renderer_;
- SbPlayerDecoderState audio_decoder_state_;
- SbPlayerDecoderState video_decoder_state_;
-
- bool paused_;
int ticket_;
+
SbPlayerState player_state_;
+ const SbTime update_interval_;
+ WriteSampleEventData pending_audio_sample_;
+ WriteSampleEventData pending_video_sample_;
};
} // namespace player
diff --git a/src/starboard/starboard.gyp b/src/starboard/starboard.gyp
index 086ee4a..a76467a 100644
--- a/src/starboard/starboard.gyp
+++ b/src/starboard/starboard.gyp
@@ -58,6 +58,9 @@
'user.h',
'window.h',
],
+ 'dependencies': [
+ 'common/common.gyp:common',
+ ],
'conditions': [
['starboard_path == ""', {
# TODO: Make starboard_path required. This legacy condition is only
diff --git a/src/starboard/stub/configuration_public.h b/src/starboard/stub/configuration_public.h
index 9a8c64f..99b64df 100644
--- a/src/starboard/stub/configuration_public.h
+++ b/src/starboard/stub/configuration_public.h
@@ -420,8 +420,19 @@
// --- Tuneable Parameters ---------------------------------------------------
-// Specifies the network receive buffer size.
-#define SB_NETWORK_RECEIVE_BUFFER_SIZE (16 * 1024)
+// Specifies the network receive buffer size in bytes, set via
+// SbSocketSetReceiveBufferSize().
+//
+// Setting this to 0 indicates that SbSocketSetReceiveBufferSize() should
+// not be called. Use this for OSs (such as Linux) where receive buffer
+// auto-tuning is better.
+//
+// On some platforms, this may affect max TCP window size which may
+// dramatically affect throughput in the presence of latency.
+//
+// If your platform does not have a good TCP auto-tuning mechanism,
+// a setting of (128 * 1024) here is recommended.
+#define SB_NETWORK_RECEIVE_BUFFER_SIZE (0)
// --- User Configuration ----------------------------------------------------
diff --git a/src/third_party/glm/glm/detail/_features.hpp b/src/third_party/glm/glm/detail/_features.hpp
index 97dd633..b1701e5 100644
--- a/src/third_party/glm/glm/detail/_features.hpp
+++ b/src/third_party/glm/glm/detail/_features.hpp
@@ -256,143 +256,143 @@
# endif
#elif(GLM_COMPILER & GLM_COMPILER_CLANG)
-# if(__has_feature(cxx_exceptions))
+# if(GLM_HAS_FEATURE(cxx_exceptions))
# define GLM_CXX98_EXCEPTIONS
# endif
-# if(__has_feature(cxx_rtti))
+# if(GLM_HAS_FEATURE(cxx_rtti))
# define GLM_CXX98_RTTI
# endif
-# if(__has_feature(cxx_access_control_sfinae))
+# if(GLM_HAS_FEATURE(cxx_access_control_sfinae))
# define GLM_CXX11_ACCESS_CONTROL_SFINAE
# endif
-# if(__has_feature(cxx_alias_templates))
+# if(GLM_HAS_FEATURE(cxx_alias_templates))
# define GLM_CXX11_ALIAS_TEMPLATE
# endif
-# if(__has_feature(cxx_alignas))
+# if(GLM_HAS_FEATURE(cxx_alignas))
# define GLM_CXX11_ALIGNAS
# endif
-# if(__has_feature(cxx_attributes))
+# if(GLM_HAS_FEATURE(cxx_attributes))
# define GLM_CXX11_ATTRIBUTES
# endif
-# if(__has_feature(cxx_constexpr))
+# if(GLM_HAS_FEATURE(cxx_constexpr))
# define GLM_CXX11_CONSTEXPR
# endif
-# if(__has_feature(cxx_decltype))
+# if(GLM_HAS_FEATURE(cxx_decltype))
# define GLM_CXX11_DECLTYPE
# endif
-# if(__has_feature(cxx_default_function_template_args))
+# if(GLM_HAS_FEATURE(cxx_default_function_template_args))
# define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS
# endif
-# if(__has_feature(cxx_defaulted_functions))
+# if(GLM_HAS_FEATURE(cxx_defaulted_functions))
# define GLM_CXX11_DEFAULTED_FUNCTIONS
# endif
-# if(__has_feature(cxx_delegating_constructors))
+# if(GLM_HAS_FEATURE(cxx_delegating_constructors))
# define GLM_CXX11_DELEGATING_CONSTRUCTORS
# endif
-# if(__has_feature(cxx_deleted_functions))
+# if(GLM_HAS_FEATURE(cxx_deleted_functions))
# define GLM_CXX11_DELETED_FUNCTIONS
# endif
-# if(__has_feature(cxx_explicit_conversions))
+# if(GLM_HAS_FEATURE(cxx_explicit_conversions))
# define GLM_CXX11_EXPLICIT_CONVERSIONS
# endif
-# if(__has_feature(cxx_generalized_initializers))
+# if(GLM_HAS_FEATURE(cxx_generalized_initializers))
# define GLM_CXX11_GENERALIZED_INITIALIZERS
# endif
-# if(__has_feature(cxx_implicit_moves))
+# if(GLM_HAS_FEATURE(cxx_implicit_moves))
# define GLM_CXX11_IMPLICIT_MOVES
# endif
-# if(__has_feature(cxx_inheriting_constructors))
+# if(GLM_HAS_FEATURE(cxx_inheriting_constructors))
# define GLM_CXX11_INHERITING_CONSTRUCTORS
# endif
-# if(__has_feature(cxx_inline_namespaces))
+# if(GLM_HAS_FEATURE(cxx_inline_namespaces))
# define GLM_CXX11_INLINE_NAMESPACES
# endif
-# if(__has_feature(cxx_lambdas))
+# if(GLM_HAS_FEATURE(cxx_lambdas))
# define GLM_CXX11_LAMBDAS
# endif
-# if(__has_feature(cxx_local_type_template_args))
+# if(GLM_HAS_FEATURE(cxx_local_type_template_args))
# define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
# endif
-# if(__has_feature(cxx_noexcept))
+# if(GLM_HAS_FEATURE(cxx_noexcept))
# define GLM_CXX11_NOEXCEPT
# endif
-# if(__has_feature(cxx_nonstatic_member_init))
+# if(GLM_HAS_FEATURE(cxx_nonstatic_member_init))
# define GLM_CXX11_NONSTATIC_MEMBER_INIT
# endif
-# if(__has_feature(cxx_nullptr))
+# if(GLM_HAS_FEATURE(cxx_nullptr))
# define GLM_CXX11_NULLPTR
# endif
-# if(__has_feature(cxx_override_control))
+# if(GLM_HAS_FEATURE(cxx_override_control))
# define GLM_CXX11_OVERRIDE_CONTROL
# endif
-# if(__has_feature(cxx_reference_qualified_functions))
+# if(GLM_HAS_FEATURE(cxx_reference_qualified_functions))
# define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS
# endif
-# if(__has_feature(cxx_range_for))
+# if(GLM_HAS_FEATURE(cxx_range_for))
# define GLM_CXX11_RANGE_FOR
# endif
-# if(__has_feature(cxx_raw_string_literals))
+# if(GLM_HAS_FEATURE(cxx_raw_string_literals))
# define GLM_CXX11_RAW_STRING_LITERALS
# endif
-# if(__has_feature(cxx_rvalue_references))
+# if(GLM_HAS_FEATURE(cxx_rvalue_references))
# define GLM_CXX11_RVALUE_REFERENCES
# endif
-# if(__has_feature(cxx_static_assert))
+# if(GLM_HAS_FEATURE(cxx_static_assert))
# define GLM_CXX11_STATIC_ASSERT
# endif
-# if(__has_feature(cxx_auto_type))
+# if(GLM_HAS_FEATURE(cxx_auto_type))
# define GLM_CXX11_AUTO_TYPE
# endif
-# if(__has_feature(cxx_strong_enums))
+# if(GLM_HAS_FEATURE(cxx_strong_enums))
# define GLM_CXX11_STRONG_ENUMS
# endif
-# if(__has_feature(cxx_trailing_return))
+# if(GLM_HAS_FEATURE(cxx_trailing_return))
# define GLM_CXX11_TRAILING_RETURN
# endif
-# if(__has_feature(cxx_unicode_literals))
+# if(GLM_HAS_FEATURE(cxx_unicode_literals))
# define GLM_CXX11_UNICODE_LITERALS
# endif
-# if(__has_feature(cxx_unrestricted_unions))
+# if(GLM_HAS_FEATURE(cxx_unrestricted_unions))
# define GLM_CXX11_UNRESTRICTED_UNIONS
# endif
-# if(__has_feature(cxx_user_literals))
+# if(GLM_HAS_FEATURE(cxx_user_literals))
# define GLM_CXX11_USER_LITERALS
# endif
-# if(__has_feature(cxx_variadic_templates))
+# if(GLM_HAS_FEATURE(cxx_variadic_templates))
# define GLM_CXX11_VARIADIC_TEMPLATES
# endif
diff --git a/src/third_party/glm/glm/detail/setup.hpp b/src/third_party/glm/glm/detail/setup.hpp
index 51c7c1a..0d524b2 100644
--- a/src/third_party/glm/glm/detail/setup.hpp
+++ b/src/third_party/glm/glm/detail/setup.hpp
@@ -748,8 +748,10 @@
///////////////////////////////////////////////////////////////////////////////////
// countof
-#ifndef __has_feature
-# define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#ifdef __has_feature
+# define GLM_HAS_FEATURE __has_feature
+#else
+# define GLM_HAS_FEATURE(x) 0 // Compatibility with non-clang compilers.
#endif
#if GLM_HAS_CONSTEXPR_PARTIAL
diff --git a/src/third_party/glm/glm/detail/type_vec1.hpp b/src/third_party/glm/glm/detail/type_vec1.hpp
index dd673a7..ecccd81 100644
--- a/src/third_party/glm/glm/detail/type_vec1.hpp
+++ b/src/third_party/glm/glm/detail/type_vec1.hpp
@@ -37,6 +37,10 @@
# pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
# pragma clang diagnostic ignored "-Wnested-anon-types"
# endif
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(push)
+# pragma warning(disable : 4201)
+# endif
union
{
@@ -57,6 +61,9 @@
# endif//GLM_SWIZZLE*/
};
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(pop)
+# endif
# if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
# endif
diff --git a/src/third_party/glm/glm/detail/type_vec2.hpp b/src/third_party/glm/glm/detail/type_vec2.hpp
index 9a9ef42..6190861 100644
--- a/src/third_party/glm/glm/detail/type_vec2.hpp
+++ b/src/third_party/glm/glm/detail/type_vec2.hpp
@@ -36,6 +36,10 @@
# pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
# pragma clang diagnostic ignored "-Wnested-anon-types"
# endif
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(push)
+# pragma warning(disable : 4201)
+# endif
union
{
@@ -57,6 +61,9 @@
};
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(pop)
+# endif
# if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
# endif
diff --git a/src/third_party/glm/glm/detail/type_vec3.hpp b/src/third_party/glm/glm/detail/type_vec3.hpp
index ebd135d..d052196 100644
--- a/src/third_party/glm/glm/detail/type_vec3.hpp
+++ b/src/third_party/glm/glm/detail/type_vec3.hpp
@@ -36,6 +36,10 @@
# pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
# pragma clang diagnostic ignored "-Wnested-anon-types"
# endif
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(push)
+# pragma warning(disable : 4201)
+# endif
union
{
@@ -56,6 +60,9 @@
# endif//GLM_SWIZZLE
};
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(pop)
+# endif
# if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
# endif
diff --git a/src/third_party/glm/glm/detail/type_vec4.hpp b/src/third_party/glm/glm/detail/type_vec4.hpp
index 5a03cd4..a923853 100644
--- a/src/third_party/glm/glm/detail/type_vec4.hpp
+++ b/src/third_party/glm/glm/detail/type_vec4.hpp
@@ -36,6 +36,10 @@
# pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
# pragma clang diagnostic ignored "-Wnested-anon-types"
# endif
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(push)
+# pragma warning(disable : 4201)
+# endif
union
{
@@ -58,6 +62,9 @@
# endif//GLM_SWIZZLE
};
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(pop)
+# endif
# if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
# endif
diff --git a/src/third_party/glm/glm/gtc/quaternion.hpp b/src/third_party/glm/glm/gtc/quaternion.hpp
index 72d0603..3f58d14 100644
--- a/src/third_party/glm/glm/gtc/quaternion.hpp
+++ b/src/third_party/glm/glm/gtc/quaternion.hpp
@@ -50,6 +50,10 @@
# pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
# pragma clang diagnostic ignored "-Wnested-anon-types"
# endif
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(push)
+# pragma warning(disable : 4201)
+# endif
union
{
@@ -57,6 +61,9 @@
typename detail::storage<T, sizeof(T) * 4, detail::is_aligned<P>::value>::type data;
};
+# if GLM_COMPILER & GLM_COMPILER_VC
+# pragma warning(pop)
+# endif
# if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
# endif
diff --git a/src/third_party/mozjs/js/src/memory_allocator_reporter.cpp b/src/third_party/mozjs/js/src/memory_allocator_reporter.cpp
index 93d42df..9b879bb 100644
--- a/src/third_party/mozjs/js/src/memory_allocator_reporter.cpp
+++ b/src/third_party/mozjs/js/src/memory_allocator_reporter.cpp
@@ -25,7 +25,7 @@
s_instance = new MemoryAllocatorReporter();
}
-void* OffsetPointer(void* base, ssize_t offset) {
+void* OffsetPointer(void* base, int64_t offset) {
uintptr_t base_as_int = reinterpret_cast<uintptr_t>(base);
return reinterpret_cast<void*>(base_as_int + offset);
}
@@ -38,17 +38,17 @@
// The metadata lives just in front of the data.
void* meta_addr =
- OffsetPointer(ptr, -static_cast<ssize_t>(sizeof(AllocationMetadata)));
+ OffsetPointer(ptr, -static_cast<int64_t>(sizeof(AllocationMetadata)));
return reinterpret_cast<AllocationMetadata*>(meta_addr);
}
void* AllocationMetadata::GetUserAddressFromBaseAddress(void* base_ptr) {
void* adjusted_base =
- OffsetPointer(base_ptr, static_cast<ssize_t>(sizeof(AllocationMetadata)));
+ OffsetPointer(base_ptr, static_cast<int64_t>(sizeof(AllocationMetadata)));
return adjusted_base;
}
-void AllocationMetadata::SetSizeToBaseAddress(void* base_ptr, size_t size) {
+void AllocationMetadata::SetSizeToBaseAddress(void* base_ptr, int64_t size) {
if (base_ptr) {
AllocationMetadata* metadata =
reinterpret_cast<AllocationMetadata*>(base_ptr);
@@ -56,22 +56,22 @@
}
}
-void MemoryAllocatorReporter::UpdateAllocatedBytes(ssize_t bytes) {
+void MemoryAllocatorReporter::UpdateAllocatedBytes(int64_t bytes) {
starboard::ScopedLock lock(mutex_);
current_bytes_allocated_ += bytes;
}
-ssize_t MemoryAllocatorReporter::GetCurrentBytesAllocated() {
+int64_t MemoryAllocatorReporter::GetCurrentBytesAllocated() {
starboard::ScopedLock lock(mutex_);
return current_bytes_allocated_;
}
-void MemoryAllocatorReporter::UpdateMappedBytes(ssize_t bytes) {
+void MemoryAllocatorReporter::UpdateMappedBytes(int64_t bytes) {
starboard::ScopedLock lock(mutex_);
current_bytes_mapped_ += bytes;
}
-ssize_t MemoryAllocatorReporter::GetCurrentBytesMapped() {
+int64_t MemoryAllocatorReporter::GetCurrentBytesMapped() {
starboard::ScopedLock lock(mutex_);
return current_bytes_mapped_;
}
diff --git a/src/third_party/mozjs/js/src/memory_allocator_reporter.h b/src/third_party/mozjs/js/src/memory_allocator_reporter.h
index e0d679f..82227e3 100644
--- a/src/third_party/mozjs/js/src/memory_allocator_reporter.h
+++ b/src/third_party/mozjs/js/src/memory_allocator_reporter.h
@@ -15,28 +15,27 @@
#ifndef MemoryAllocatorReporter_h
#define MemoryAllocatorReporter_h
-#include <sys/types.h>
-
#include "starboard/mutex.h"
+#include "starboard/types.h"
class AllocationMetadata {
public:
static AllocationMetadata* GetMetadataFromUserAddress(void* ptr);
static void* GetUserAddressFromBaseAddress(void* base_ptr);
- static size_t GetReservationBytes(size_t bytes_requested) {
+ static int64_t GetReservationBytes(int64_t bytes_requested) {
return sizeof(AllocationMetadata) + bytes_requested;
}
- static size_t GetSizeOfAllocationFromMetadata(AllocationMetadata* metadata) {
+ static int64_t GetSizeOfAllocationFromMetadata(AllocationMetadata* metadata) {
return metadata ? metadata->size_requested() : 0;
}
- static void SetSizeToBaseAddress(void* base_ptr, size_t size);
+ static void SetSizeToBaseAddress(void* base_ptr, int64_t size);
- size_t size_requested() { return size_requested_; }
- void set_size_requested(size_t size) { size_requested_ = size; }
+ int64_t size_requested() { return size_requested_; }
+ void set_size_requested(int64_t size) { size_requested_ = size; }
private:
// Bytes requested by the underlying allocator.
- size_t size_requested_;
+ int64_t size_requested_;
};
// Reporter that is used to report memory allocation.
@@ -47,16 +46,16 @@
MemoryAllocatorReporter()
: current_bytes_allocated_(0), current_bytes_mapped_(0) {}
- void UpdateAllocatedBytes(ssize_t bytes);
- ssize_t GetCurrentBytesAllocated();
+ void UpdateAllocatedBytes(int64_t bytes);
+ int64_t GetCurrentBytesAllocated();
- void UpdateMappedBytes(ssize_t bytes);
- ssize_t GetCurrentBytesMapped();
+ void UpdateMappedBytes(int64_t bytes);
+ int64_t GetCurrentBytesMapped();
private:
starboard::Mutex mutex_;
- ssize_t current_bytes_allocated_;
- ssize_t current_bytes_mapped_;
+ int64_t current_bytes_allocated_;
+ int64_t current_bytes_mapped_;
};
#endif /* MemoryAllocatorReporter_h */
diff --git a/src/third_party/mozjs/js/src/vm/ThreadPool.cpp b/src/third_party/mozjs/js/src/vm/ThreadPool.cpp
index af88bbc..70e74fa 100644
--- a/src/third_party/mozjs/js/src/vm/ThreadPool.cpp
+++ b/src/third_party/mozjs/js/src/vm/ThreadPool.cpp
@@ -123,8 +123,21 @@
// variable and give a 10k buffer. Is there a better way?
// (Note: 2k proved to be fine on Mac, but too little on Linux)
uintptr_t stackLimitOffset = WORKER_THREAD_STACK_SIZE - 10*1024;
+
+ // The following code results in an internal compiler error when compiling
+ // with GCC 4.9.2 for the MIPS architecture with optimizations enabled.
+ // A volatile qualifier is added as a workaround, as it disables those
+ // optimizations.
+#if __GNUC__ == 4 && __GNUC_MINOR__ == 9 && __GNUC_PATCHLEVEL__ == 2 && \
+ defined(_MIPS_ARCH) && __mips16 == 1
+ volatile uintptr_t stackLimitVolatile =
+ (((uintptr_t)&stackLimitOffset) +
+ stackLimitOffset * JS_STACK_GROWTH_DIRECTION);
+ uintptr_t stackLimit = stackLimitVolatile;
+#else // GCC 4.9.2, mips, mips16
uintptr_t stackLimit = (((uintptr_t)&stackLimitOffset) +
stackLimitOffset * JS_STACK_GROWTH_DIRECTION);
+#endif // GCC 4.9.2, mips, mips16
AutoLockMonitor lock(*this);
diff --git a/src/third_party/protobuf/CHANGES.txt b/src/third_party/protobuf/CHANGES.txt
new file mode 100644
index 0000000..737f865
--- /dev/null
+++ b/src/third_party/protobuf/CHANGES.txt
@@ -0,0 +1,470 @@
+2011-05-01 version 2.4.1:
+
+ C++
+ * Fixed the frendship problem for old compilers to make the library now gcc 3
+ compatible again.
+ * Fixed vcprojects/extract_includes.bat to extract compiler/plugin.h.
+
+ Java
+ * Removed usages of JDK 1.6 only features to make the library now JDK 1.5
+ compatible again.
+ * Fixed a bug about negative enum values.
+ * serialVersionUID is now defined in generated messages for java serializing.
+ * Fixed protoc to use java.lang.Object, which makes "Object" now a valid
+ message name again.
+
+ Python
+ * Experimental C++ implementation now requires C++ protobuf library installed.
+ See the README.txt in the python directory for details.
+
+2011-02-02 version 2.4.0:
+
+ General
+ * The RPC (cc|java|py)_generic_services default value is now false instead of
+ true.
+ * Custom options can have aggregate types. For example,
+ message MyOption {
+ optional string comment = 1;
+ optional string author = 2;
+ }
+ extend google.protobuf.FieldOptions {
+ optional MyOption myoption = 12345;
+ }
+ This option can now be set as follows:
+ message SomeType {
+ optional int32 field = 1 [(myoption) = { comment:'x' author:'y' }];
+ }
+
+ C++
+ * Various speed and code size optimizations.
+ * Added a release_foo() method on string and message fields.
+ * Fixed gzip_output_stream sub-stream handling.
+
+ Java
+ * Builders now maintain sub-builders for sub-messages. Use getFooBuilder() to
+ get the builder for the sub-message "foo". This allows you to repeatedly
+ modify deeply-nested sub-messages without rebuilding them.
+ * Builder.build() no longer invalidates the Builder for generated messages
+ (You may continue to modify it and then build another message).
+ * Code generator will generate efficient equals() and hashCode()
+ implementations if new option java_generate_equals_and_hash is enabled.
+ (Otherwise, reflection-based implementations are used.)
+ * Generated messages now implement Serializable.
+ * Fields with [deprecated=true] will be marked with @Deprecated in Java.
+ * Added lazy conversion of UTF-8 encoded strings to String objects to improve
+ performance.
+ * Various optimizations.
+ * Enum value can be accessed directly, instead of calling getNumber() on the
+ enum member.
+ * For each enum value, an integer constant is also generated with the suffix
+ _VALUE.
+
+ Python
+ * Added an experimental C++ implementation for Python messages via a Python
+ extension. Implementation type is controlled by an environment variable
+ PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION (valid values: "cpp" and "python")
+ The default value is currently "python" but will be changed to "cpp" in
+ future release.
+ * Improved performance on message instantiation significantly.
+ Most of the work on message instantiation is done just once per message
+ class, instead of once per message instance.
+ * Improved performance on text message parsing.
+ * Allow add() to forward keyword arguments to the concrete class.
+ E.g. instead of
+ item = repeated_field.add()
+ item.foo = bar
+ item.baz = quux
+ You can do:
+ repeated_field.add(foo=bar, baz=quux)
+ * Added a sort() interface to the BaseContainer.
+ * Added an extend() method to repeated composite fields.
+ * Added UTF8 debug string support.
+
+2010-01-08 version 2.3.0:
+
+ General
+ * Parsers for repeated numeric fields now always accept both packed and
+ unpacked input. The [packed=true] option only affects serializers.
+ Therefore, it is possible to switch a field to packed format without
+ breaking backwards-compatibility -- as long as all parties are using
+ protobuf 2.3.0 or above, at least.
+ * The generic RPC service code generated by the C++, Java, and Python
+ generators can be disabled via file options:
+ option cc_generic_services = false;
+ option java_generic_services = false;
+ option py_generic_services = false;
+ This allows plugins to generate alternative code, possibly specific to some
+ particular RPC implementation.
+
+ protoc
+ * Now supports a plugin system for code generators. Plugins can generate
+ code for new languages or inject additional code into the output of other
+ code generators. Plugins are just binaries which accept a protocol buffer
+ on stdin and write a protocol buffer to stdout, so they may be written in
+ any language. See src/google/protobuf/compiler/plugin.proto.
+ **WARNING**: Plugins are experimental. The interface may change in a
+ future version.
+ * If the output location ends in .zip or .jar, protoc will write its output
+ to a zip/jar archive instead of a directory. For example:
+ protoc --java_out=myproto_srcs.jar --python_out=myproto.zip myproto.proto
+ Currently the archive contents are not compressed, though this could change
+ in the future.
+ * inf, -inf, and nan can now be used as default values for float and double
+ fields.
+
+ C++
+ * Various speed and code size optimizations.
+ * DynamicMessageFactory is now fully thread-safe.
+ * Message::Utf8DebugString() method is like DebugString() but avoids escaping
+ UTF-8 bytes.
+ * Compiled-in message types can now contain dynamic extensions, through use
+ of CodedInputStream::SetExtensionRegistry().
+ * Now compiles shared libraries (DLLs) by default on Cygwin and MinGW, to
+ match other platforms. Use --disable-shared to avoid this.
+
+ Java
+ * parseDelimitedFrom() and mergeDelimitedFrom() now detect EOF and return
+ false/null instead of throwing an exception.
+ * Fixed some initialization ordering bugs.
+ * Fixes for OpenJDK 7.
+
+ Python
+ * 10-25 times faster than 2.2.0, still pure-Python.
+ * Calling a mutating method on a sub-message always instantiates the message
+ in its parent even if the mutating method doesn't actually mutate anything
+ (e.g. parsing from an empty string).
+ * Expanded descriptors a bit.
+
+2009-08-11 version 2.2.0:
+
+ C++
+ * Lite mode: The "optimize_for = LITE_RUNTIME" option causes the compiler
+ to generate code which only depends libprotobuf-lite, which is much smaller
+ than libprotobuf but lacks descriptors, reflection, and some other features.
+ * Fixed bug where Message.Swap(Message) was only implemented for
+ optimize_for_speed. Swap now properly implemented in both modes
+ (Issue 91).
+ * Added RemoveLast and SwapElements(index1, index2) to Reflection
+ interface for repeated elements.
+ * Added Swap(Message) to Reflection interface.
+ * Floating-point literals in generated code that are intended to be
+ single-precision now explicitly have 'f' suffix to avoid pedantic warnings
+ produced by some compilers.
+ * The [deprecated=true] option now causes the C++ code generator to generate
+ a GCC-style deprecation annotation (no-op on other compilers).
+ * google::protobuf::GetEnumDescriptor<SomeGeneratedEnumType>() returns the
+ EnumDescriptor for that type -- useful for templates which cannot call
+ SomeGeneratedEnumType_descriptor().
+ * Various optimizations and obscure bug fixes.
+
+ Java
+ * Lite mode: The "optimize_for = LITE_RUNTIME" option causes the compiler
+ to generate code which only depends libprotobuf-lite, which is much smaller
+ than libprotobuf but lacks descriptors, reflection, and some other features.
+ * Lots of style cleanups.
+
+ Python
+ * Fixed endianness bug with floats and doubles.
+ * Text format parsing support.
+ * Fix bug with parsing packed repeated fields in embedded messages.
+ * Ability to initialize fields by passing keyword args to constructor.
+ * Support iterators in extend and __setslice__ for containers.
+
+2009-05-13 version 2.1.0:
+
+ General
+ * Repeated fields of primitive types (types other that string, group, and
+ nested messages) may now use the option [packed = true] to get a more
+ efficient encoding. In the new encoding, the entire list is written
+ as a single byte blob using the "length-delimited" wire type. Within
+ this blob, the individual values are encoded the same way they would
+ be normally except without a tag before each value (thus, they are
+ tightly "packed").
+ * For each field, the generated code contains an integer constant assigned
+ to the field number. For example, the .proto file:
+ message Foo { optional int bar_baz = 123; }
+ would generate the following constants, all with the integer value 123:
+ C++: Foo::kBarBazFieldNumber
+ Java: Foo.BAR_BAZ_FIELD_NUMBER
+ Python: Foo.BAR_BAZ_FIELD_NUMBER
+ Constants are also generated for extensions, with the same naming scheme.
+ These constants may be used as switch cases.
+ * Updated bundled Google Test to version 1.3.0. Google Test is now bundled
+ in its verbatim form as a nested autoconf package, so you can drop in any
+ other version of Google Test if needed.
+ * optimize_for = SPEED is now the default, by popular demand. Use
+ optimize_for = CODE_SIZE if code size is more important in your app.
+ * It is now an error to define a default value for a repeated field.
+ Previously, this was silently ignored (it had no effect on the generated
+ code).
+ * Fields can now be marked deprecated like:
+ optional int32 foo = 1 [deprecated = true];
+ Currently this does not have any actual effect, but in the future the code
+ generators may generate deprecation annotations in each language.
+ * Cross-compiling should now be possible using the --with-protoc option to
+ configure. See README.txt for more info.
+
+ protoc
+ * --error_format=msvs option causes errors to be printed in Visual Studio
+ format, which should allow them to be clicked on in the build log to go
+ directly to the error location.
+ * The type name resolver will no longer resolve type names to fields. For
+ example, this now works:
+ message Foo {}
+ message Bar {
+ optional int32 Foo = 1;
+ optional Foo baz = 2;
+ }
+ Previously, the type of "baz" would resolve to "Bar.Foo", and you'd get
+ an error because Bar.Foo is a field, not a type. Now the type of "baz"
+ resolves to the message type Foo. This change is unlikely to make a
+ difference to anyone who follows the Protocol Buffers style guide.
+
+ C++
+ * Several optimizations, including but not limited to:
+ - Serialization, especially to flat arrays, is 10%-50% faster, possibly
+ more for small objects.
+ - Several descriptor operations which previously required locking no longer
+ do.
+ - Descriptors are now constructed lazily on first use, rather than at
+ process startup time. This should save memory in programs which do not
+ use descriptors or reflection.
+ - UnknownFieldSet completely redesigned to be more efficient (especially in
+ terms of memory usage).
+ - Various optimizations to reduce code size (though the serialization speed
+ optimizations increased code size).
+ * Message interface has method ParseFromBoundedZeroCopyStream() which parses
+ a limited number of bytes from an input stream rather than parsing until
+ EOF.
+ * GzipInputStream and GzipOutputStream support reading/writing gzip- or
+ zlib-compressed streams if zlib is available.
+ (google/protobuf/io/gzip_stream.h)
+ * DescriptorPool::FindAllExtensions() and corresponding
+ DescriptorDatabase::FindAllExtensions() can be used to enumerate all
+ extensions of a given type.
+ * For each enum type Foo, protoc will generate functions:
+ const string& Foo_Name(Foo value);
+ bool Foo_Parse(const string& name, Foo* result);
+ The former returns the name of the enum constant corresponding to the given
+ value while the latter finds the value corresponding to a name.
+ * RepeatedField and RepeatedPtrField now have back-insertion iterators.
+ * String fields now have setters that take a char* and a size, in addition
+ to the existing ones that took char* or const string&.
+ * DescriptorPool::AllowUnknownDependencies() may be used to tell
+ DescriptorPool to create placeholder descriptors for unknown entities
+ referenced in a FileDescriptorProto. This can allow you to parse a .proto
+ file without having access to other .proto files that it imports, for
+ example.
+ * Updated gtest to latest version. The gtest package is now included as a
+ nested autoconf package, so it should be able to drop new versions into the
+ "gtest" subdirectory without modification.
+
+ Java
+ * Fixed bug where Message.mergeFrom(Message) failed to merge extensions.
+ * Message interface has new method toBuilder() which is equivalent to
+ newBuilderForType().mergeFrom(this).
+ * All enums now implement the ProtocolMessageEnum interface.
+ * Setting a field to null now throws NullPointerException.
+ * Fixed tendency for TextFormat's parsing to overflow the stack when
+ parsing large string values. The underlying problem is with Java's
+ regex implementation (which unfortunately uses recursive backtracking
+ rather than building an NFA). Worked around by making use of possesive
+ quantifiers.
+ * Generated service classes now also generate pure interfaces. For a service
+ Foo, Foo.Interface is a pure interface containing all of the service's
+ defined methods. Foo.newReflectiveService() can be called to wrap an
+ instance of this interface in a class that implements the generic
+ RpcService interface, which provides reflection support that is usually
+ needed by RPC server implementations.
+ * RPC interfaces now support blocking operation in addition to non-blocking.
+ The protocol compiler generates separate blocking and non-blocking stubs
+ which operate against separate blocking and non-blocking RPC interfaces.
+ RPC implementations will have to implement the new interfaces in order to
+ support blocking mode.
+ * New I/O methods parseDelimitedFrom(), mergeDelimitedFrom(), and
+ writeDelimitedTo() read and write "delemited" messages from/to a stream,
+ meaning that the message size precedes the data. This way, you can write
+ multiple messages to a stream without having to worry about delimiting
+ them yourself.
+ * Throw a more descriptive exception when build() is double-called.
+ * Add a method to query whether CodedInputStream is at the end of the input
+ stream.
+ * Add a method to reset a CodedInputStream's size counter; useful when
+ reading many messages with the same stream.
+ * equals() and hashCode() now account for unknown fields.
+
+ Python
+ * Added slicing support for repeated scalar fields. Added slice retrieval and
+ removal of repeated composite fields.
+ * Updated RPC interfaces to allow for blocking operation. A client may
+ now pass None for a callback when making an RPC, in which case the
+ call will block until the response is received, and the response
+ object will be returned directly to the caller. This interface change
+ cannot be used in practice until RPC implementations are updated to
+ implement it.
+ * Changes to input_stream.py should make protobuf compatible with appengine.
+
+2008-11-25 version 2.0.3:
+
+ protoc
+ * Enum values may now have custom options, using syntax similar to field
+ options.
+ * Fixed bug where .proto files which use custom options but don't actually
+ define them (i.e. they import another .proto file defining the options)
+ had to explicitly import descriptor.proto.
+ * Adjacent string literals in .proto files will now be concatenated, like in
+ C.
+ * If an input file is a Windows absolute path (e.g. "C:\foo\bar.proto") and
+ the import path only contains "." (or contains "." but does not contain
+ the file), protoc incorrectly thought that the file was under ".", because
+ it thought that the path was relative (since it didn't start with a slash).
+ This has been fixed.
+
+ C++
+ * Generated message classes now have a Swap() method which efficiently swaps
+ the contents of two objects.
+ * All message classes now have a SpaceUsed() method which returns an estimate
+ of the number of bytes of allocated memory currently owned by the object.
+ This is particularly useful when you are reusing a single message object
+ to improve performance but want to make sure it doesn't bloat up too large.
+ * New method Message::SerializeAsString() returns a string containing the
+ serialized data. May be more convenient than calling
+ SerializeToString(string*).
+ * In debug mode, log error messages when string-type fields are found to
+ contain bytes that are not valid UTF-8.
+ * Fixed bug where a message with multiple extension ranges couldn't parse
+ extensions.
+ * Fixed bug where MergeFrom(const Message&) didn't do anything if invoked on
+ a message that contained no fields (but possibly contained extensions).
+ * Fixed ShortDebugString() to not be O(n^2). Durr.
+ * Fixed crash in TextFormat parsing if the first token in the input caused a
+ tokenization error.
+ * Fixed obscure bugs in zero_copy_stream_impl.cc.
+ * Added support for HP C++ on Tru64.
+ * Only build tests on "make check", not "make".
+ * Fixed alignment issue that caused crashes when using DynamicMessage on
+ 64-bit Sparc machines.
+ * Simplify template usage to work with MSVC 2003.
+ * Work around GCC 4.3.x x86_64 compiler bug that caused crashes on startup.
+ (This affected Fedora 9 in particular.)
+ * Now works on "Solaris 10 using recent Sun Studio".
+
+ Java
+ * New overload of mergeFrom() which parses a slice of a byte array instead
+ of the whole thing.
+ * New method ByteString.asReadOnlyByteBuffer() does what it sounds like.
+ * Improved performance of isInitialized() when optimizing for code size.
+
+ Python
+ * Corrected ListFields() signature in Message base class to match what
+ subclasses actually implement.
+ * Some minor refactoring.
+ * Don't pass self as first argument to superclass constructor (no longer
+ allowed in Python 2.6).
+
+2008-09-29 version 2.0.2:
+
+ General
+ * License changed from Apache 2.0 to New BSD.
+ * It is now possible to define custom "options", which are basically
+ annotations which may be placed on definitions in a .proto file.
+ For example, you might define a field option called "foo" like so:
+ import "google/protobuf/descriptor.proto"
+ extend google.protobuf.FieldOptions {
+ optional string foo = 12345;
+ }
+ Then you annotate a field using the "foo" option:
+ message MyMessage {
+ optional int32 some_field = 1 [(foo) = "bar"]
+ }
+ The value of this option is then visible via the message's
+ Descriptor:
+ const FieldDescriptor* field =
+ MyMessage::descriptor()->FindFieldByName("some_field");
+ assert(field->options().GetExtension(foo) == "bar");
+ This feature has been implemented and tested in C++ and Java.
+ Other languages may or may not need to do extra work to support
+ custom options, depending on how they construct descriptors.
+
+ C++
+ * Fixed some GCC warnings that only occur when using -pedantic.
+ * Improved static initialization code, making ordering more
+ predictable among other things.
+ * TextFormat will no longer accept messages which contain multiple
+ instances of a singular field. Previously, the latter instance
+ would overwrite the former.
+ * Now works on systems that don't have hash_map.
+
+ Java
+ * Print @Override annotation in generated code where appropriate.
+
+ Python
+ * Strings now use the "unicode" type rather than the "str" type.
+ String fields may still be assigned ASCII "str" values; they will
+ automatically be converted.
+ * Adding a property to an object representing a repeated field now
+ raises an exception. For example:
+ # No longer works (and never should have).
+ message.some_repeated_field.foo = 1
+
+ Windows
+ * We now build static libraries rather than DLLs by default on MSVC.
+ See vsprojects/readme.txt for more information.
+
+2008-08-15 version 2.0.1:
+
+ protoc
+ * New flags --encode and --decode can be used to convert between protobuf text
+ format and binary format from the command-line.
+ * New flag --descriptor_set_out can be used to write FileDescriptorProtos for
+ all parsed files directly into a single output file. This is particularly
+ useful if you wish to parse .proto files from programs written in languages
+ other than C++: just run protoc as a background process and have it output
+ a FileDescriptorList, then parse that natively.
+ * Improved error message when an enum value's name conflicts with another
+ symbol defined in the enum type's scope, e.g. if two enum types declared
+ in the same scope have values with the same name. This is disallowed for
+ compatibility with C++, but this wasn't clear from the error.
+ * Fixed absolute output paths on Windows.
+ * Allow trailing slashes in --proto_path mappings.
+
+ C++
+ * Reflection objects are now per-class rather than per-instance. To make this
+ possible, the Reflection interface had to be changed such that all methods
+ take the Message instance as a parameter. This change improves performance
+ significantly in memory-bandwidth-limited use cases, since it makes the
+ message objects smaller. Note that source-incompatible interface changes
+ like this will not be made again after the library leaves beta.
+ * Heuristically detect sub-messages when printing unknown fields.
+ * Fix static initialization ordering bug that caused crashes at startup when
+ compiling on Mac with static linking.
+ * Fixed TokenizerTest when compiling with -DNDEBUG on Linux.
+ * Fixed incorrect definition of kint32min.
+ * Fix bytes type setter to work with byte sequences with embedded NULLs.
+ * Other irrelevant tweaks.
+
+ Java
+ * Fixed UnknownFieldSet's parsing of varints larger than 32 bits.
+ * Fixed TextFormat's parsing of "inf" and "nan".
+ * Fixed TextFormat's parsing of comments.
+ * Added info to Java POM that will be required when we upload the
+ package to a Maven repo.
+
+ Python
+ * MergeFrom(message) and CopyFrom(message) are now implemented.
+ * SerializeToString() raises an exception if the message is missing required
+ fields.
+ * Code organization improvements.
+ * Fixed doc comments for RpcController and RpcChannel, which had somehow been
+ swapped.
+ * Fixed text_format_test on Windows where floating-point exponents sometimes
+ contain extra zeros.
+ * Fix Python service CallMethod() implementation.
+
+ Other
+ * Improved readmes.
+ * VIM syntax highlighting improvements.
+
+2008-07-07 version 2.0.0:
+
+ * First public release.
diff --git a/src/third_party/protobuf/CONTRIBUTORS.txt b/src/third_party/protobuf/CONTRIBUTORS.txt
new file mode 100644
index 0000000..7c1ac80
--- /dev/null
+++ b/src/third_party/protobuf/CONTRIBUTORS.txt
@@ -0,0 +1,88 @@
+This file contains a list of people who have made large contributions
+to the public version of Protocol Buffers.
+
+Original Protocol Buffers design and implementation:
+ Sanjay Ghemawat <sanjay@google.com>
+ Jeff Dean <jeff@google.com>
+ Daniel Dulitz <daniel@google.com>
+ Craig Silverstein
+ Paul Haahr <haahr@google.com>
+ Corey Anderson <corin@google.com>
+ (and many others)
+
+Proto2 C++ and Java primary author:
+ Kenton Varda <kenton@google.com>
+
+Proto2 Python primary authors:
+ Will Robinson <robinson@google.com>
+ Petar Petrov <petar@google.com>
+
+Large code contributions:
+ Jason Hsueh <jasonh@google.com>
+ Joseph Schorr <jschorr@google.com>
+ Wenbo Zhu <wenboz@google.com>
+
+Large quantity of code reviews:
+ Scott Bruce <sbruce@google.com>
+ Frank Yellin
+ Neal Norwitz <nnorwitz@google.com>
+ Jeffrey Yasskin <jyasskin@google.com>
+ Ambrose Feinstein <ambrose@google.com>
+
+Documentation:
+ Lisa Carey <lcarey@google.com>
+
+Maven packaging:
+ Gregory Kick <gak@google.com>
+
+Patch contributors:
+ Kevin Ko <kevin.s.ko@gmail.com>
+ * Small patch to handle trailing slashes in --proto_path flag.
+ Johan Euphrosine <proppy@aminche.com>
+ * Small patch to fix Python CallMethod().
+ Ulrich Kunitz <kune@deine-taler.de>
+ * Small optimizations to Python serialization.
+ Leandro Lucarella <llucax@gmail.com>
+ * VI syntax highlighting tweaks.
+ * Fix compiler to not make output executable.
+ Dilip Joseph <dilip.antony.joseph@gmail.com>
+ * Heuristic detection of sub-messages when printing unknown fields in
+ text format.
+ Brian Atkinson <nairb774@gmail.com>
+ * Added @Override annotation to generated Java code where appropriate.
+ Vincent Choinière <Choiniere.Vincent@hydro.qc.ca>
+ * Tru64 support.
+ Monty Taylor <monty.taylor@gmail.com>
+ * Solaris 10 + Sun Studio fixes.
+ Alek Storm <alek.storm@gmail.com>
+ * Slicing support for repeated scalar fields for the Python API.
+ Oleg Smolsky <oleg.smolsky@gmail.com>
+ * MS Visual Studio error format option.
+ * Detect unordered_map in stl_hash.m4.
+ Brian Olson <brianolson@google.com>
+ * gzip/zlib I/O support.
+ Michael Poole <mdpoole@troilus.org>
+ * Fixed warnings about generated constructors not explicitly initializing
+ all fields (only present with certain compiler settings).
+ * Added generation of field number constants.
+ Wink Saville <wink@google.com>
+ * Fixed initialization ordering problem in logging code.
+ Will Pierce <willp@nuclei.com>
+ * Small patch improving performance of in Python serialization.
+ Alexandre Vassalotti <alexandre@peadrop.com>
+ * Emacs mode for Protocol Buffers (editors/protobuf-mode.el).
+ Scott Stafford <scott.stafford@gmail.com>
+ * Added Swap(), SwapElements(), and RemoveLast() to Reflection interface.
+ Alexander Melnikov <alm@sibmail.ru>
+ * HPUX support.
+ Oliver Jowett <oliver.jowett@gmail.com>
+ * Detect whether zlib is new enough in configure script.
+ * Fixes for Solaris 10 32/64-bit confusion.
+ Evan Jones <evanj@mit.edu>
+ * Optimize Java serialization code when writing a small message to a stream.
+ * Optimize Java serialization of strings so that UTF-8 encoding happens only
+ once per string per serialization call.
+ * Clean up some Java warnings.
+ * Fix bug with permanent callbacks that delete themselves when run.
+ Michael Kucharski <m.kucharski@gmail.com>
+ * Added CodedInputStream.getTotalBytesRead().
diff --git a/src/third_party/protobuf/COPYING.txt b/src/third_party/protobuf/COPYING.txt
new file mode 100644
index 0000000..705db57
--- /dev/null
+++ b/src/third_party/protobuf/COPYING.txt
@@ -0,0 +1,33 @@
+Copyright 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it. This code is not
+standalone and requires a support library to be linked with it. This
+support library is itself covered by the above license.
diff --git a/src/third_party/protobuf/INSTALL.txt b/src/third_party/protobuf/INSTALL.txt
new file mode 100644
index 0000000..ce3b094
--- /dev/null
+++ b/src/third_party/protobuf/INSTALL.txt
@@ -0,0 +1,237 @@
+This file contains detailed but generic information on building and
+installing the C++ part of this project. For shorter instructions,
+as well as instructions for compiling and installing the Java or
+Python parts, see README.
+
+======================================================================
+
+Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+ This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/src/third_party/protobuf/README.chromium b/src/third_party/protobuf/README.chromium
new file mode 100644
index 0000000..7672411
--- /dev/null
+++ b/src/third_party/protobuf/README.chromium
@@ -0,0 +1,36 @@
+Name: Protocol Buffers
+Short Name: protobuf
+URL: http://protobuf.googlecode.com/svn/trunk
+License: BSD
+License File: COPYING.txt
+Version: unknown
+Revision: r423
+Security Critical: yes
+
+Local files (not taken from upstream):
+README.chromium
+config.h
+descriptor2_pb.py
+protobuf_lite_java_descriptor_proto.py
+protobuf_lite_java_parse_pom.py
+
+A protobuf.gyp file has been added for building with Chromium.
+
+This code has been patched to support unknown field retention in protobuf-lite.
+See r62331 for the patch.
+
+This code has been patched to ensure that files in the target protobuf_lite
+do not include headers from protobuf_full. See r173228 for the patch.
+
+Revisions r427 and r430 were cherry-picked from upstream.
+
+Cherry-pick patch from http://code.google.com/p/protobuf/issues/detail?id=425.
+
+Notes about Java:
+We have not forked the Java version of protobuf-lite, so the Java version does
+not support unknown field retention.
+
+The list of Java files included in the lite profile for Java is parsed from the
+maven java/pom.xml by the script protobuf_lite_java_parse_pom.py. See
+'javac_includes' variable in protobuf_lite_javalib GYP target.
+
diff --git a/src/third_party/protobuf/README.txt b/src/third_party/protobuf/README.txt
new file mode 100644
index 0000000..a8f6604
--- /dev/null
+++ b/src/third_party/protobuf/README.txt
@@ -0,0 +1,152 @@
+Protocol Buffers - Google's data interchange format
+Copyright 2008 Google Inc.
+http://code.google.com/apis/protocolbuffers/
+
+C++ Installation - Unix
+=======================
+
+To build and install the C++ Protocol Buffer runtime and the Protocol
+Buffer compiler (protoc) execute the following:
+
+ $ ./configure
+ $ make
+ $ make check
+ $ make install
+
+If "make check" fails, you can still install, but it is likely that
+some features of this library will not work correctly on your system.
+Proceed at your own risk.
+
+"make install" may require superuser privileges.
+
+For advanced usage information on configure and make, see INSTALL.txt.
+
+** Hint on install location **
+
+ By default, the package will be installed to /usr/local. However,
+ on many platforms, /usr/local/lib is not part of LD_LIBRARY_PATH.
+ You can add it, but it may be easier to just install to /usr
+ instead. To do this, invoke configure as follows:
+
+ ./configure --prefix=/usr
+
+ If you already built the package with a different prefix, make sure
+ to run "make clean" before building again.
+
+** Compiling dependent packages **
+
+ To compile a package that uses Protocol Buffers, you need to pass
+ various flags to your compiler and linker. As of version 2.2.0,
+ Protocol Buffers integrates with pkg-config to manage this. If you
+ have pkg-config installed, then you can invoke it to get a list of
+ flags like so:
+
+ pkg-config --cflags protobuf # print compiler flags
+ pkg-config --libs protobuf # print linker flags
+ pkg-config --cflags --libs protobuf # print both
+
+ For example:
+
+ c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf`
+
+ Note that packages written prior to the 2.2.0 release of Protocol
+ Buffers may not yet integrate with pkg-config to get flags, and may
+ not pass the correct set of flags to correctly link against
+ libprotobuf. If the package in question uses autoconf, you can
+ often fix the problem by invoking its configure script like:
+
+ configure CXXFLAGS="$(pkg-config --cflags protobuf)" \
+ LIBS="$(pkg-config --libs protobuf)"
+
+ This will force it to use the correct flags.
+
+ If you are writing an autoconf-based package that uses Protocol
+ Buffers, you should probably use the PKG_CHECK_MODULES macro in your
+ configure script like:
+
+ PKG_CHECK_MODULES([protobuf], [protobuf])
+
+ See the pkg-config man page for more info.
+
+ If you only want protobuf-lite, substitute "protobuf-lite" in place
+ of "protobuf" in these examples.
+
+** Note for cross-compiling **
+
+ The makefiles normally invoke the protoc executable that they just
+ built in order to build tests. When cross-compiling, the protoc
+ executable may not be executable on the host machine. In this case,
+ you must build a copy of protoc for the host machine first, then use
+ the --with-protoc option to tell configure to use it instead. For
+ example:
+
+ ./configure --with-protoc=protoc
+
+ This will use the installed protoc (found in your $PATH) instead of
+ trying to execute the one built during the build process. You can
+ also use an executable that hasn't been installed. For example, if
+ you built the protobuf package for your host machine in ../host,
+ you might do:
+
+ ./configure --with-protoc=../host/src/protoc
+
+ Either way, you must make sure that the protoc executable you use
+ has the same version as the protobuf source code you are trying to
+ use it with.
+
+** Note for Solaris users **
+
+ Solaris 10 x86 has a bug that will make linking fail, complaining
+ about libstdc++.la being invalid. We have included a work-around
+ in this package. To use the work-around, run configure as follows:
+
+ ./configure LDFLAGS=-L$PWD/src/solaris
+
+ See src/solaris/libstdc++.la for more info on this bug.
+
+** Note for HP C++ Tru64 users **
+
+ To compile invoke configure as follows:
+
+ ./configure CXXFLAGS="-O -std ansi -ieee -D__USE_STD_IOSTREAM"
+
+ Also, you will need to use gmake instead of make.
+
+C++ Installation - Windows
+==========================
+
+If you are using Micosoft Visual C++, see vsprojects/readme.txt.
+
+If you are using Cygwin or MinGW, follow the Unix installation
+instructions, above.
+
+Binary Compatibility Warning
+============================
+
+Due to the nature of C++, it is unlikely that any two versions of the
+Protocol Buffers C++ runtime libraries will have compatible ABIs.
+That is, if you linked an executable against an older version of
+libprotobuf, it is unlikely to work with a newer version without
+re-compiling. This problem, when it occurs, will normally be detected
+immediately on startup of your app. Still, you may want to consider
+using static linkage. You can configure this package to install
+static libraries only using:
+
+ ./configure --disable-shared
+
+Java and Python Installation
+============================
+
+The Java and Python runtime libraries for Protocol Buffers are located
+in the java and python directories. See the README file in each
+directory for more information on how to compile and install them.
+Note that both of them require you to first install the Protocol
+Buffer compiler (protoc), which is part of the C++ package.
+
+Usage
+=====
+
+The complete documentation for Protocol Buffers is available via the
+web at:
+
+ http://code.google.com/apis/protocolbuffers/
diff --git a/src/third_party/protobuf/__init__.py b/src/third_party/protobuf/__init__.py
new file mode 100755
index 0000000..139597f
--- /dev/null
+++ b/src/third_party/protobuf/__init__.py
@@ -0,0 +1,2 @@
+
+
diff --git a/src/third_party/protobuf/config.h b/src/third_party/protobuf/config.h
new file mode 100644
index 0000000..439a95b
--- /dev/null
+++ b/src/third_party/protobuf/config.h
@@ -0,0 +1,161 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* the name of <hash_set> */
+#define HASH_MAP_CLASS hash_map
+
+/* the location of <hash_map> */
+#if defined(USE_STLPORT)
+#define HASH_MAP_H <hash_map>
+#else
+#define HASH_MAP_H <ext/hash_map>
+#endif
+
+/* the namespace of hash_map/hash_set */
+#if defined(USE_STLPORT)
+#define HASH_NAMESPACE std
+#else
+#define HASH_NAMESPACE __gnu_cxx
+#endif
+
+/* the name of <hash_set> */
+#define HASH_SET_CLASS hash_set
+
+/* the location of <hash_set> */
+#if defined(USE_STLPORT)
+#define HASH_SET_H <hash_set>
+#else
+#define HASH_SET_H <ext/hash_set>
+#endif
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* define if the compiler has hash_map */
+#define HAVE_HASH_MAP 1
+
+/* define if the compiler has hash_set */
+#define HAVE_HASH_SET 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the `mkdir' function. */
+#define HAVE_MKDIR 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strtol' function. */
+#define HAVE_STRTOL 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Enable classes using zlib compression. */
+#define HAVE_ZLIB 1
+
+#if defined(__LB_SHELL__) || defined(COBALT)
+#undef HAVE_HASH_MAP
+#undef HAVE_HASH_SET
+#endif
+
+/* Name of package */
+#define PACKAGE "protobuf"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "protobuf@googlegroups.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Protocol Buffers"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Protocol Buffers 2.3.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "protobuf"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.3.0"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "2.3.0"
+
+/* Define to 1 if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+/* # undef _ALL_SOURCE */
+#endif
+
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Enable extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
diff --git a/src/third_party/protobuf/descriptor_pb2.py b/src/third_party/protobuf/descriptor_pb2.py
new file mode 100755
index 0000000..cbacd34
--- /dev/null
+++ b/src/third_party/protobuf/descriptor_pb2.py
@@ -0,0 +1,1172 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+
+from google.protobuf import descriptor
+from google.protobuf import message
+from google.protobuf import reflection
+# @@protoc_insertion_point(imports)
+
+
+DESCRIPTOR = descriptor.FileDescriptor(
+ name='google/protobuf/descriptor.proto',
+ package='google.protobuf',
+ serialized_pb='\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xdc\x02\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\"\xa9\x03\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x1a,\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"\x94\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"\x8c\x01\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x90\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptions\"\x7f\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\"\xa4\x03\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12!\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x04true\x12#\n\x15java_generic_services\x18\x11 \x01(\x08:\x04true\x12!\n\x13py_generic_services\x18\x12 \x01(\x08:\x04true\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xb8\x01\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x94\x02\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x1c\n\x14\x65xperimental_map_key\x18\t \x01(\t\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"]\n\x0b\x45numOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"b\n\x10\x45numValueOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"`\n\x0eServiceOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"_\n\rMethodOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x85\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\x42)\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01')
+
+
+
+_FIELDDESCRIPTORPROTO_TYPE = descriptor.EnumDescriptor(
+ name='Type',
+ full_name='google.protobuf.FieldDescriptorProto.Type',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ descriptor.EnumValueDescriptor(
+ name='TYPE_DOUBLE', index=0, number=1,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_FLOAT', index=1, number=2,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_INT64', index=2, number=3,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_UINT64', index=3, number=4,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_INT32', index=4, number=5,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_FIXED64', index=5, number=6,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_FIXED32', index=6, number=7,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_BOOL', index=7, number=8,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_STRING', index=8, number=9,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_GROUP', index=9, number=10,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_MESSAGE', index=10, number=11,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_BYTES', index=11, number=12,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_UINT32', index=12, number=13,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_ENUM', index=13, number=14,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_SFIXED32', index=14, number=15,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_SFIXED64', index=15, number=16,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_SINT32', index=16, number=17,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='TYPE_SINT64', index=17, number=18,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=1187,
+ serialized_end=1497,
+)
+
+_FIELDDESCRIPTORPROTO_LABEL = descriptor.EnumDescriptor(
+ name='Label',
+ full_name='google.protobuf.FieldDescriptorProto.Label',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ descriptor.EnumValueDescriptor(
+ name='LABEL_OPTIONAL', index=0, number=1,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='LABEL_REQUIRED', index=1, number=2,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='LABEL_REPEATED', index=2, number=3,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=1499,
+ serialized_end=1566,
+)
+
+_FILEOPTIONS_OPTIMIZEMODE = descriptor.EnumDescriptor(
+ name='OptimizeMode',
+ full_name='google.protobuf.FileOptions.OptimizeMode',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ descriptor.EnumValueDescriptor(
+ name='SPEED', index=0, number=1,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='CODE_SIZE', index=1, number=2,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='LITE_RUNTIME', index=2, number=3,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=2449,
+ serialized_end=2507,
+)
+
+_FIELDOPTIONS_CTYPE = descriptor.EnumDescriptor(
+ name='CType',
+ full_name='google.protobuf.FieldOptions.CType',
+ filename=None,
+ file=DESCRIPTOR,
+ values=[
+ descriptor.EnumValueDescriptor(
+ name='STRING', index=0, number=0,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='CORD', index=1, number=1,
+ options=None,
+ type=None),
+ descriptor.EnumValueDescriptor(
+ name='STRING_PIECE', index=2, number=2,
+ options=None,
+ type=None),
+ ],
+ containing_type=None,
+ options=None,
+ serialized_start=2926,
+ serialized_end=2973,
+)
+
+
+_FILEDESCRIPTORSET = descriptor.Descriptor(
+ name='FileDescriptorSet',
+ full_name='google.protobuf.FileDescriptorSet',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='file', full_name='google.protobuf.FileDescriptorSet.file', index=0,
+ number=1, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=53,
+ serialized_end=124,
+)
+
+
+_FILEDESCRIPTORPROTO = descriptor.Descriptor(
+ name='FileDescriptorProto',
+ full_name='google.protobuf.FileDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.FileDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='package', full_name='google.protobuf.FileDescriptorProto.package', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='dependency', full_name='google.protobuf.FileDescriptorProto.dependency', index=2,
+ number=3, type=9, cpp_type=9, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='message_type', full_name='google.protobuf.FileDescriptorProto.message_type', index=3,
+ number=4, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='enum_type', full_name='google.protobuf.FileDescriptorProto.enum_type', index=4,
+ number=5, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='service', full_name='google.protobuf.FileDescriptorProto.service', index=5,
+ number=6, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='extension', full_name='google.protobuf.FileDescriptorProto.extension', index=6,
+ number=7, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.FileDescriptorProto.options', index=7,
+ number=8, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=127,
+ serialized_end=475,
+)
+
+
+_DESCRIPTORPROTO_EXTENSIONRANGE = descriptor.Descriptor(
+ name='ExtensionRange',
+ full_name='google.protobuf.DescriptorProto.ExtensionRange',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='start', full_name='google.protobuf.DescriptorProto.ExtensionRange.start', index=0,
+ number=1, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='end', full_name='google.protobuf.DescriptorProto.ExtensionRange.end', index=1,
+ number=2, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=859,
+ serialized_end=903,
+)
+
+_DESCRIPTORPROTO = descriptor.Descriptor(
+ name='DescriptorProto',
+ full_name='google.protobuf.DescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.DescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='field', full_name='google.protobuf.DescriptorProto.field', index=1,
+ number=2, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='extension', full_name='google.protobuf.DescriptorProto.extension', index=2,
+ number=6, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='nested_type', full_name='google.protobuf.DescriptorProto.nested_type', index=3,
+ number=3, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='enum_type', full_name='google.protobuf.DescriptorProto.enum_type', index=4,
+ number=4, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='extension_range', full_name='google.protobuf.DescriptorProto.extension_range', index=5,
+ number=5, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.DescriptorProto.options', index=6,
+ number=7, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[_DESCRIPTORPROTO_EXTENSIONRANGE, ],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=478,
+ serialized_end=903,
+)
+
+
+_FIELDDESCRIPTORPROTO = descriptor.Descriptor(
+ name='FieldDescriptorProto',
+ full_name='google.protobuf.FieldDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.FieldDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='number', full_name='google.protobuf.FieldDescriptorProto.number', index=1,
+ number=3, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='label', full_name='google.protobuf.FieldDescriptorProto.label', index=2,
+ number=4, type=14, cpp_type=8, label=1,
+ has_default_value=False, default_value=1,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='type', full_name='google.protobuf.FieldDescriptorProto.type', index=3,
+ number=5, type=14, cpp_type=8, label=1,
+ has_default_value=False, default_value=1,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='type_name', full_name='google.protobuf.FieldDescriptorProto.type_name', index=4,
+ number=6, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='extendee', full_name='google.protobuf.FieldDescriptorProto.extendee', index=5,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='default_value', full_name='google.protobuf.FieldDescriptorProto.default_value', index=6,
+ number=7, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.FieldDescriptorProto.options', index=7,
+ number=8, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ _FIELDDESCRIPTORPROTO_TYPE,
+ _FIELDDESCRIPTORPROTO_LABEL,
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=906,
+ serialized_end=1566,
+)
+
+
+_ENUMDESCRIPTORPROTO = descriptor.Descriptor(
+ name='EnumDescriptorProto',
+ full_name='google.protobuf.EnumDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.EnumDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='value', full_name='google.protobuf.EnumDescriptorProto.value', index=1,
+ number=2, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.EnumDescriptorProto.options', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=1569,
+ serialized_end=1709,
+)
+
+
+_ENUMVALUEDESCRIPTORPROTO = descriptor.Descriptor(
+ name='EnumValueDescriptorProto',
+ full_name='google.protobuf.EnumValueDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.EnumValueDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='number', full_name='google.protobuf.EnumValueDescriptorProto.number', index=1,
+ number=2, type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.EnumValueDescriptorProto.options', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=1711,
+ serialized_end=1819,
+)
+
+
+_SERVICEDESCRIPTORPROTO = descriptor.Descriptor(
+ name='ServiceDescriptorProto',
+ full_name='google.protobuf.ServiceDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.ServiceDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='method', full_name='google.protobuf.ServiceDescriptorProto.method', index=1,
+ number=2, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.ServiceDescriptorProto.options', index=2,
+ number=3, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=1822,
+ serialized_end=1966,
+)
+
+
+_METHODDESCRIPTORPROTO = descriptor.Descriptor(
+ name='MethodDescriptorProto',
+ full_name='google.protobuf.MethodDescriptorProto',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.MethodDescriptorProto.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='input_type', full_name='google.protobuf.MethodDescriptorProto.input_type', index=1,
+ number=2, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='output_type', full_name='google.protobuf.MethodDescriptorProto.output_type', index=2,
+ number=3, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='options', full_name='google.protobuf.MethodDescriptorProto.options', index=3,
+ number=4, type=11, cpp_type=10, label=1,
+ has_default_value=False, default_value=None,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=1968,
+ serialized_end=2095,
+)
+
+
+_FILEOPTIONS = descriptor.Descriptor(
+ name='FileOptions',
+ full_name='google.protobuf.FileOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='java_package', full_name='google.protobuf.FileOptions.java_package', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='java_outer_classname', full_name='google.protobuf.FileOptions.java_outer_classname', index=1,
+ number=8, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='java_multiple_files', full_name='google.protobuf.FileOptions.java_multiple_files', index=2,
+ number=10, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='optimize_for', full_name='google.protobuf.FileOptions.optimize_for', index=3,
+ number=9, type=14, cpp_type=8, label=1,
+ has_default_value=True, default_value=1,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='cc_generic_services', full_name='google.protobuf.FileOptions.cc_generic_services', index=4,
+ number=16, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=True,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='java_generic_services', full_name='google.protobuf.FileOptions.java_generic_services', index=5,
+ number=17, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=True,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='py_generic_services', full_name='google.protobuf.FileOptions.py_generic_services', index=6,
+ number=18, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=True,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.FileOptions.uninterpreted_option', index=7,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ _FILEOPTIONS_OPTIMIZEMODE,
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=2098,
+ serialized_end=2518,
+)
+
+
+_MESSAGEOPTIONS = descriptor.Descriptor(
+ name='MessageOptions',
+ full_name='google.protobuf.MessageOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='message_set_wire_format', full_name='google.protobuf.MessageOptions.message_set_wire_format', index=0,
+ number=1, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='no_standard_descriptor_accessor', full_name='google.protobuf.MessageOptions.no_standard_descriptor_accessor', index=1,
+ number=2, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.MessageOptions.uninterpreted_option', index=2,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=2521,
+ serialized_end=2705,
+)
+
+
+_FIELDOPTIONS = descriptor.Descriptor(
+ name='FieldOptions',
+ full_name='google.protobuf.FieldOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='ctype', full_name='google.protobuf.FieldOptions.ctype', index=0,
+ number=1, type=14, cpp_type=8, label=1,
+ has_default_value=True, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='packed', full_name='google.protobuf.FieldOptions.packed', index=1,
+ number=2, type=8, cpp_type=7, label=1,
+ has_default_value=False, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='deprecated', full_name='google.protobuf.FieldOptions.deprecated', index=2,
+ number=3, type=8, cpp_type=7, label=1,
+ has_default_value=True, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='experimental_map_key', full_name='google.protobuf.FieldOptions.experimental_map_key', index=3,
+ number=9, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.FieldOptions.uninterpreted_option', index=4,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ _FIELDOPTIONS_CTYPE,
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=2708,
+ serialized_end=2984,
+)
+
+
+_ENUMOPTIONS = descriptor.Descriptor(
+ name='EnumOptions',
+ full_name='google.protobuf.EnumOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.EnumOptions.uninterpreted_option', index=0,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=2986,
+ serialized_end=3079,
+)
+
+
+_ENUMVALUEOPTIONS = descriptor.Descriptor(
+ name='EnumValueOptions',
+ full_name='google.protobuf.EnumValueOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.EnumValueOptions.uninterpreted_option', index=0,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=3081,
+ serialized_end=3179,
+)
+
+
+_SERVICEOPTIONS = descriptor.Descriptor(
+ name='ServiceOptions',
+ full_name='google.protobuf.ServiceOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.ServiceOptions.uninterpreted_option', index=0,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=3181,
+ serialized_end=3277,
+)
+
+
+_METHODOPTIONS = descriptor.Descriptor(
+ name='MethodOptions',
+ full_name='google.protobuf.MethodOptions',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='uninterpreted_option', full_name='google.protobuf.MethodOptions.uninterpreted_option', index=0,
+ number=999, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=True,
+ extension_ranges=[(1000, 536870912), ],
+ serialized_start=3279,
+ serialized_end=3374,
+)
+
+
+_UNINTERPRETEDOPTION_NAMEPART = descriptor.Descriptor(
+ name='NamePart',
+ full_name='google.protobuf.UninterpretedOption.NamePart',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name_part', full_name='google.protobuf.UninterpretedOption.NamePart.name_part', index=0,
+ number=1, type=9, cpp_type=9, label=2,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='is_extension', full_name='google.protobuf.UninterpretedOption.NamePart.is_extension', index=1,
+ number=2, type=8, cpp_type=7, label=2,
+ has_default_value=False, default_value=False,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=3587,
+ serialized_end=3638,
+)
+
+_UNINTERPRETEDOPTION = descriptor.Descriptor(
+ name='UninterpretedOption',
+ full_name='google.protobuf.UninterpretedOption',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='name', full_name='google.protobuf.UninterpretedOption.name', index=0,
+ number=2, type=11, cpp_type=10, label=3,
+ has_default_value=False, default_value=[],
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='identifier_value', full_name='google.protobuf.UninterpretedOption.identifier_value', index=1,
+ number=3, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=unicode("", "utf-8"),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='positive_int_value', full_name='google.protobuf.UninterpretedOption.positive_int_value', index=2,
+ number=4, type=4, cpp_type=4, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='negative_int_value', full_name='google.protobuf.UninterpretedOption.negative_int_value', index=3,
+ number=5, type=3, cpp_type=2, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='double_value', full_name='google.protobuf.UninterpretedOption.double_value', index=4,
+ number=6, type=1, cpp_type=5, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ descriptor.FieldDescriptor(
+ name='string_value', full_name='google.protobuf.UninterpretedOption.string_value', index=5,
+ number=7, type=12, cpp_type=9, label=1,
+ has_default_value=False, default_value="",
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[_UNINTERPRETEDOPTION_NAMEPART, ],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ extension_ranges=[],
+ serialized_start=3377,
+ serialized_end=3638,
+)
+
+
+_FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['message_type'].message_type = _DESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['service'].message_type = _SERVICEDESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO
+_FILEDESCRIPTORPROTO.fields_by_name['options'].message_type = _FILEOPTIONS
+_DESCRIPTORPROTO_EXTENSIONRANGE.containing_type = _DESCRIPTORPROTO;
+_DESCRIPTORPROTO.fields_by_name['field'].message_type = _FIELDDESCRIPTORPROTO
+_DESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO
+_DESCRIPTORPROTO.fields_by_name['nested_type'].message_type = _DESCRIPTORPROTO
+_DESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO
+_DESCRIPTORPROTO.fields_by_name['extension_range'].message_type = _DESCRIPTORPROTO_EXTENSIONRANGE
+_DESCRIPTORPROTO.fields_by_name['options'].message_type = _MESSAGEOPTIONS
+_FIELDDESCRIPTORPROTO.fields_by_name['label'].enum_type = _FIELDDESCRIPTORPROTO_LABEL
+_FIELDDESCRIPTORPROTO.fields_by_name['type'].enum_type = _FIELDDESCRIPTORPROTO_TYPE
+_FIELDDESCRIPTORPROTO.fields_by_name['options'].message_type = _FIELDOPTIONS
+_FIELDDESCRIPTORPROTO_TYPE.containing_type = _FIELDDESCRIPTORPROTO;
+_FIELDDESCRIPTORPROTO_LABEL.containing_type = _FIELDDESCRIPTORPROTO;
+_ENUMDESCRIPTORPROTO.fields_by_name['value'].message_type = _ENUMVALUEDESCRIPTORPROTO
+_ENUMDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMOPTIONS
+_ENUMVALUEDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMVALUEOPTIONS
+_SERVICEDESCRIPTORPROTO.fields_by_name['method'].message_type = _METHODDESCRIPTORPROTO
+_SERVICEDESCRIPTORPROTO.fields_by_name['options'].message_type = _SERVICEOPTIONS
+_METHODDESCRIPTORPROTO.fields_by_name['options'].message_type = _METHODOPTIONS
+_FILEOPTIONS.fields_by_name['optimize_for'].enum_type = _FILEOPTIONS_OPTIMIZEMODE
+_FILEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_FILEOPTIONS_OPTIMIZEMODE.containing_type = _FILEOPTIONS;
+_MESSAGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_FIELDOPTIONS.fields_by_name['ctype'].enum_type = _FIELDOPTIONS_CTYPE
+_FIELDOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_FIELDOPTIONS_CTYPE.containing_type = _FIELDOPTIONS;
+_ENUMOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_ENUMVALUEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_SERVICEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_METHODOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION
+_UNINTERPRETEDOPTION_NAMEPART.containing_type = _UNINTERPRETEDOPTION;
+_UNINTERPRETEDOPTION.fields_by_name['name'].message_type = _UNINTERPRETEDOPTION_NAMEPART
+
+class FileDescriptorSet(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FILEDESCRIPTORSET
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
+
+class FileDescriptorProto(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FILEDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
+
+class DescriptorProto(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+
+ class ExtensionRange(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _DESCRIPTORPROTO_EXTENSIONRANGE
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
+ DESCRIPTOR = _DESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
+
+class FieldDescriptorProto(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FIELDDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
+
+class EnumDescriptorProto(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _ENUMDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
+
+class EnumValueDescriptorProto(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _ENUMVALUEDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
+
+class ServiceDescriptorProto(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _SERVICEDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
+
+class MethodDescriptorProto(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _METHODDESCRIPTORPROTO
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
+
+class FileOptions(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FILEOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
+
+class MessageOptions(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _MESSAGEOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
+
+class FieldOptions(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _FIELDOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
+
+class EnumOptions(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _ENUMOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
+
+class EnumValueOptions(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _ENUMVALUEOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
+
+class ServiceOptions(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _SERVICEOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
+
+class MethodOptions(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _METHODOPTIONS
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
+
+class UninterpretedOption(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+
+ class NamePart(message.Message):
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ DESCRIPTOR = _UNINTERPRETEDOPTION_NAMEPART
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
+ DESCRIPTOR = _UNINTERPRETEDOPTION
+
+ # @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/third_party/protobuf/java/README.txt b/src/third_party/protobuf/java/README.txt
new file mode 100644
index 0000000..3ed06a1
--- /dev/null
+++ b/src/third_party/protobuf/java/README.txt
@@ -0,0 +1,96 @@
+Protocol Buffers - Google's data interchange format
+Copyright 2008 Google Inc.
+
+This directory contains the Java Protocol Buffers runtime library.
+
+Installation - With Maven
+=========================
+
+The Protocol Buffers build is managed using Maven. If you would
+rather build without Maven, see below.
+
+1) Install Apache Maven if you don't have it:
+
+ http://maven.apache.org/
+
+2) Build the C++ code, or obtain a binary distribution of protoc. If
+ you install a binary distribution, make sure that it is the same
+ version as this package. If in doubt, run:
+
+ $ protoc --version
+
+ You will need to place the protoc executable in ../src. (If you
+ built it yourself, it should already be there.)
+
+3) Run the tests:
+
+ $ mvn test
+
+ If some tests fail, this library may not work correctly on your
+ system. Continue at your own risk.
+
+4) Install the library into your Maven repository:
+
+ $ mvn install
+
+5) If you do not use Maven to manage your own build, you can build a
+ .jar file to use:
+
+ $ mvn package
+
+ The .jar will be placed in the "target" directory.
+
+Installation - 'Lite' Version - With Maven
+==========================================
+
+Building the 'lite' version of the Java Protocol Buffers library is
+the same as building the full version, except that all commands are
+run using the 'lite' profile. (see
+http://maven.apache.org/guides/introduction/introduction-to-profiles.html)
+
+E.g. to install the lite version of the jar, you would run:
+
+ $ mvn install -P lite
+
+The resulting artifact has the 'lite' classifier. To reference it
+for dependency resolution, you would specify it as:
+
+ <dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>${version}</version>
+ <classifier>lite</classifier>
+ </dependency>
+
+Installation - Without Maven
+============================
+
+If you would rather not install Maven to build the library, you may
+follow these instructions instead. Note that these instructions skip
+running unit tests.
+
+1) Build the C++ code, or obtain a binary distribution of protoc. If
+ you install a binary distribution, make sure that it is the same
+ version as this package. If in doubt, run:
+
+ $ protoc --version
+
+ If you built the C++ code without installing, the compiler binary
+ should be located in ../src.
+
+2) Invoke protoc to build DescriptorProtos.java:
+
+ $ protoc --java_out=src/main/java -I../src \
+ ../src/google/protobuf/descriptor.proto
+
+3) Compile the code in src/main/java using whatever means you prefer.
+
+4) Install the classes wherever you prefer.
+
+Usage
+=====
+
+The complete documentation for Protocol Buffers is available via the
+web at:
+
+ http://code.google.com/apis/protocolbuffers/
diff --git a/src/third_party/protobuf/java/pom.xml b/src/third_party/protobuf/java/pom.xml
new file mode 100644
index 0000000..e28d6db
--- /dev/null
+++ b/src/third_party/protobuf/java/pom.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.google</groupId>
+ <artifactId>google</artifactId>
+ <version>1</version>
+ </parent>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>2.4.2-pre</version>
+ <packaging>jar</packaging>
+ <name>Protocol Buffer Java API</name>
+ <description>
+ Protocol Buffers are a way of encoding structured data in an efficient yet
+ extensible format.
+ </description>
+ <inceptionYear>2008</inceptionYear>
+ <url>http://code.google.com/p/protobuf</url>
+ <licenses>
+ <license>
+ <name>New BSD license</name>
+ <url>http://www.opensource.org/licenses/bsd-license.php</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+ <scm>
+ <url>http://code.google.com/p/protobuf/source/browse</url>
+ <connection>
+ scm:svn:http://protobuf.googlecode.com/svn/trunk/
+ </connection>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>2.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymockclassextension</artifactId>
+ <version>2.2.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/*Test.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-sources</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="target/generated-sources" />
+ <exec executable="../src/protoc">
+ <arg value="--java_out=target/generated-sources" />
+ <arg value="--proto_path=../src" />
+ <arg value="../src/google/protobuf/descriptor.proto" />
+ </exec>
+ </tasks>
+ <sourceRoot>target/generated-sources</sourceRoot>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>generate-test-sources</id>
+ <phase>generate-test-sources</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="target/generated-test-sources" />
+ <exec executable="../src/protoc">
+ <arg value="--java_out=target/generated-test-sources" />
+ <arg value="--proto_path=../src" />
+ <arg value="--proto_path=src/test/java" />
+ <arg value="../src/google/protobuf/unittest.proto" />
+ <arg value="../src/google/protobuf/unittest_import.proto" />
+ <arg value="../src/google/protobuf/unittest_mset.proto" />
+ <arg
+ value="src/test/java/com/google/protobuf/multiple_files_test.proto" />
+ <arg value="src/test/java/com/google/protobuf/nested_builders_test.proto" />
+ <arg value="src/test/java/com/google/protobuf/nested_extension.proto" />
+ <arg value="src/test/java/com/google/protobuf/nested_extension_lite.proto" />
+ <arg value="src/test/java/com/google/protobuf/non_nested_extension.proto" />
+ <arg value="src/test/java/com/google/protobuf/non_nested_extension_lite.proto" />
+ <arg value="src/test/java/com/google/protobuf/test_bad_identifiers.proto" />
+ <arg
+ value="../src/google/protobuf/unittest_optimize_for.proto" />
+ <arg
+ value="../src/google/protobuf/unittest_custom_options.proto" />
+ <arg value="../src/google/protobuf/unittest_lite.proto" />
+ <arg value="../src/google/protobuf/unittest_import_lite.proto" />
+ <arg value="../src/google/protobuf/unittest_lite_imports_nonlite.proto" />
+ <arg value="../src/google/protobuf/unittest_enormous_descriptor.proto" />
+ <arg value="../src/google/protobuf/unittest_no_generic_services.proto" />
+ </exec>
+ </tasks>
+ <testSourceRoot>target/generated-test-sources</testSourceRoot>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>lite</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/AbstractMessageLite.java</include>
+ <include>**/ByteString.java</include>
+ <include>**/CodedInputStream.java</include>
+ <include>**/CodedOutputStream.java</include>
+ <include>**/ExtensionRegistryLite.java</include>
+ <include>**/FieldSet.java</include>
+ <include>**/GeneratedMessageLite.java</include>
+ <include>**/Internal.java</include>
+ <include>**/InvalidProtocolBufferException.java</include>
+ <include>**/LazyStringArrayList.java</include>
+ <include>**/LazyStringList.java</include>
+ <include>**/MessageLite.java</include>
+ <include>**/MessageLiteOrBuilder.java</include>
+ <include>**/SmallSortedMap.java</include>
+ <include>**/UninitializedMessageException.java</include>
+ <include>**/UnmodifiableLazyStringList.java</include>
+ <include>**/WireFormat.java</include>
+ </includes>
+ <testIncludes>
+ <testInclude>**/LiteTest.java</testInclude>
+ <testInclude>**/*Lite.java</testInclude>
+ </testIncludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/LiteTest.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <classifier>lite</classifier>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java
new file mode 100644
index 0000000..b9d8301
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -0,0 +1,764 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Internal.EnumLite;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A partial implementation of the {@link Message} interface which implements
+ * as many methods of that interface as possible in terms of other methods.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class AbstractMessage extends AbstractMessageLite
+ implements Message {
+ @SuppressWarnings("unchecked")
+ public boolean isInitialized() {
+ // Check that all required fields are present.
+ for (final FieldDescriptor field : getDescriptorForType().getFields()) {
+ if (field.isRequired()) {
+ if (!hasField(field)) {
+ return false;
+ }
+ }
+ }
+
+ // Check that embedded messages are initialized.
+ for (final Map.Entry<FieldDescriptor, Object> entry :
+ getAllFields().entrySet()) {
+ final FieldDescriptor field = entry.getKey();
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ for (final Message element : (List<Message>) entry.getValue()) {
+ if (!element.isInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (!((Message) entry.getValue()).isInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public final String toString() {
+ return TextFormat.printToString(this);
+ }
+
+ public void writeTo(final CodedOutputStream output) throws IOException {
+ final boolean isMessageSet =
+ getDescriptorForType().getOptions().getMessageSetWireFormat();
+
+ for (final Map.Entry<FieldDescriptor, Object> entry :
+ getAllFields().entrySet()) {
+ final FieldDescriptor field = entry.getKey();
+ final Object value = entry.getValue();
+ if (isMessageSet && field.isExtension() &&
+ field.getType() == FieldDescriptor.Type.MESSAGE &&
+ !field.isRepeated()) {
+ output.writeMessageSetExtension(field.getNumber(), (Message) value);
+ } else {
+ FieldSet.writeField(field, value, output);
+ }
+ }
+
+ final UnknownFieldSet unknownFields = getUnknownFields();
+ if (isMessageSet) {
+ unknownFields.writeAsMessageSetTo(output);
+ } else {
+ unknownFields.writeTo(output);
+ }
+ }
+
+ private int memoizedSize = -1;
+
+ public int getSerializedSize() {
+ int size = memoizedSize;
+ if (size != -1) {
+ return size;
+ }
+
+ size = 0;
+ final boolean isMessageSet =
+ getDescriptorForType().getOptions().getMessageSetWireFormat();
+
+ for (final Map.Entry<FieldDescriptor, Object> entry :
+ getAllFields().entrySet()) {
+ final FieldDescriptor field = entry.getKey();
+ final Object value = entry.getValue();
+ if (isMessageSet && field.isExtension() &&
+ field.getType() == FieldDescriptor.Type.MESSAGE &&
+ !field.isRepeated()) {
+ size += CodedOutputStream.computeMessageSetExtensionSize(
+ field.getNumber(), (Message) value);
+ } else {
+ size += FieldSet.computeFieldSize(field, value);
+ }
+ }
+
+ final UnknownFieldSet unknownFields = getUnknownFields();
+ if (isMessageSet) {
+ size += unknownFields.getSerializedSizeAsMessageSet();
+ } else {
+ size += unknownFields.getSerializedSize();
+ }
+
+ memoizedSize = size;
+ return size;
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (other == this) {
+ return true;
+ }
+ if (!(other instanceof Message)) {
+ return false;
+ }
+ final Message otherMessage = (Message) other;
+ if (getDescriptorForType() != otherMessage.getDescriptorForType()) {
+ return false;
+ }
+ return getAllFields().equals(otherMessage.getAllFields()) &&
+ getUnknownFields().equals(otherMessage.getUnknownFields());
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 41;
+ hash = (19 * hash) + getDescriptorForType().hashCode();
+ hash = hashFields(hash, getAllFields());
+ hash = (29 * hash) + getUnknownFields().hashCode();
+ return hash;
+ }
+
+ /** Get a hash code for given fields and values, using the given seed. */
+ @SuppressWarnings("unchecked")
+ protected int hashFields(int hash, Map<FieldDescriptor, Object> map) {
+ for (Map.Entry<FieldDescriptor, Object> entry : map.entrySet()) {
+ FieldDescriptor field = entry.getKey();
+ Object value = entry.getValue();
+ hash = (37 * hash) + field.getNumber();
+ if (field.getType() != FieldDescriptor.Type.ENUM){
+ hash = (53 * hash) + value.hashCode();
+ } else if (field.isRepeated()) {
+ List<? extends EnumLite> list = (List<? extends EnumLite>) value;
+ hash = (53 * hash) + hashEnumList(list);
+ } else {
+ hash = (53 * hash) + hashEnum((EnumLite) value);
+ }
+ }
+ return hash;
+ }
+
+ /**
+ * Helper method for implementing {@link Message#hashCode()}.
+ * @see Boolean#hashCode()
+ */
+ protected static int hashLong(long n) {
+ return (int) (n ^ (n >>> 32));
+ }
+
+ /**
+ * Helper method for implementing {@link Message#hashCode()}.
+ * @see Boolean#hashCode()
+ */
+ protected static int hashBoolean(boolean b) {
+ return b ? 1231 : 1237;
+ }
+
+ /**
+ * Helper method for implementing {@link Message#hashCode()}.
+ * <p>
+ * This is needed because {@link java.lang.Enum#hashCode()} is final, but we
+ * need to use the field number as the hash code to ensure compatibility
+ * between statically and dynamically generated enum objects.
+ */
+ protected static int hashEnum(EnumLite e) {
+ return e.getNumber();
+ }
+
+ /** Helper method for implementing {@link Message#hashCode()}. */
+ protected static int hashEnumList(List<? extends EnumLite> list) {
+ int hash = 1;
+ for (EnumLite e : list) {
+ hash = 31 * hash + hashEnum(e);
+ }
+ return hash;
+ }
+
+ // =================================================================
+
+ /**
+ * A partial implementation of the {@link Message.Builder} interface which
+ * implements as many methods of that interface as possible in terms of
+ * other methods.
+ */
+ @SuppressWarnings("unchecked")
+ public static abstract class Builder<BuilderType extends Builder>
+ extends AbstractMessageLite.Builder<BuilderType>
+ implements Message.Builder {
+ // The compiler produces an error if this is not declared explicitly.
+ @Override
+ public abstract BuilderType clone();
+
+ public BuilderType clear() {
+ for (final Map.Entry<FieldDescriptor, Object> entry :
+ getAllFields().entrySet()) {
+ clearField(entry.getKey());
+ }
+ return (BuilderType) this;
+ }
+
+ public BuilderType mergeFrom(final Message other) {
+ if (other.getDescriptorForType() != getDescriptorForType()) {
+ throw new IllegalArgumentException(
+ "mergeFrom(Message) can only merge messages of the same type.");
+ }
+
+ // Note: We don't attempt to verify that other's fields have valid
+ // types. Doing so would be a losing battle. We'd have to verify
+ // all sub-messages as well, and we'd have to make copies of all of
+ // them to insure that they don't change after verification (since
+ // the Message interface itself cannot enforce immutability of
+ // implementations).
+ // TODO(kenton): Provide a function somewhere called makeDeepCopy()
+ // which allows people to make secure deep copies of messages.
+
+ for (final Map.Entry<FieldDescriptor, Object> entry :
+ other.getAllFields().entrySet()) {
+ final FieldDescriptor field = entry.getKey();
+ if (field.isRepeated()) {
+ for (final Object element : (List)entry.getValue()) {
+ addRepeatedField(field, element);
+ }
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ final Message existingValue = (Message)getField(field);
+ if (existingValue == existingValue.getDefaultInstanceForType()) {
+ setField(field, entry.getValue());
+ } else {
+ setField(field,
+ existingValue.newBuilderForType()
+ .mergeFrom(existingValue)
+ .mergeFrom((Message)entry.getValue())
+ .build());
+ }
+ } else {
+ setField(field, entry.getValue());
+ }
+ }
+
+ mergeUnknownFields(other.getUnknownFields());
+
+ return (BuilderType) this;
+ }
+
+ @Override
+ public BuilderType mergeFrom(final CodedInputStream input)
+ throws IOException {
+ return mergeFrom(input, ExtensionRegistry.getEmptyRegistry());
+ }
+
+ @Override
+ public BuilderType mergeFrom(
+ final CodedInputStream input,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ final UnknownFieldSet.Builder unknownFields =
+ UnknownFieldSet.newBuilder(getUnknownFields());
+ while (true) {
+ final int tag = input.readTag();
+ if (tag == 0) {
+ break;
+ }
+
+ if (!mergeFieldFrom(input, unknownFields, extensionRegistry,
+ this, tag)) {
+ // end group tag
+ break;
+ }
+ }
+ setUnknownFields(unknownFields.build());
+ return (BuilderType) this;
+ }
+
+ /**
+ * Like {@link #mergeFrom(CodedInputStream, UnknownFieldSet.Builder,
+ * ExtensionRegistryLite, Message.Builder)}, but parses a single field.
+ * Package-private because it is used by GeneratedMessage.ExtendableMessage.
+ * @param tag The tag, which should have already been read.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ static boolean mergeFieldFrom(
+ final CodedInputStream input,
+ final UnknownFieldSet.Builder unknownFields,
+ final ExtensionRegistryLite extensionRegistry,
+ final Message.Builder builder,
+ final int tag) throws IOException {
+ final Descriptor type = builder.getDescriptorForType();
+
+ if (type.getOptions().getMessageSetWireFormat() &&
+ tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
+ mergeMessageSetExtensionFromCodedStream(
+ input, unknownFields, extensionRegistry, builder);
+ return true;
+ }
+
+ final int wireType = WireFormat.getTagWireType(tag);
+ final int fieldNumber = WireFormat.getTagFieldNumber(tag);
+
+ final FieldDescriptor field;
+ Message defaultInstance = null;
+
+ if (type.isExtensionNumber(fieldNumber)) {
+ // extensionRegistry may be either ExtensionRegistry or
+ // ExtensionRegistryLite. Since the type we are parsing is a full
+ // message, only a full ExtensionRegistry could possibly contain
+ // extensions of it. Otherwise we will treat the registry as if it
+ // were empty.
+ if (extensionRegistry instanceof ExtensionRegistry) {
+ final ExtensionRegistry.ExtensionInfo extension =
+ ((ExtensionRegistry) extensionRegistry)
+ .findExtensionByNumber(type, fieldNumber);
+ if (extension == null) {
+ field = null;
+ } else {
+ field = extension.descriptor;
+ defaultInstance = extension.defaultInstance;
+ if (defaultInstance == null &&
+ field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ throw new IllegalStateException(
+ "Message-typed extension lacked default instance: " +
+ field.getFullName());
+ }
+ }
+ } else {
+ field = null;
+ }
+ } else {
+ field = type.findFieldByNumber(fieldNumber);
+ }
+
+ boolean unknown = false;
+ boolean packed = false;
+ if (field == null) {
+ unknown = true; // Unknown field.
+ } else if (wireType == FieldSet.getWireFormatForFieldType(
+ field.getLiteType(),
+ false /* isPacked */)) {
+ packed = false;
+ } else if (field.isPackable() &&
+ wireType == FieldSet.getWireFormatForFieldType(
+ field.getLiteType(),
+ true /* isPacked */)) {
+ packed = true;
+ } else {
+ unknown = true; // Unknown wire type.
+ }
+
+ if (unknown) { // Unknown field or wrong wire type. Skip.
+ return unknownFields.mergeFieldFrom(tag, input);
+ }
+
+ if (packed) {
+ final int length = input.readRawVarint32();
+ final int limit = input.pushLimit(length);
+ if (field.getLiteType() == WireFormat.FieldType.ENUM) {
+ while (input.getBytesUntilLimit() > 0) {
+ final int rawValue = input.readEnum();
+ final Object value = field.getEnumType().findValueByNumber(rawValue);
+ if (value == null) {
+ // If the number isn't recognized as a valid value for this
+ // enum, drop it (don't even add it to unknownFields).
+ return true;
+ }
+ builder.addRepeatedField(field, value);
+ }
+ } else {
+ while (input.getBytesUntilLimit() > 0) {
+ final Object value =
+ FieldSet.readPrimitiveField(input, field.getLiteType());
+ builder.addRepeatedField(field, value);
+ }
+ }
+ input.popLimit(limit);
+ } else {
+ final Object value;
+ switch (field.getType()) {
+ case GROUP: {
+ final Message.Builder subBuilder;
+ if (defaultInstance != null) {
+ subBuilder = defaultInstance.newBuilderForType();
+ } else {
+ subBuilder = builder.newBuilderForField(field);
+ }
+ if (!field.isRepeated()) {
+ subBuilder.mergeFrom((Message) builder.getField(field));
+ }
+ input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
+ value = subBuilder.build();
+ break;
+ }
+ case MESSAGE: {
+ final Message.Builder subBuilder;
+ if (defaultInstance != null) {
+ subBuilder = defaultInstance.newBuilderForType();
+ } else {
+ subBuilder = builder.newBuilderForField(field);
+ }
+ if (!field.isRepeated()) {
+ subBuilder.mergeFrom((Message) builder.getField(field));
+ }
+ input.readMessage(subBuilder, extensionRegistry);
+ value = subBuilder.build();
+ break;
+ }
+ case ENUM:
+ final int rawValue = input.readEnum();
+ value = field.getEnumType().findValueByNumber(rawValue);
+ // If the number isn't recognized as a valid value for this enum,
+ // drop it.
+ if (value == null) {
+ unknownFields.mergeVarintField(fieldNumber, rawValue);
+ return true;
+ }
+ break;
+ default:
+ value = FieldSet.readPrimitiveField(input, field.getLiteType());
+ break;
+ }
+
+ if (field.isRepeated()) {
+ builder.addRepeatedField(field, value);
+ } else {
+ builder.setField(field, value);
+ }
+ }
+
+ return true;
+ }
+
+ /** Called by {@code #mergeFieldFrom()} to parse a MessageSet extension. */
+ private static void mergeMessageSetExtensionFromCodedStream(
+ final CodedInputStream input,
+ final UnknownFieldSet.Builder unknownFields,
+ final ExtensionRegistryLite extensionRegistry,
+ final Message.Builder builder) throws IOException {
+ final Descriptor type = builder.getDescriptorForType();
+
+ // The wire format for MessageSet is:
+ // message MessageSet {
+ // repeated group Item = 1 {
+ // required int32 typeId = 2;
+ // required bytes message = 3;
+ // }
+ // }
+ // "typeId" is the extension's field number. The extension can only be
+ // a message type, where "message" contains the encoded bytes of that
+ // message.
+ //
+ // In practice, we will probably never see a MessageSet item in which
+ // the message appears before the type ID, or where either field does not
+ // appear exactly once. However, in theory such cases are valid, so we
+ // should be prepared to accept them.
+
+ int typeId = 0;
+ ByteString rawBytes = null; // If we encounter "message" before "typeId"
+ Message.Builder subBuilder = null;
+ FieldDescriptor field = null;
+
+ while (true) {
+ final int tag = input.readTag();
+ if (tag == 0) {
+ break;
+ }
+
+ if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
+ typeId = input.readUInt32();
+ // Zero is not a valid type ID.
+ if (typeId != 0) {
+ final ExtensionRegistry.ExtensionInfo extension;
+
+ // extensionRegistry may be either ExtensionRegistry or
+ // ExtensionRegistryLite. Since the type we are parsing is a full
+ // message, only a full ExtensionRegistry could possibly contain
+ // extensions of it. Otherwise we will treat the registry as if it
+ // were empty.
+ if (extensionRegistry instanceof ExtensionRegistry) {
+ extension = ((ExtensionRegistry) extensionRegistry)
+ .findExtensionByNumber(type, typeId);
+ } else {
+ extension = null;
+ }
+
+ if (extension != null) {
+ field = extension.descriptor;
+ subBuilder = extension.defaultInstance.newBuilderForType();
+ final Message originalMessage = (Message)builder.getField(field);
+ if (originalMessage != null) {
+ subBuilder.mergeFrom(originalMessage);
+ }
+ if (rawBytes != null) {
+ // We already encountered the message. Parse it now.
+ subBuilder.mergeFrom(
+ CodedInputStream.newInstance(rawBytes.newInput()));
+ rawBytes = null;
+ }
+ } else {
+ // Unknown extension number. If we already saw data, put it
+ // in rawBytes.
+ if (rawBytes != null) {
+ unknownFields.mergeField(typeId,
+ UnknownFieldSet.Field.newBuilder()
+ .addLengthDelimited(rawBytes)
+ .build());
+ rawBytes = null;
+ }
+ }
+ }
+ } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
+ if (typeId == 0) {
+ // We haven't seen a type ID yet, so we have to store the raw bytes
+ // for now.
+ rawBytes = input.readBytes();
+ } else if (subBuilder == null) {
+ // We don't know how to parse this. Ignore it.
+ unknownFields.mergeField(typeId,
+ UnknownFieldSet.Field.newBuilder()
+ .addLengthDelimited(input.readBytes())
+ .build());
+ } else {
+ // We already know the type, so we can parse directly from the input
+ // with no copying. Hooray!
+ input.readMessage(subBuilder, extensionRegistry);
+ }
+ } else {
+ // Unknown tag. Skip it.
+ if (!input.skipField(tag)) {
+ break; // end of group
+ }
+ }
+ }
+
+ input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
+
+ if (subBuilder != null) {
+ builder.setField(field, subBuilder.build());
+ }
+ }
+
+ public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
+ setUnknownFields(
+ UnknownFieldSet.newBuilder(getUnknownFields())
+ .mergeFrom(unknownFields)
+ .build());
+ return (BuilderType) this;
+ }
+
+ /**
+ * Construct an UninitializedMessageException reporting missing fields in
+ * the given message.
+ */
+ protected static UninitializedMessageException
+ newUninitializedMessageException(Message message) {
+ return new UninitializedMessageException(findMissingFields(message));
+ }
+
+ /**
+ * Populates {@code this.missingFields} with the full "path" of each
+ * missing required field in the given message.
+ */
+ private static List<String> findMissingFields(final Message message) {
+ final List<String> results = new ArrayList<String>();
+ findMissingFields(message, "", results);
+ return results;
+ }
+
+ /** Recursive helper implementing {@link #findMissingFields(Message)}. */
+ private static void findMissingFields(final Message message,
+ final String prefix,
+ final List<String> results) {
+ for (final FieldDescriptor field :
+ message.getDescriptorForType().getFields()) {
+ if (field.isRequired() && !message.hasField(field)) {
+ results.add(prefix + field.getName());
+ }
+ }
+
+ for (final Map.Entry<FieldDescriptor, Object> entry :
+ message.getAllFields().entrySet()) {
+ final FieldDescriptor field = entry.getKey();
+ final Object value = entry.getValue();
+
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ int i = 0;
+ for (final Object element : (List) value) {
+ findMissingFields((Message) element,
+ subMessagePrefix(prefix, field, i++),
+ results);
+ }
+ } else {
+ if (message.hasField(field)) {
+ findMissingFields((Message) value,
+ subMessagePrefix(prefix, field, -1),
+ results);
+ }
+ }
+ }
+ }
+ }
+
+ private static String subMessagePrefix(final String prefix,
+ final FieldDescriptor field,
+ final int index) {
+ final StringBuilder result = new StringBuilder(prefix);
+ if (field.isExtension()) {
+ result.append('(')
+ .append(field.getFullName())
+ .append(')');
+ } else {
+ result.append(field.getName());
+ }
+ if (index != -1) {
+ result.append('[')
+ .append(index)
+ .append(']');
+ }
+ result.append('.');
+ return result.toString();
+ }
+
+ // ===============================================================
+ // The following definitions seem to be required in order to make javac
+ // not produce weird errors like:
+ //
+ // java/com/google/protobuf/DynamicMessage.java:203: types
+ // com.google.protobuf.AbstractMessage.Builder<
+ // com.google.protobuf.DynamicMessage.Builder> and
+ // com.google.protobuf.AbstractMessage.Builder<
+ // com.google.protobuf.DynamicMessage.Builder> are incompatible; both
+ // define mergeFrom(com.google.protobuf.ByteString), but with unrelated
+ // return types.
+ //
+ // Strangely, these lines are only needed if javac is invoked separately
+ // on AbstractMessage.java and AbstractMessageLite.java. If javac is
+ // invoked on both simultaneously, it works. (Or maybe the important
+ // point is whether or not DynamicMessage.java is compiled together with
+ // AbstractMessageLite.java -- not sure.) I suspect this is a compiler
+ // bug.
+
+ @Override
+ public BuilderType mergeFrom(final ByteString data)
+ throws InvalidProtocolBufferException {
+ return super.mergeFrom(data);
+ }
+
+ @Override
+ public BuilderType mergeFrom(
+ final ByteString data,
+ final ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return super.mergeFrom(data, extensionRegistry);
+ }
+
+ @Override
+ public BuilderType mergeFrom(final byte[] data)
+ throws InvalidProtocolBufferException {
+ return super.mergeFrom(data);
+ }
+
+ @Override
+ public BuilderType mergeFrom(
+ final byte[] data, final int off, final int len)
+ throws InvalidProtocolBufferException {
+ return super.mergeFrom(data, off, len);
+ }
+
+ @Override
+ public BuilderType mergeFrom(
+ final byte[] data,
+ final ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return super.mergeFrom(data, extensionRegistry);
+ }
+
+ @Override
+ public BuilderType mergeFrom(
+ final byte[] data, final int off, final int len,
+ final ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return super.mergeFrom(data, off, len, extensionRegistry);
+ }
+
+ @Override
+ public BuilderType mergeFrom(final InputStream input)
+ throws IOException {
+ return super.mergeFrom(input);
+ }
+
+ @Override
+ public BuilderType mergeFrom(
+ final InputStream input,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ return super.mergeFrom(input, extensionRegistry);
+ }
+
+ @Override
+ public boolean mergeDelimitedFrom(final InputStream input)
+ throws IOException {
+ return super.mergeDelimitedFrom(input);
+ }
+
+ @Override
+ public boolean mergeDelimitedFrom(
+ final InputStream input,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ return super.mergeDelimitedFrom(input, extensionRegistry);
+ }
+
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessageLite.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
new file mode 100644
index 0000000..77b2737
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
@@ -0,0 +1,325 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+
+/**
+ * A partial implementation of the {@link MessageLite} interface which
+ * implements as many methods of that interface as possible in terms of other
+ * methods.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class AbstractMessageLite implements MessageLite {
+ public ByteString toByteString() {
+ try {
+ final ByteString.CodedBuilder out =
+ ByteString.newCodedBuilder(getSerializedSize());
+ writeTo(out.getCodedOutput());
+ return out.build();
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Serializing to a ByteString threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ public byte[] toByteArray() {
+ try {
+ final byte[] result = new byte[getSerializedSize()];
+ final CodedOutputStream output = CodedOutputStream.newInstance(result);
+ writeTo(output);
+ output.checkNoSpaceLeft();
+ return result;
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Serializing to a byte array threw an IOException " +
+ "(should never happen).", e);
+ }
+ }
+
+ public void writeTo(final OutputStream output) throws IOException {
+ final int bufferSize =
+ CodedOutputStream.computePreferredBufferSize(getSerializedSize());
+ final CodedOutputStream codedOutput =
+ CodedOutputStream.newInstance(output, bufferSize);
+ writeTo(codedOutput);
+ codedOutput.flush();
+ }
+
+ public void writeDelimitedTo(final OutputStream output) throws IOException {
+ final int serialized = getSerializedSize();
+ final int bufferSize = CodedOutputStream.computePreferredBufferSize(
+ CodedOutputStream.computeRawVarint32Size(serialized) + serialized);
+ final CodedOutputStream codedOutput =
+ CodedOutputStream.newInstance(output, bufferSize);
+ codedOutput.writeRawVarint32(serialized);
+ writeTo(codedOutput);
+ codedOutput.flush();
+ }
+
+ /**
+ * A partial implementation of the {@link Message.Builder} interface which
+ * implements as many methods of that interface as possible in terms of
+ * other methods.
+ */
+ @SuppressWarnings("unchecked")
+ public static abstract class Builder<BuilderType extends Builder>
+ implements MessageLite.Builder {
+ // The compiler produces an error if this is not declared explicitly.
+ @Override
+ public abstract BuilderType clone();
+
+ public BuilderType mergeFrom(final CodedInputStream input)
+ throws IOException {
+ return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
+ }
+
+ // Re-defined here for return type covariance.
+ public abstract BuilderType mergeFrom(
+ final CodedInputStream input,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException;
+
+ public BuilderType mergeFrom(final ByteString data)
+ throws InvalidProtocolBufferException {
+ try {
+ final CodedInputStream input = data.newCodedInput();
+ mergeFrom(input);
+ input.checkLastTagWas(0);
+ return (BuilderType) this;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Reading from a ByteString threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ public BuilderType mergeFrom(
+ final ByteString data,
+ final ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ try {
+ final CodedInputStream input = data.newCodedInput();
+ mergeFrom(input, extensionRegistry);
+ input.checkLastTagWas(0);
+ return (BuilderType) this;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Reading from a ByteString threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ public BuilderType mergeFrom(final byte[] data)
+ throws InvalidProtocolBufferException {
+ return mergeFrom(data, 0, data.length);
+ }
+
+ public BuilderType mergeFrom(final byte[] data, final int off,
+ final int len)
+ throws InvalidProtocolBufferException {
+ try {
+ final CodedInputStream input =
+ CodedInputStream.newInstance(data, off, len);
+ mergeFrom(input);
+ input.checkLastTagWas(0);
+ return (BuilderType) this;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Reading from a byte array threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ public BuilderType mergeFrom(
+ final byte[] data,
+ final ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return mergeFrom(data, 0, data.length, extensionRegistry);
+ }
+
+ public BuilderType mergeFrom(
+ final byte[] data, final int off, final int len,
+ final ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ try {
+ final CodedInputStream input =
+ CodedInputStream.newInstance(data, off, len);
+ mergeFrom(input, extensionRegistry);
+ input.checkLastTagWas(0);
+ return (BuilderType) this;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Reading from a byte array threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ public BuilderType mergeFrom(final InputStream input) throws IOException {
+ final CodedInputStream codedInput = CodedInputStream.newInstance(input);
+ mergeFrom(codedInput);
+ codedInput.checkLastTagWas(0);
+ return (BuilderType) this;
+ }
+
+ public BuilderType mergeFrom(
+ final InputStream input,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ final CodedInputStream codedInput = CodedInputStream.newInstance(input);
+ mergeFrom(codedInput, extensionRegistry);
+ codedInput.checkLastTagWas(0);
+ return (BuilderType) this;
+ }
+
+ /**
+ * An InputStream implementations which reads from some other InputStream
+ * but is limited to a particular number of bytes. Used by
+ * mergeDelimitedFrom(). This is intentionally package-private so that
+ * UnknownFieldSet can share it.
+ */
+ static final class LimitedInputStream extends FilterInputStream {
+ private int limit;
+
+ LimitedInputStream(InputStream in, int limit) {
+ super(in);
+ this.limit = limit;
+ }
+
+ @Override
+ public int available() throws IOException {
+ return Math.min(super.available(), limit);
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (limit <= 0) {
+ return -1;
+ }
+ final int result = super.read();
+ if (result >= 0) {
+ --limit;
+ }
+ return result;
+ }
+
+ @Override
+ public int read(final byte[] b, final int off, int len)
+ throws IOException {
+ if (limit <= 0) {
+ return -1;
+ }
+ len = Math.min(len, limit);
+ final int result = super.read(b, off, len);
+ if (result >= 0) {
+ limit -= result;
+ }
+ return result;
+ }
+
+ @Override
+ public long skip(final long n) throws IOException {
+ final long result = super.skip(Math.min(n, limit));
+ if (result >= 0) {
+ limit -= result;
+ }
+ return result;
+ }
+ }
+
+ public boolean mergeDelimitedFrom(
+ final InputStream input,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ final int firstByte = input.read();
+ if (firstByte == -1) {
+ return false;
+ }
+ final int size = CodedInputStream.readRawVarint32(firstByte, input);
+ final InputStream limitedInput = new LimitedInputStream(input, size);
+ mergeFrom(limitedInput, extensionRegistry);
+ return true;
+ }
+
+ public boolean mergeDelimitedFrom(final InputStream input)
+ throws IOException {
+ return mergeDelimitedFrom(input,
+ ExtensionRegistryLite.getEmptyRegistry());
+ }
+
+ /**
+ * Construct an UninitializedMessageException reporting missing fields in
+ * the given message.
+ */
+ protected static UninitializedMessageException
+ newUninitializedMessageException(MessageLite message) {
+ return new UninitializedMessageException(message);
+ }
+
+ /**
+ * Adds the {@code values} to the {@code list}. This is a helper method
+ * used by generated code. Users should ignore it.
+ *
+ * @throws NullPointerException if any of the elements of {@code values} is
+ * null.
+ */
+ protected static <T> void addAll(final Iterable<T> values,
+ final Collection<? super T> list) {
+ for (final T value : values) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ }
+ if (values instanceof Collection) {
+ final Collection<T> collection = (Collection<T>) values;
+ list.addAll(collection);
+ } else {
+ for (final T value : values) {
+ list.add(value);
+ }
+ }
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
new file mode 100644
index 0000000..1e81143
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * <p>Abstract interface for a blocking RPC channel. {@code BlockingRpcChannel}
+ * is the blocking equivalent to {@link RpcChannel}.
+ *
+ * @author kenton@google.com Kenton Varda
+ * @author cpovirk@google.com Chris Povirk
+ */
+public interface BlockingRpcChannel {
+ /**
+ * Call the given method of the remote service and blocks until it returns.
+ * {@code callBlockingMethod()} is the blocking equivalent to
+ * {@link RpcChannel#callMethod}.
+ */
+ Message callBlockingMethod(
+ Descriptors.MethodDescriptor method,
+ RpcController controller,
+ Message request,
+ Message responsePrototype) throws ServiceException;
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/BlockingService.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/BlockingService.java
new file mode 100644
index 0000000..ecc8009
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/BlockingService.java
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Blocking equivalent to {@link Service}.
+ *
+ * @author kenton@google.com Kenton Varda
+ * @author cpovirk@google.com Chris Povirk
+ */
+public interface BlockingService {
+ /**
+ * Equivalent to {@link Service#getDescriptorForType}.
+ */
+ Descriptors.ServiceDescriptor getDescriptorForType();
+
+ /**
+ * Equivalent to {@link Service#callMethod}, except that
+ * {@code callBlockingMethod()} returns the result of the RPC or throws a
+ * {@link ServiceException} if there is a failure, rather than passing the
+ * information to a callback.
+ */
+ Message callBlockingMethod(Descriptors.MethodDescriptor method,
+ RpcController controller,
+ Message request) throws ServiceException;
+
+ /**
+ * Equivalent to {@link Service#getRequestPrototype}.
+ */
+ Message getRequestPrototype(Descriptors.MethodDescriptor method);
+
+ /**
+ * Equivalent to {@link Service#getResponsePrototype}.
+ */
+ Message getResponsePrototype(Descriptors.MethodDescriptor method);
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ByteString.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ByteString.java
new file mode 100644
index 0000000..9135635
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ByteString.java
@@ -0,0 +1,403 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * Immutable array of bytes.
+ *
+ * @author crazybob@google.com Bob Lee
+ * @author kenton@google.com Kenton Varda
+ */
+public final class ByteString {
+ private final byte[] bytes;
+
+ private ByteString(final byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ /**
+ * Gets the byte at the given index.
+ *
+ * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
+ */
+ public byte byteAt(final int index) {
+ return bytes[index];
+ }
+
+ /**
+ * Gets the number of bytes.
+ */
+ public int size() {
+ return bytes.length;
+ }
+
+ /**
+ * Returns {@code true} if the size is {@code 0}, {@code false} otherwise.
+ */
+ public boolean isEmpty() {
+ return bytes.length == 0;
+ }
+
+ // =================================================================
+ // byte[] -> ByteString
+
+ /**
+ * Empty ByteString.
+ */
+ public static final ByteString EMPTY = new ByteString(new byte[0]);
+
+ /**
+ * Copies the given bytes into a {@code ByteString}.
+ */
+ public static ByteString copyFrom(final byte[] bytes, final int offset,
+ final int size) {
+ final byte[] copy = new byte[size];
+ System.arraycopy(bytes, offset, copy, 0, size);
+ return new ByteString(copy);
+ }
+
+ /**
+ * Copies the given bytes into a {@code ByteString}.
+ */
+ public static ByteString copyFrom(final byte[] bytes) {
+ return copyFrom(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Copies {@code size} bytes from a {@code java.nio.ByteBuffer} into
+ * a {@code ByteString}.
+ */
+ public static ByteString copyFrom(final ByteBuffer bytes, final int size) {
+ final byte[] copy = new byte[size];
+ bytes.get(copy);
+ return new ByteString(copy);
+ }
+
+ /**
+ * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into
+ * a {@code ByteString}.
+ */
+ public static ByteString copyFrom(final ByteBuffer bytes) {
+ return copyFrom(bytes, bytes.remaining());
+ }
+
+ /**
+ * Encodes {@code text} into a sequence of bytes using the named charset
+ * and returns the result as a {@code ByteString}.
+ */
+ public static ByteString copyFrom(final String text, final String charsetName)
+ throws UnsupportedEncodingException {
+ return new ByteString(text.getBytes(charsetName));
+ }
+
+ /**
+ * Encodes {@code text} into a sequence of UTF-8 bytes and returns the
+ * result as a {@code ByteString}.
+ */
+ public static ByteString copyFromUtf8(final String text) {
+ try {
+ return new ByteString(text.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported?", e);
+ }
+ }
+
+ /**
+ * Concatenates all byte strings in the list and returns the result.
+ *
+ * <p>The returned {@code ByteString} is not necessarily a unique object.
+ * If the list is empty, the returned object is the singleton empty
+ * {@code ByteString}. If the list has only one element, that
+ * {@code ByteString} will be returned without copying.
+ */
+ public static ByteString copyFrom(List<ByteString> list) {
+ if (list.size() == 0) {
+ return EMPTY;
+ } else if (list.size() == 1) {
+ return list.get(0);
+ }
+
+ int size = 0;
+ for (ByteString str : list) {
+ size += str.size();
+ }
+ byte[] bytes = new byte[size];
+ int pos = 0;
+ for (ByteString str : list) {
+ System.arraycopy(str.bytes, 0, bytes, pos, str.size());
+ pos += str.size();
+ }
+ return new ByteString(bytes);
+ }
+
+ // =================================================================
+ // ByteString -> byte[]
+
+ /**
+ * Copies bytes into a buffer at the given offset.
+ *
+ * @param target buffer to copy into
+ * @param offset in the target buffer
+ */
+ public void copyTo(final byte[] target, final int offset) {
+ System.arraycopy(bytes, 0, target, offset, bytes.length);
+ }
+
+ /**
+ * Copies bytes into a buffer.
+ *
+ * @param target buffer to copy into
+ * @param sourceOffset offset within these bytes
+ * @param targetOffset offset within the target buffer
+ * @param size number of bytes to copy
+ */
+ public void copyTo(final byte[] target, final int sourceOffset,
+ final int targetOffset,
+ final int size) {
+ System.arraycopy(bytes, sourceOffset, target, targetOffset, size);
+ }
+
+ /**
+ * Copies bytes into a ByteBuffer.
+ *
+ * @param target ByteBuffer to copy into.
+ * @throws ReadOnlyBufferException if the {@code target} is read-only
+ * @throws BufferOverflowException if the {@code target}'s remaining()
+ * space is not large enough to hold the data.
+ */
+ public void copyTo(ByteBuffer target) {
+ target.put(bytes, 0, bytes.length);
+ }
+
+ /**
+ * Copies bytes to a {@code byte[]}.
+ */
+ public byte[] toByteArray() {
+ final int size = bytes.length;
+ final byte[] copy = new byte[size];
+ System.arraycopy(bytes, 0, copy, 0, size);
+ return copy;
+ }
+
+ /**
+ * Constructs a new read-only {@code java.nio.ByteBuffer} with the
+ * same backing byte array.
+ */
+ public ByteBuffer asReadOnlyByteBuffer() {
+ final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+ return byteBuffer.asReadOnlyBuffer();
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the bytes using the
+ * specified charset.
+ */
+ public String toString(final String charsetName)
+ throws UnsupportedEncodingException {
+ return new String(bytes, charsetName);
+ }
+
+ /**
+ * Constructs a new {@code String} by decoding the bytes as UTF-8.
+ */
+ public String toStringUtf8() {
+ try {
+ return new String(bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported?", e);
+ }
+ }
+
+ // =================================================================
+ // equals() and hashCode()
+
+ @Override
+ public boolean equals(final Object o) {
+ if (o == this) {
+ return true;
+ }
+
+ if (!(o instanceof ByteString)) {
+ return false;
+ }
+
+ final ByteString other = (ByteString) o;
+ final int size = bytes.length;
+ if (size != other.bytes.length) {
+ return false;
+ }
+
+ final byte[] thisBytes = bytes;
+ final byte[] otherBytes = other.bytes;
+ for (int i = 0; i < size; i++) {
+ if (thisBytes[i] != otherBytes[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private volatile int hash = 0;
+
+ @Override
+ public int hashCode() {
+ int h = hash;
+
+ if (h == 0) {
+ final byte[] thisBytes = bytes;
+ final int size = bytes.length;
+
+ h = size;
+ for (int i = 0; i < size; i++) {
+ h = h * 31 + thisBytes[i];
+ }
+ if (h == 0) {
+ h = 1;
+ }
+
+ hash = h;
+ }
+
+ return h;
+ }
+
+ // =================================================================
+ // Input stream
+
+ /**
+ * Creates an {@code InputStream} which can be used to read the bytes.
+ */
+ public InputStream newInput() {
+ return new ByteArrayInputStream(bytes);
+ }
+
+ /**
+ * Creates a {@link CodedInputStream} which can be used to read the bytes.
+ * Using this is more efficient than creating a {@link CodedInputStream}
+ * wrapping the result of {@link #newInput()}.
+ */
+ public CodedInputStream newCodedInput() {
+ // We trust CodedInputStream not to modify the bytes, or to give anyone
+ // else access to them.
+ return CodedInputStream.newInstance(bytes);
+ }
+
+ // =================================================================
+ // Output stream
+
+ /**
+ * Creates a new {@link Output} with the given initial capacity.
+ */
+ public static Output newOutput(final int initialCapacity) {
+ return new Output(new ByteArrayOutputStream(initialCapacity));
+ }
+
+ /**
+ * Creates a new {@link Output}.
+ */
+ public static Output newOutput() {
+ return newOutput(32);
+ }
+
+ /**
+ * Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to
+ * create the {@code ByteString} instance.
+ */
+ public static final class Output extends FilterOutputStream {
+ private final ByteArrayOutputStream bout;
+
+ /**
+ * Constructs a new output with the given initial capacity.
+ */
+ private Output(final ByteArrayOutputStream bout) {
+ super(bout);
+ this.bout = bout;
+ }
+
+ /**
+ * Creates a {@code ByteString} instance from this {@code Output}.
+ */
+ public ByteString toByteString() {
+ final byte[] byteArray = bout.toByteArray();
+ return new ByteString(byteArray);
+ }
+ }
+
+ /**
+ * Constructs a new ByteString builder, which allows you to efficiently
+ * construct a {@code ByteString} by writing to a {@link CodedOutputStream}.
+ * Using this is much more efficient than calling {@code newOutput()} and
+ * wrapping that in a {@code CodedOutputStream}.
+ *
+ * <p>This is package-private because it's a somewhat confusing interface.
+ * Users can call {@link Message#toByteString()} instead of calling this
+ * directly.
+ *
+ * @param size The target byte size of the {@code ByteString}. You must
+ * write exactly this many bytes before building the result.
+ */
+ static CodedBuilder newCodedBuilder(final int size) {
+ return new CodedBuilder(size);
+ }
+
+ /** See {@link ByteString#newCodedBuilder(int)}. */
+ static final class CodedBuilder {
+ private final CodedOutputStream output;
+ private final byte[] buffer;
+
+ private CodedBuilder(final int size) {
+ buffer = new byte[size];
+ output = CodedOutputStream.newInstance(buffer);
+ }
+
+ public ByteString build() {
+ output.checkNoSpaceLeft();
+
+ // We can be confident that the CodedOutputStream will not modify the
+ // underlying bytes anymore because it already wrote all of them. So,
+ // no need to make a copy.
+ return new ByteString(buffer);
+ }
+
+ public CodedOutputStream getCodedOutput() {
+ return output;
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/CodedInputStream.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/CodedInputStream.java
new file mode 100644
index 0000000..b3e0855
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -0,0 +1,885 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Reads and decodes protocol message fields.
+ *
+ * This class contains two kinds of methods: methods that read specific
+ * protocol message constructs and field types (e.g. {@link #readTag()} and
+ * {@link #readInt32()}) and methods that read low-level values (e.g.
+ * {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading
+ * encoded protocol messages, you should use the former methods, but if you are
+ * reading some other format of your own design, use the latter.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class CodedInputStream {
+ /**
+ * Create a new CodedInputStream wrapping the given InputStream.
+ */
+ public static CodedInputStream newInstance(final InputStream input) {
+ return new CodedInputStream(input);
+ }
+
+ /**
+ * Create a new CodedInputStream wrapping the given byte array.
+ */
+ public static CodedInputStream newInstance(final byte[] buf) {
+ return newInstance(buf, 0, buf.length);
+ }
+
+ /**
+ * Create a new CodedInputStream wrapping the given byte array slice.
+ */
+ public static CodedInputStream newInstance(final byte[] buf, final int off,
+ final int len) {
+ CodedInputStream result = new CodedInputStream(buf, off, len);
+ try {
+ // Some uses of CodedInputStream can be more efficient if they know
+ // exactly how many bytes are available. By pushing the end point of the
+ // buffer as a limit, we allow them to get this information via
+ // getBytesUntilLimit(). Pushing a limit that we know is at the end of
+ // the stream can never hurt, since we can never past that point anyway.
+ result.pushLimit(len);
+ } catch (InvalidProtocolBufferException ex) {
+ // The only reason pushLimit() might throw an exception here is if len
+ // is negative. Normally pushLimit()'s parameter comes directly off the
+ // wire, so it's important to catch exceptions in case of corrupt or
+ // malicious data. However, in this case, we expect that len is not a
+ // user-supplied value, so we can assume that it being negative indicates
+ // a programming error. Therefore, throwing an unchecked exception is
+ // appropriate.
+ throw new IllegalArgumentException(ex);
+ }
+ return result;
+ }
+
+ // -----------------------------------------------------------------
+
+ /**
+ * Attempt to read a field tag, returning zero if we have reached EOF.
+ * Protocol message parsers use this to read tags, since a protocol message
+ * may legally end wherever a tag occurs, and zero is not a valid tag number.
+ */
+ public int readTag() throws IOException {
+ if (isAtEnd()) {
+ lastTag = 0;
+ return 0;
+ }
+
+ lastTag = readRawVarint32();
+ if (WireFormat.getTagFieldNumber(lastTag) == 0) {
+ // If we actually read zero (or any tag number corresponding to field
+ // number zero), that's not a valid tag.
+ throw InvalidProtocolBufferException.invalidTag();
+ }
+ return lastTag;
+ }
+
+ /**
+ * Verifies that the last call to readTag() returned the given tag value.
+ * This is used to verify that a nested group ended with the correct
+ * end tag.
+ *
+ * @throws InvalidProtocolBufferException {@code value} does not match the
+ * last tag.
+ */
+ public void checkLastTagWas(final int value)
+ throws InvalidProtocolBufferException {
+ if (lastTag != value) {
+ throw InvalidProtocolBufferException.invalidEndTag();
+ }
+ }
+
+ /**
+ * Reads and discards a single field, given its tag value.
+ *
+ * @return {@code false} if the tag is an endgroup tag, in which case
+ * nothing is skipped. Otherwise, returns {@code true}.
+ */
+ public boolean skipField(final int tag) throws IOException {
+ switch (WireFormat.getTagWireType(tag)) {
+ case WireFormat.WIRETYPE_VARINT:
+ readInt32();
+ return true;
+ case WireFormat.WIRETYPE_FIXED64:
+ readRawLittleEndian64();
+ return true;
+ case WireFormat.WIRETYPE_LENGTH_DELIMITED:
+ skipRawBytes(readRawVarint32());
+ return true;
+ case WireFormat.WIRETYPE_START_GROUP:
+ skipMessage();
+ checkLastTagWas(
+ WireFormat.makeTag(WireFormat.getTagFieldNumber(tag),
+ WireFormat.WIRETYPE_END_GROUP));
+ return true;
+ case WireFormat.WIRETYPE_END_GROUP:
+ return false;
+ case WireFormat.WIRETYPE_FIXED32:
+ readRawLittleEndian32();
+ return true;
+ default:
+ throw InvalidProtocolBufferException.invalidWireType();
+ }
+ }
+
+ /**
+ * Reads and discards an entire message. This will read either until EOF
+ * or until an endgroup tag, whichever comes first.
+ */
+ public void skipMessage() throws IOException {
+ while (true) {
+ final int tag = readTag();
+ if (tag == 0 || !skipField(tag)) {
+ return;
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+ /** Read a {@code double} field value from the stream. */
+ public double readDouble() throws IOException {
+ return Double.longBitsToDouble(readRawLittleEndian64());
+ }
+
+ /** Read a {@code float} field value from the stream. */
+ public float readFloat() throws IOException {
+ return Float.intBitsToFloat(readRawLittleEndian32());
+ }
+
+ /** Read a {@code uint64} field value from the stream. */
+ public long readUInt64() throws IOException {
+ return readRawVarint64();
+ }
+
+ /** Read an {@code int64} field value from the stream. */
+ public long readInt64() throws IOException {
+ return readRawVarint64();
+ }
+
+ /** Read an {@code int32} field value from the stream. */
+ public int readInt32() throws IOException {
+ return readRawVarint32();
+ }
+
+ /** Read a {@code fixed64} field value from the stream. */
+ public long readFixed64() throws IOException {
+ return readRawLittleEndian64();
+ }
+
+ /** Read a {@code fixed32} field value from the stream. */
+ public int readFixed32() throws IOException {
+ return readRawLittleEndian32();
+ }
+
+ /** Read a {@code bool} field value from the stream. */
+ public boolean readBool() throws IOException {
+ return readRawVarint32() != 0;
+ }
+
+ /** Read a {@code string} field value from the stream. */
+ public String readString() throws IOException {
+ final int size = readRawVarint32();
+ if (size <= (bufferSize - bufferPos) && size > 0) {
+ // Fast path: We already have the bytes in a contiguous buffer, so
+ // just copy directly from it.
+ final String result = new String(buffer, bufferPos, size, "UTF-8");
+ bufferPos += size;
+ return result;
+ } else {
+ // Slow path: Build a byte array first then copy it.
+ return new String(readRawBytes(size), "UTF-8");
+ }
+ }
+
+ /** Read a {@code group} field value from the stream. */
+ public void readGroup(final int fieldNumber,
+ final MessageLite.Builder builder,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ if (recursionDepth >= recursionLimit) {
+ throw InvalidProtocolBufferException.recursionLimitExceeded();
+ }
+ ++recursionDepth;
+ builder.mergeFrom(this, extensionRegistry);
+ checkLastTagWas(
+ WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
+ --recursionDepth;
+ }
+
+ /**
+ * Reads a {@code group} field value from the stream and merges it into the
+ * given {@link UnknownFieldSet}.
+ *
+ * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so
+ * you can just call {@link #readGroup}.
+ */
+ @Deprecated
+ public void readUnknownGroup(final int fieldNumber,
+ final MessageLite.Builder builder)
+ throws IOException {
+ // We know that UnknownFieldSet will ignore any ExtensionRegistry so it
+ // is safe to pass null here. (We can't call
+ // ExtensionRegistry.getEmptyRegistry() because that would make this
+ // class depend on ExtensionRegistry, which is not part of the lite
+ // library.)
+ readGroup(fieldNumber, builder, null);
+ }
+
+ /** Read an embedded message field value from the stream. */
+ public void readMessage(final MessageLite.Builder builder,
+ final ExtensionRegistryLite extensionRegistry)
+ throws IOException {
+ final int length = readRawVarint32();
+ if (recursionDepth >= recursionLimit) {
+ throw InvalidProtocolBufferException.recursionLimitExceeded();
+ }
+ final int oldLimit = pushLimit(length);
+ ++recursionDepth;
+ builder.mergeFrom(this, extensionRegistry);
+ checkLastTagWas(0);
+ --recursionDepth;
+ popLimit(oldLimit);
+ }
+
+ /** Read a {@code bytes} field value from the stream. */
+ public ByteString readBytes() throws IOException {
+ final int size = readRawVarint32();
+ if (size == 0) {
+ return ByteString.EMPTY;
+ } else if (size <= (bufferSize - bufferPos) && size > 0) {
+ // Fast path: We already have the bytes in a contiguous buffer, so
+ // just copy directly from it.
+ final ByteString result = ByteString.copyFrom(buffer, bufferPos, size);
+ bufferPos += size;
+ return result;
+ } else {
+ // Slow path: Build a byte array first then copy it.
+ return ByteString.copyFrom(readRawBytes(size));
+ }
+ }
+
+ /** Read a {@code uint32} field value from the stream. */
+ public int readUInt32() throws IOException {
+ return readRawVarint32();
+ }
+
+ /**
+ * Read an enum field value from the stream. Caller is responsible
+ * for converting the numeric value to an actual enum.
+ */
+ public int readEnum() throws IOException {
+ return readRawVarint32();
+ }
+
+ /** Read an {@code sfixed32} field value from the stream. */
+ public int readSFixed32() throws IOException {
+ return readRawLittleEndian32();
+ }
+
+ /** Read an {@code sfixed64} field value from the stream. */
+ public long readSFixed64() throws IOException {
+ return readRawLittleEndian64();
+ }
+
+ /** Read an {@code sint32} field value from the stream. */
+ public int readSInt32() throws IOException {
+ return decodeZigZag32(readRawVarint32());
+ }
+
+ /** Read an {@code sint64} field value from the stream. */
+ public long readSInt64() throws IOException {
+ return decodeZigZag64(readRawVarint64());
+ }
+
+ // =================================================================
+
+ /**
+ * Read a raw Varint from the stream. If larger than 32 bits, discard the
+ * upper bits.
+ */
+ public int readRawVarint32() throws IOException {
+ byte tmp = readRawByte();
+ if (tmp >= 0) {
+ return tmp;
+ }
+ int result = tmp & 0x7f;
+ if ((tmp = readRawByte()) >= 0) {
+ result |= tmp << 7;
+ } else {
+ result |= (tmp & 0x7f) << 7;
+ if ((tmp = readRawByte()) >= 0) {
+ result |= tmp << 14;
+ } else {
+ result |= (tmp & 0x7f) << 14;
+ if ((tmp = readRawByte()) >= 0) {
+ result |= tmp << 21;
+ } else {
+ result |= (tmp & 0x7f) << 21;
+ result |= (tmp = readRawByte()) << 28;
+ if (tmp < 0) {
+ // Discard upper 32 bits.
+ for (int i = 0; i < 5; i++) {
+ if (readRawByte() >= 0) {
+ return result;
+ }
+ }
+ throw InvalidProtocolBufferException.malformedVarint();
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Reads a varint from the input one byte at a time, so that it does not
+ * read any bytes after the end of the varint. If you simply wrapped the
+ * stream in a CodedInputStream and used {@link #readRawVarint32(InputStream)}
+ * then you would probably end up reading past the end of the varint since
+ * CodedInputStream buffers its input.
+ */
+ static int readRawVarint32(final InputStream input) throws IOException {
+ final int firstByte = input.read();
+ if (firstByte == -1) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ return readRawVarint32(firstByte, input);
+ }
+
+ /**
+ * Like {@link #readRawVarint32(InputStream)}, but expects that the caller
+ * has already read one byte. This allows the caller to determine if EOF
+ * has been reached before attempting to read.
+ */
+ public static int readRawVarint32(
+ final int firstByte, final InputStream input) throws IOException {
+ if ((firstByte & 0x80) == 0) {
+ return firstByte;
+ }
+
+ int result = firstByte & 0x7f;
+ int offset = 7;
+ for (; offset < 32; offset += 7) {
+ final int b = input.read();
+ if (b == -1) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ result |= (b & 0x7f) << offset;
+ if ((b & 0x80) == 0) {
+ return result;
+ }
+ }
+ // Keep reading up to 64 bits.
+ for (; offset < 64; offset += 7) {
+ final int b = input.read();
+ if (b == -1) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ if ((b & 0x80) == 0) {
+ return result;
+ }
+ }
+ throw InvalidProtocolBufferException.malformedVarint();
+ }
+
+ /** Read a raw Varint from the stream. */
+ public long readRawVarint64() throws IOException {
+ int shift = 0;
+ long result = 0;
+ while (shift < 64) {
+ final byte b = readRawByte();
+ result |= (long)(b & 0x7F) << shift;
+ if ((b & 0x80) == 0) {
+ return result;
+ }
+ shift += 7;
+ }
+ throw InvalidProtocolBufferException.malformedVarint();
+ }
+
+ /** Read a 32-bit little-endian integer from the stream. */
+ public int readRawLittleEndian32() throws IOException {
+ final byte b1 = readRawByte();
+ final byte b2 = readRawByte();
+ final byte b3 = readRawByte();
+ final byte b4 = readRawByte();
+ return (((int)b1 & 0xff) ) |
+ (((int)b2 & 0xff) << 8) |
+ (((int)b3 & 0xff) << 16) |
+ (((int)b4 & 0xff) << 24);
+ }
+
+ /** Read a 64-bit little-endian integer from the stream. */
+ public long readRawLittleEndian64() throws IOException {
+ final byte b1 = readRawByte();
+ final byte b2 = readRawByte();
+ final byte b3 = readRawByte();
+ final byte b4 = readRawByte();
+ final byte b5 = readRawByte();
+ final byte b6 = readRawByte();
+ final byte b7 = readRawByte();
+ final byte b8 = readRawByte();
+ return (((long)b1 & 0xff) ) |
+ (((long)b2 & 0xff) << 8) |
+ (((long)b3 & 0xff) << 16) |
+ (((long)b4 & 0xff) << 24) |
+ (((long)b5 & 0xff) << 32) |
+ (((long)b6 & 0xff) << 40) |
+ (((long)b7 & 0xff) << 48) |
+ (((long)b8 & 0xff) << 56);
+ }
+
+ /**
+ * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
+ * into values that can be efficiently encoded with varint. (Otherwise,
+ * negative values must be sign-extended to 64 bits to be varint encoded,
+ * thus always taking 10 bytes on the wire.)
+ *
+ * @param n An unsigned 32-bit integer, stored in a signed int because
+ * Java has no explicit unsigned support.
+ * @return A signed 32-bit integer.
+ */
+ public static int decodeZigZag32(final int n) {
+ return (n >>> 1) ^ -(n & 1);
+ }
+
+ /**
+ * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
+ * into values that can be efficiently encoded with varint. (Otherwise,
+ * negative values must be sign-extended to 64 bits to be varint encoded,
+ * thus always taking 10 bytes on the wire.)
+ *
+ * @param n An unsigned 64-bit integer, stored in a signed int because
+ * Java has no explicit unsigned support.
+ * @return A signed 64-bit integer.
+ */
+ public static long decodeZigZag64(final long n) {
+ return (n >>> 1) ^ -(n & 1);
+ }
+
+ // -----------------------------------------------------------------
+
+ private final byte[] buffer;
+ private int bufferSize;
+ private int bufferSizeAfterLimit;
+ private int bufferPos;
+ private final InputStream input;
+ private int lastTag;
+
+ /**
+ * The total number of bytes read before the current buffer. The total
+ * bytes read up to the current position can be computed as
+ * {@code totalBytesRetired + bufferPos}. This value may be negative if
+ * reading started in the middle of the current buffer (e.g. if the
+ * constructor that takes a byte array and an offset was used).
+ */
+ private int totalBytesRetired;
+
+ /** The absolute position of the end of the current message. */
+ private int currentLimit = Integer.MAX_VALUE;
+
+ /** See setRecursionLimit() */
+ private int recursionDepth;
+ private int recursionLimit = DEFAULT_RECURSION_LIMIT;
+
+ /** See setSizeLimit() */
+ private int sizeLimit = DEFAULT_SIZE_LIMIT;
+
+ private static final int DEFAULT_RECURSION_LIMIT = 64;
+ private static final int DEFAULT_SIZE_LIMIT = 64 << 20; // 64MB
+ private static final int BUFFER_SIZE = 4096;
+
+ private CodedInputStream(final byte[] buffer, final int off, final int len) {
+ this.buffer = buffer;
+ bufferSize = off + len;
+ bufferPos = off;
+ totalBytesRetired = -off;
+ input = null;
+ }
+
+ private CodedInputStream(final InputStream input) {
+ buffer = new byte[BUFFER_SIZE];
+ bufferSize = 0;
+ bufferPos = 0;
+ totalBytesRetired = 0;
+ this.input = input;
+ }
+
+ /**
+ * Set the maximum message recursion depth. In order to prevent malicious
+ * messages from causing stack overflows, {@code CodedInputStream} limits
+ * how deeply messages may be nested. The default limit is 64.
+ *
+ * @return the old limit.
+ */
+ public int setRecursionLimit(final int limit) {
+ if (limit < 0) {
+ throw new IllegalArgumentException(
+ "Recursion limit cannot be negative: " + limit);
+ }
+ final int oldLimit = recursionLimit;
+ recursionLimit = limit;
+ return oldLimit;
+ }
+
+ /**
+ * Set the maximum message size. In order to prevent malicious
+ * messages from exhausting memory or causing integer overflows,
+ * {@code CodedInputStream} limits how large a message may be.
+ * The default limit is 64MB. You should set this limit as small
+ * as you can without harming your app's functionality. Note that
+ * size limits only apply when reading from an {@code InputStream}, not
+ * when constructed around a raw byte array (nor with
+ * {@link ByteString#newCodedInput}).
+ * <p>
+ * If you want to read several messages from a single CodedInputStream, you
+ * could call {@link #resetSizeCounter()} after each one to avoid hitting the
+ * size limit.
+ *
+ * @return the old limit.
+ */
+ public int setSizeLimit(final int limit) {
+ if (limit < 0) {
+ throw new IllegalArgumentException(
+ "Size limit cannot be negative: " + limit);
+ }
+ final int oldLimit = sizeLimit;
+ sizeLimit = limit;
+ return oldLimit;
+ }
+
+ /**
+ * Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
+ */
+ public void resetSizeCounter() {
+ totalBytesRetired = -bufferPos;
+ }
+
+ /**
+ * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This
+ * is called when descending into a length-delimited embedded message.
+ *
+ * <p>Note that {@code pushLimit()} does NOT affect how many bytes the
+ * {@code CodedInputStream} reads from an underlying {@code InputStream} when
+ * refreshing its buffer. If you need to prevent reading past a certain
+ * point in the underlying {@code InputStream} (e.g. because you expect it to
+ * contain more data after the end of the message which you need to handle
+ * differently) then you must place a wrapper around you {@code InputStream}
+ * which limits the amount of data that can be read from it.
+ *
+ * @return the old limit.
+ */
+ public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
+ if (byteLimit < 0) {
+ throw InvalidProtocolBufferException.negativeSize();
+ }
+ byteLimit += totalBytesRetired + bufferPos;
+ final int oldLimit = currentLimit;
+ if (byteLimit > oldLimit) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ currentLimit = byteLimit;
+
+ recomputeBufferSizeAfterLimit();
+
+ return oldLimit;
+ }
+
+ private void recomputeBufferSizeAfterLimit() {
+ bufferSize += bufferSizeAfterLimit;
+ final int bufferEnd = totalBytesRetired + bufferSize;
+ if (bufferEnd > currentLimit) {
+ // Limit is in current buffer.
+ bufferSizeAfterLimit = bufferEnd - currentLimit;
+ bufferSize -= bufferSizeAfterLimit;
+ } else {
+ bufferSizeAfterLimit = 0;
+ }
+ }
+
+ /**
+ * Discards the current limit, returning to the previous limit.
+ *
+ * @param oldLimit The old limit, as returned by {@code pushLimit}.
+ */
+ public void popLimit(final int oldLimit) {
+ currentLimit = oldLimit;
+ recomputeBufferSizeAfterLimit();
+ }
+
+ /**
+ * Returns the number of bytes to be read before the current limit.
+ * If no limit is set, returns -1.
+ */
+ public int getBytesUntilLimit() {
+ if (currentLimit == Integer.MAX_VALUE) {
+ return -1;
+ }
+
+ final int currentAbsolutePosition = totalBytesRetired + bufferPos;
+ return currentLimit - currentAbsolutePosition;
+ }
+
+ /**
+ * Returns true if the stream has reached the end of the input. This is the
+ * case if either the end of the underlying input source has been reached or
+ * if the stream has reached a limit created using {@link #pushLimit(int)}.
+ */
+ public boolean isAtEnd() throws IOException {
+ return bufferPos == bufferSize && !refillBuffer(false);
+ }
+
+ /**
+ * The total bytes read up to the current position. Calling
+ * {@link #resetSizeCounter()} resets this value to zero.
+ */
+ public int getTotalBytesRead() {
+ return totalBytesRetired + bufferPos;
+ }
+
+ /**
+ * Called with {@code this.buffer} is empty to read more bytes from the
+ * input. If {@code mustSucceed} is true, refillBuffer() gurantees that
+ * either there will be at least one byte in the buffer when it returns
+ * or it will throw an exception. If {@code mustSucceed} is false,
+ * refillBuffer() returns false if no more bytes were available.
+ */
+ private boolean refillBuffer(final boolean mustSucceed) throws IOException {
+ if (bufferPos < bufferSize) {
+ throw new IllegalStateException(
+ "refillBuffer() called when buffer wasn't empty.");
+ }
+
+ if (totalBytesRetired + bufferSize == currentLimit) {
+ // Oops, we hit a limit.
+ if (mustSucceed) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ } else {
+ return false;
+ }
+ }
+
+ totalBytesRetired += bufferSize;
+
+ bufferPos = 0;
+ bufferSize = (input == null) ? -1 : input.read(buffer);
+ if (bufferSize == 0 || bufferSize < -1) {
+ throw new IllegalStateException(
+ "InputStream#read(byte[]) returned invalid result: " + bufferSize +
+ "\nThe InputStream implementation is buggy.");
+ }
+ if (bufferSize == -1) {
+ bufferSize = 0;
+ if (mustSucceed) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ } else {
+ return false;
+ }
+ } else {
+ recomputeBufferSizeAfterLimit();
+ final int totalBytesRead =
+ totalBytesRetired + bufferSize + bufferSizeAfterLimit;
+ if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
+ throw InvalidProtocolBufferException.sizeLimitExceeded();
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Read one byte from the input.
+ *
+ * @throws InvalidProtocolBufferException The end of the stream or the current
+ * limit was reached.
+ */
+ public byte readRawByte() throws IOException {
+ if (bufferPos == bufferSize) {
+ refillBuffer(true);
+ }
+ return buffer[bufferPos++];
+ }
+
+ /**
+ * Read a fixed size of bytes from the input.
+ *
+ * @throws InvalidProtocolBufferException The end of the stream or the current
+ * limit was reached.
+ */
+ public byte[] readRawBytes(final int size) throws IOException {
+ if (size < 0) {
+ throw InvalidProtocolBufferException.negativeSize();
+ }
+
+ if (totalBytesRetired + bufferPos + size > currentLimit) {
+ // Read to the end of the stream anyway.
+ skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+ // Then fail.
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+
+ if (size <= bufferSize - bufferPos) {
+ // We have all the bytes we need already.
+ final byte[] bytes = new byte[size];
+ System.arraycopy(buffer, bufferPos, bytes, 0, size);
+ bufferPos += size;
+ return bytes;
+ } else if (size < BUFFER_SIZE) {
+ // Reading more bytes than are in the buffer, but not an excessive number
+ // of bytes. We can safely allocate the resulting array ahead of time.
+
+ // First copy what we have.
+ final byte[] bytes = new byte[size];
+ int pos = bufferSize - bufferPos;
+ System.arraycopy(buffer, bufferPos, bytes, 0, pos);
+ bufferPos = bufferSize;
+
+ // We want to use refillBuffer() and then copy from the buffer into our
+ // byte array rather than reading directly into our byte array because
+ // the input may be unbuffered.
+ refillBuffer(true);
+
+ while (size - pos > bufferSize) {
+ System.arraycopy(buffer, 0, bytes, pos, bufferSize);
+ pos += bufferSize;
+ bufferPos = bufferSize;
+ refillBuffer(true);
+ }
+
+ System.arraycopy(buffer, 0, bytes, pos, size - pos);
+ bufferPos = size - pos;
+
+ return bytes;
+ } else {
+ // The size is very large. For security reasons, we can't allocate the
+ // entire byte array yet. The size comes directly from the input, so a
+ // maliciously-crafted message could provide a bogus very large size in
+ // order to trick the app into allocating a lot of memory. We avoid this
+ // by allocating and reading only a small chunk at a time, so that the
+ // malicious message must actually *be* extremely large to cause
+ // problems. Meanwhile, we limit the allowed size of a message elsewhere.
+
+ // Remember the buffer markers since we'll have to copy the bytes out of
+ // it later.
+ final int originalBufferPos = bufferPos;
+ final int originalBufferSize = bufferSize;
+
+ // Mark the current buffer consumed.
+ totalBytesRetired += bufferSize;
+ bufferPos = 0;
+ bufferSize = 0;
+
+ // Read all the rest of the bytes we need.
+ int sizeLeft = size - (originalBufferSize - originalBufferPos);
+ final List<byte[]> chunks = new ArrayList<byte[]>();
+
+ while (sizeLeft > 0) {
+ final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];
+ int pos = 0;
+ while (pos < chunk.length) {
+ final int n = (input == null) ? -1 :
+ input.read(chunk, pos, chunk.length - pos);
+ if (n == -1) {
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+ totalBytesRetired += n;
+ pos += n;
+ }
+ sizeLeft -= chunk.length;
+ chunks.add(chunk);
+ }
+
+ // OK, got everything. Now concatenate it all into one buffer.
+ final byte[] bytes = new byte[size];
+
+ // Start by copying the leftover bytes from this.buffer.
+ int pos = originalBufferSize - originalBufferPos;
+ System.arraycopy(buffer, originalBufferPos, bytes, 0, pos);
+
+ // And now all the chunks.
+ for (final byte[] chunk : chunks) {
+ System.arraycopy(chunk, 0, bytes, pos, chunk.length);
+ pos += chunk.length;
+ }
+
+ // Done.
+ return bytes;
+ }
+ }
+
+ /**
+ * Reads and discards {@code size} bytes.
+ *
+ * @throws InvalidProtocolBufferException The end of the stream or the current
+ * limit was reached.
+ */
+ public void skipRawBytes(final int size) throws IOException {
+ if (size < 0) {
+ throw InvalidProtocolBufferException.negativeSize();
+ }
+
+ if (totalBytesRetired + bufferPos + size > currentLimit) {
+ // Read to the end of the stream anyway.
+ skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+ // Then fail.
+ throw InvalidProtocolBufferException.truncatedMessage();
+ }
+
+ if (size <= bufferSize - bufferPos) {
+ // We have all the bytes we need already.
+ bufferPos += size;
+ } else {
+ // Skipping more bytes than are in the buffer. First skip what we have.
+ int pos = bufferSize - bufferPos;
+ bufferPos = bufferSize;
+
+ // Keep refilling the buffer until we get to the point we wanted to skip
+ // to. This has the side effect of ensuring the limits are updated
+ // correctly.
+ refillBuffer(true);
+ while (size - pos > bufferSize) {
+ pos += bufferSize;
+ bufferPos = bufferSize;
+ refillBuffer(true);
+ }
+
+ bufferPos = size - pos;
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/CodedOutputStream.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/CodedOutputStream.java
new file mode 100644
index 0000000..ac5f2d3
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/CodedOutputStream.java
@@ -0,0 +1,1081 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.InputStream;
+
+/**
+ * Encodes and writes protocol message fields.
+ *
+ * <p>This class contains two kinds of methods: methods that write specific
+ * protocol message constructs and field types (e.g. {@link #writeTag} and
+ * {@link #writeInt32}) and methods that write low-level values (e.g.
+ * {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are
+ * writing encoded protocol messages, you should use the former methods, but if
+ * you are writing some other format of your own design, use the latter.
+ *
+ * <p>This class is totally unsynchronized.
+ *
+ * @author kneton@google.com Kenton Varda
+ */
+public final class CodedOutputStream {
+ private final byte[] buffer;
+ private final int limit;
+ private int position;
+
+ private final OutputStream output;
+
+ /**
+ * The buffer size used in {@link #newInstance(OutputStream)}.
+ */
+ public static final int DEFAULT_BUFFER_SIZE = 4096;
+
+ /**
+ * Returns the buffer size to efficiently write dataLength bytes to this
+ * CodedOutputStream. Used by AbstractMessageLite.
+ *
+ * @return the buffer size to efficiently write dataLength bytes to this
+ * CodedOutputStream.
+ */
+ static int computePreferredBufferSize(int dataLength) {
+ if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE;
+ return dataLength;
+ }
+
+ private CodedOutputStream(final byte[] buffer, final int offset,
+ final int length) {
+ output = null;
+ this.buffer = buffer;
+ position = offset;
+ limit = offset + length;
+ }
+
+ private CodedOutputStream(final OutputStream output, final byte[] buffer) {
+ this.output = output;
+ this.buffer = buffer;
+ position = 0;
+ limit = buffer.length;
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} wrapping the given
+ * {@code OutputStream}.
+ */
+ public static CodedOutputStream newInstance(final OutputStream output) {
+ return newInstance(output, DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} wrapping the given
+ * {@code OutputStream} with a given buffer size.
+ */
+ public static CodedOutputStream newInstance(final OutputStream output,
+ final int bufferSize) {
+ return new CodedOutputStream(output, new byte[bufferSize]);
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} that writes directly to the given
+ * byte array. If more bytes are written than fit in the array,
+ * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
+ * array is faster than writing to an {@code OutputStream}. See also
+ * {@link ByteString#newCodedBuilder}.
+ */
+ public static CodedOutputStream newInstance(final byte[] flatArray) {
+ return newInstance(flatArray, 0, flatArray.length);
+ }
+
+ /**
+ * Create a new {@code CodedOutputStream} that writes directly to the given
+ * byte array slice. If more bytes are written than fit in the slice,
+ * {@link OutOfSpaceException} will be thrown. Writing directly to a flat
+ * array is faster than writing to an {@code OutputStream}. See also
+ * {@link ByteString#newCodedBuilder}.
+ */
+ public static CodedOutputStream newInstance(final byte[] flatArray,
+ final int offset,
+ final int length) {
+ return new CodedOutputStream(flatArray, offset, length);
+ }
+
+ // -----------------------------------------------------------------
+
+ /** Write a {@code double} field, including tag, to the stream. */
+ public void writeDouble(final int fieldNumber, final double value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeDoubleNoTag(value);
+ }
+
+ /** Write a {@code float} field, including tag, to the stream. */
+ public void writeFloat(final int fieldNumber, final float value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeFloatNoTag(value);
+ }
+
+ /** Write a {@code uint64} field, including tag, to the stream. */
+ public void writeUInt64(final int fieldNumber, final long value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt64NoTag(value);
+ }
+
+ /** Write an {@code int64} field, including tag, to the stream. */
+ public void writeInt64(final int fieldNumber, final long value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeInt64NoTag(value);
+ }
+
+ /** Write an {@code int32} field, including tag, to the stream. */
+ public void writeInt32(final int fieldNumber, final int value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeInt32NoTag(value);
+ }
+
+ /** Write a {@code fixed64} field, including tag, to the stream. */
+ public void writeFixed64(final int fieldNumber, final long value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeFixed64NoTag(value);
+ }
+
+ /** Write a {@code fixed32} field, including tag, to the stream. */
+ public void writeFixed32(final int fieldNumber, final int value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeFixed32NoTag(value);
+ }
+
+ /** Write a {@code bool} field, including tag, to the stream. */
+ public void writeBool(final int fieldNumber, final boolean value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeBoolNoTag(value);
+ }
+
+ /** Write a {@code string} field, including tag, to the stream. */
+ public void writeString(final int fieldNumber, final String value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeStringNoTag(value);
+ }
+
+ /** Write a {@code group} field, including tag, to the stream. */
+ public void writeGroup(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
+ writeGroupNoTag(value);
+ writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ /**
+ * Write a group represented by an {@link UnknownFieldSet}.
+ *
+ * @deprecated UnknownFieldSet now implements MessageLite, so you can just
+ * call {@link #writeGroup}.
+ */
+ @Deprecated
+ public void writeUnknownGroup(final int fieldNumber,
+ final MessageLite value)
+ throws IOException {
+ writeGroup(fieldNumber, value);
+ }
+
+ /** Write an embedded message field, including tag, to the stream. */
+ public void writeMessage(final int fieldNumber, final MessageLite value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeMessageNoTag(value);
+ }
+
+ /** Write a {@code bytes} field, including tag, to the stream. */
+ public void writeBytes(final int fieldNumber, final ByteString value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ writeBytesNoTag(value);
+ }
+
+ /** Write a {@code uint32} field, including tag, to the stream. */
+ public void writeUInt32(final int fieldNumber, final int value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeUInt32NoTag(value);
+ }
+
+ /**
+ * Write an enum field, including tag, to the stream. Caller is responsible
+ * for converting the enum value to its numeric value.
+ */
+ public void writeEnum(final int fieldNumber, final int value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeEnumNoTag(value);
+ }
+
+ /** Write an {@code sfixed32} field, including tag, to the stream. */
+ public void writeSFixed32(final int fieldNumber, final int value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+ writeSFixed32NoTag(value);
+ }
+
+ /** Write an {@code sfixed64} field, including tag, to the stream. */
+ public void writeSFixed64(final int fieldNumber, final long value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+ writeSFixed64NoTag(value);
+ }
+
+ /** Write an {@code sint32} field, including tag, to the stream. */
+ public void writeSInt32(final int fieldNumber, final int value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeSInt32NoTag(value);
+ }
+
+ /** Write an {@code sint64} field, including tag, to the stream. */
+ public void writeSInt64(final int fieldNumber, final long value)
+ throws IOException {
+ writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+ writeSInt64NoTag(value);
+ }
+
+ /**
+ * Write a MessageSet extension field to the stream. For historical reasons,
+ * the wire format differs from normal fields.
+ */
+ public void writeMessageSetExtension(final int fieldNumber,
+ final MessageLite value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ /**
+ * Write an unparsed MessageSet extension field to the stream. For
+ * historical reasons, the wire format differs from normal fields.
+ */
+ public void writeRawMessageSetExtension(final int fieldNumber,
+ final ByteString value)
+ throws IOException {
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+ writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+ writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+ writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+ }
+
+ // -----------------------------------------------------------------
+
+ /** Write a {@code double} field to the stream. */
+ public void writeDoubleNoTag(final double value) throws IOException {
+ writeRawLittleEndian64(Double.doubleToRawLongBits(value));
+ }
+
+ /** Write a {@code float} field to the stream. */
+ public void writeFloatNoTag(final float value) throws IOException {
+ writeRawLittleEndian32(Float.floatToRawIntBits(value));
+ }
+
+ /** Write a {@code uint64} field to the stream. */
+ public void writeUInt64NoTag(final long value) throws IOException {
+ writeRawVarint64(value);
+ }
+
+ /** Write an {@code int64} field to the stream. */
+ public void writeInt64NoTag(final long value) throws IOException {
+ writeRawVarint64(value);
+ }
+
+ /** Write an {@code int32} field to the stream. */
+ public void writeInt32NoTag(final int value) throws IOException {
+ if (value >= 0) {
+ writeRawVarint32(value);
+ } else {
+ // Must sign-extend.
+ writeRawVarint64(value);
+ }
+ }
+
+ /** Write a {@code fixed64} field to the stream. */
+ public void writeFixed64NoTag(final long value) throws IOException {
+ writeRawLittleEndian64(value);
+ }
+
+ /** Write a {@code fixed32} field to the stream. */
+ public void writeFixed32NoTag(final int value) throws IOException {
+ writeRawLittleEndian32(value);
+ }
+
+ /** Write a {@code bool} field to the stream. */
+ public void writeBoolNoTag(final boolean value) throws IOException {
+ writeRawByte(value ? 1 : 0);
+ }
+
+ /** Write a {@code string} field to the stream. */
+ public void writeStringNoTag(final String value) throws IOException {
+ // Unfortunately there does not appear to be any way to tell Java to encode
+ // UTF-8 directly into our buffer, so we have to let it create its own byte
+ // array and then copy.
+ final byte[] bytes = value.getBytes("UTF-8");
+ writeRawVarint32(bytes.length);
+ writeRawBytes(bytes);
+ }
+
+ /** Write a {@code group} field to the stream. */
+ public void writeGroupNoTag(final MessageLite value) throws IOException {
+ value.writeTo(this);
+ }
+
+ /**
+ * Write a group represented by an {@link UnknownFieldSet}.
+ *
+ * @deprecated UnknownFieldSet now implements MessageLite, so you can just
+ * call {@link #writeGroupNoTag}.
+ */
+ @Deprecated
+ public void writeUnknownGroupNoTag(final MessageLite value)
+ throws IOException {
+ writeGroupNoTag(value);
+ }
+
+ /** Write an embedded message field to the stream. */
+ public void writeMessageNoTag(final MessageLite value) throws IOException {
+ writeRawVarint32(value.getSerializedSize());
+ value.writeTo(this);
+ }
+
+ /** Write a {@code bytes} field to the stream. */
+ public void writeBytesNoTag(final ByteString value) throws IOException {
+ writeRawVarint32(value.size());
+ writeRawBytes(value);
+ }
+
+ /** Write a {@code uint32} field to the stream. */
+ public void writeUInt32NoTag(final int value) throws IOException {
+ writeRawVarint32(value);
+ }
+
+ /**
+ * Write an enum field to the stream. Caller is responsible
+ * for converting the enum value to its numeric value.
+ */
+ public void writeEnumNoTag(final int value) throws IOException {
+ writeInt32NoTag(value);
+ }
+
+ /** Write an {@code sfixed32} field to the stream. */
+ public void writeSFixed32NoTag(final int value) throws IOException {
+ writeRawLittleEndian32(value);
+ }
+
+ /** Write an {@code sfixed64} field to the stream. */
+ public void writeSFixed64NoTag(final long value) throws IOException {
+ writeRawLittleEndian64(value);
+ }
+
+ /** Write an {@code sint32} field to the stream. */
+ public void writeSInt32NoTag(final int value) throws IOException {
+ writeRawVarint32(encodeZigZag32(value));
+ }
+
+ /** Write an {@code sint64} field to the stream. */
+ public void writeSInt64NoTag(final long value) throws IOException {
+ writeRawVarint64(encodeZigZag64(value));
+ }
+
+ // =================================================================
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code double} field, including tag.
+ */
+ public static int computeDoubleSize(final int fieldNumber,
+ final double value) {
+ return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code float} field, including tag.
+ */
+ public static int computeFloatSize(final int fieldNumber, final float value) {
+ return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint64} field, including tag.
+ */
+ public static int computeUInt64Size(final int fieldNumber, final long value) {
+ return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int64} field, including tag.
+ */
+ public static int computeInt64Size(final int fieldNumber, final long value) {
+ return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int32} field, including tag.
+ */
+ public static int computeInt32Size(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed64} field, including tag.
+ */
+ public static int computeFixed64Size(final int fieldNumber,
+ final long value) {
+ return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed32} field, including tag.
+ */
+ public static int computeFixed32Size(final int fieldNumber,
+ final int value) {
+ return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bool} field, including tag.
+ */
+ public static int computeBoolSize(final int fieldNumber,
+ final boolean value) {
+ return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code string} field, including tag.
+ */
+ public static int computeStringSize(final int fieldNumber,
+ final String value) {
+ return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code group} field, including tag.
+ */
+ public static int computeGroupSize(final int fieldNumber,
+ final MessageLite value) {
+ return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code group} field represented by an {@code UnknownFieldSet}, including
+ * tag.
+ *
+ * @deprecated UnknownFieldSet now implements MessageLite, so you can just
+ * call {@link #computeGroupSize}.
+ */
+ @Deprecated
+ public static int computeUnknownGroupSize(final int fieldNumber,
+ final MessageLite value) {
+ return computeGroupSize(fieldNumber, value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * embedded message field, including tag.
+ */
+ public static int computeMessageSize(final int fieldNumber,
+ final MessageLite value) {
+ return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field, including tag.
+ */
+ public static int computeBytesSize(final int fieldNumber,
+ final ByteString value) {
+ return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint32} field, including tag.
+ */
+ public static int computeUInt32Size(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * enum field, including tag. Caller is responsible for converting the
+ * enum value to its numeric value.
+ */
+ public static int computeEnumSize(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed32} field, including tag.
+ */
+ public static int computeSFixed32Size(final int fieldNumber,
+ final int value) {
+ return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed64} field, including tag.
+ */
+ public static int computeSFixed64Size(final int fieldNumber,
+ final long value) {
+ return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint32} field, including tag.
+ */
+ public static int computeSInt32Size(final int fieldNumber, final int value) {
+ return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint64} field, including tag.
+ */
+ public static int computeSInt64Size(final int fieldNumber, final long value) {
+ return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * MessageSet extension to the stream. For historical reasons,
+ * the wire format differs from normal fields.
+ */
+ public static int computeMessageSetExtensionSize(
+ final int fieldNumber, final MessageLite value) {
+ return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
+ computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
+ computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * unparsed MessageSet extension field to the stream. For
+ * historical reasons, the wire format differs from normal fields.
+ */
+ public static int computeRawMessageSetExtensionSize(
+ final int fieldNumber, final ByteString value) {
+ return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
+ computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
+ computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
+ }
+
+ // -----------------------------------------------------------------
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code double} field, including tag.
+ */
+ public static int computeDoubleSizeNoTag(final double value) {
+ return LITTLE_ENDIAN_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code float} field, including tag.
+ */
+ public static int computeFloatSizeNoTag(final float value) {
+ return LITTLE_ENDIAN_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint64} field, including tag.
+ */
+ public static int computeUInt64SizeNoTag(final long value) {
+ return computeRawVarint64Size(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int64} field, including tag.
+ */
+ public static int computeInt64SizeNoTag(final long value) {
+ return computeRawVarint64Size(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code int32} field, including tag.
+ */
+ public static int computeInt32SizeNoTag(final int value) {
+ if (value >= 0) {
+ return computeRawVarint32Size(value);
+ } else {
+ // Must sign-extend.
+ return 10;
+ }
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed64} field.
+ */
+ public static int computeFixed64SizeNoTag(final long value) {
+ return LITTLE_ENDIAN_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code fixed32} field.
+ */
+ public static int computeFixed32SizeNoTag(final int value) {
+ return LITTLE_ENDIAN_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bool} field.
+ */
+ public static int computeBoolSizeNoTag(final boolean value) {
+ return 1;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code string} field.
+ */
+ public static int computeStringSizeNoTag(final String value) {
+ try {
+ final byte[] bytes = value.getBytes("UTF-8");
+ return computeRawVarint32Size(bytes.length) +
+ bytes.length;
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported.", e);
+ }
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code group} field.
+ */
+ public static int computeGroupSizeNoTag(final MessageLite value) {
+ return value.getSerializedSize();
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code group} field represented by an {@code UnknownFieldSet}, including
+ * tag.
+ *
+ * @deprecated UnknownFieldSet now implements MessageLite, so you can just
+ * call {@link #computeUnknownGroupSizeNoTag}.
+ */
+ @Deprecated
+ public static int computeUnknownGroupSizeNoTag(final MessageLite value) {
+ return computeGroupSizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an embedded
+ * message field.
+ */
+ public static int computeMessageSizeNoTag(final MessageLite value) {
+ final int size = value.getSerializedSize();
+ return computeRawVarint32Size(size) + size;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code bytes} field.
+ */
+ public static int computeBytesSizeNoTag(final ByteString value) {
+ return computeRawVarint32Size(value.size()) +
+ value.size();
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * {@code uint32} field.
+ */
+ public static int computeUInt32SizeNoTag(final int value) {
+ return computeRawVarint32Size(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an enum field.
+ * Caller is responsible for converting the enum value to its numeric value.
+ */
+ public static int computeEnumSizeNoTag(final int value) {
+ return computeInt32SizeNoTag(value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed32} field.
+ */
+ public static int computeSFixed32SizeNoTag(final int value) {
+ return LITTLE_ENDIAN_32_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sfixed64} field.
+ */
+ public static int computeSFixed64SizeNoTag(final long value) {
+ return LITTLE_ENDIAN_64_SIZE;
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint32} field.
+ */
+ public static int computeSInt32SizeNoTag(final int value) {
+ return computeRawVarint32Size(encodeZigZag32(value));
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode an
+ * {@code sint64} field.
+ */
+ public static int computeSInt64SizeNoTag(final long value) {
+ return computeRawVarint64Size(encodeZigZag64(value));
+ }
+
+ // =================================================================
+
+ /**
+ * Internal helper that writes the current buffer to the output. The
+ * buffer position is reset to its initial value when this returns.
+ */
+ private void refreshBuffer() throws IOException {
+ if (output == null) {
+ // We're writing to a single buffer.
+ throw new OutOfSpaceException();
+ }
+
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ output.write(buffer, 0, position);
+ position = 0;
+ }
+
+ /**
+ * Flushes the stream and forces any buffered bytes to be written. This
+ * does not flush the underlying OutputStream.
+ */
+ public void flush() throws IOException {
+ if (output != null) {
+ refreshBuffer();
+ }
+ }
+
+ /**
+ * If writing to a flat array, return the space left in the array.
+ * Otherwise, throws {@code UnsupportedOperationException}.
+ */
+ public int spaceLeft() {
+ if (output == null) {
+ return limit - position;
+ } else {
+ throw new UnsupportedOperationException(
+ "spaceLeft() can only be called on CodedOutputStreams that are " +
+ "writing to a flat array.");
+ }
+ }
+
+ /**
+ * Verifies that {@link #spaceLeft()} returns zero. It's common to create
+ * a byte array that is exactly big enough to hold a message, then write to
+ * it with a {@code CodedOutputStream}. Calling {@code checkNoSpaceLeft()}
+ * after writing verifies that the message was actually as big as expected,
+ * which can help catch bugs.
+ */
+ public void checkNoSpaceLeft() {
+ if (spaceLeft() != 0) {
+ throw new IllegalStateException(
+ "Did not write as much data as expected.");
+ }
+ }
+
+ /**
+ * If you create a CodedOutputStream around a simple flat array, you must
+ * not attempt to write more bytes than the array has space. Otherwise,
+ * this exception will be thrown.
+ */
+ public static class OutOfSpaceException extends IOException {
+ private static final long serialVersionUID = -6947486886997889499L;
+
+ OutOfSpaceException() {
+ super("CodedOutputStream was writing to a flat byte array and ran " +
+ "out of space.");
+ }
+ }
+
+ /** Write a single byte. */
+ public void writeRawByte(final byte value) throws IOException {
+ if (position == limit) {
+ refreshBuffer();
+ }
+
+ buffer[position++] = value;
+ }
+
+ /** Write a single byte, represented by an integer value. */
+ public void writeRawByte(final int value) throws IOException {
+ writeRawByte((byte) value);
+ }
+
+ /** Write a byte string. */
+ public void writeRawBytes(final ByteString value) throws IOException {
+ writeRawBytes(value, 0, value.size());
+ }
+
+ /** Write an array of bytes. */
+ public void writeRawBytes(final byte[] value) throws IOException {
+ writeRawBytes(value, 0, value.length);
+ }
+
+ /** Write part of an array of bytes. */
+ public void writeRawBytes(final byte[] value, int offset, int length)
+ throws IOException {
+ if (limit - position >= length) {
+ // We have room in the current buffer.
+ System.arraycopy(value, offset, buffer, position, length);
+ position += length;
+ } else {
+ // Write extends past current buffer. Fill the rest of this buffer and
+ // flush.
+ final int bytesWritten = limit - position;
+ System.arraycopy(value, offset, buffer, position, bytesWritten);
+ offset += bytesWritten;
+ length -= bytesWritten;
+ position = limit;
+ refreshBuffer();
+
+ // Now deal with the rest.
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ if (length <= limit) {
+ // Fits in new buffer.
+ System.arraycopy(value, offset, buffer, 0, length);
+ position = length;
+ } else {
+ // Write is very big. Let's do it all at once.
+ output.write(value, offset, length);
+ }
+ }
+ }
+
+ /** Write part of a byte string. */
+ public void writeRawBytes(final ByteString value, int offset, int length)
+ throws IOException {
+ if (limit - position >= length) {
+ // We have room in the current buffer.
+ value.copyTo(buffer, offset, position, length);
+ position += length;
+ } else {
+ // Write extends past current buffer. Fill the rest of this buffer and
+ // flush.
+ final int bytesWritten = limit - position;
+ value.copyTo(buffer, offset, position, bytesWritten);
+ offset += bytesWritten;
+ length -= bytesWritten;
+ position = limit;
+ refreshBuffer();
+
+ // Now deal with the rest.
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ if (length <= limit) {
+ // Fits in new buffer.
+ value.copyTo(buffer, offset, 0, length);
+ position = length;
+ } else {
+ // Write is very big, but we can't do it all at once without allocating
+ // an a copy of the byte array since ByteString does not give us access
+ // to the underlying bytes. Use the InputStream interface on the
+ // ByteString and our buffer to copy between the two.
+ InputStream inputStreamFrom = value.newInput();
+ if (offset != inputStreamFrom.skip(offset)) {
+ throw new IllegalStateException("Skip failed? Should never happen.");
+ }
+ // Use the buffer as the temporary buffer to avoid allocating memory.
+ while (length > 0) {
+ int bytesToRead = Math.min(length, limit);
+ int bytesRead = inputStreamFrom.read(buffer, 0, bytesToRead);
+ if (bytesRead != bytesToRead) {
+ throw new IllegalStateException("Read failed? Should never happen");
+ }
+ output.write(buffer, 0, bytesRead);
+ length -= bytesRead;
+ }
+ }
+ }
+ }
+
+ /** Encode and write a tag. */
+ public void writeTag(final int fieldNumber, final int wireType)
+ throws IOException {
+ writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
+ }
+
+ /** Compute the number of bytes that would be needed to encode a tag. */
+ public static int computeTagSize(final int fieldNumber) {
+ return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));
+ }
+
+ /**
+ * Encode and write a varint. {@code value} is treated as
+ * unsigned, so it won't be sign-extended if negative.
+ */
+ public void writeRawVarint32(int value) throws IOException {
+ while (true) {
+ if ((value & ~0x7F) == 0) {
+ writeRawByte(value);
+ return;
+ } else {
+ writeRawByte((value & 0x7F) | 0x80);
+ value >>>= 7;
+ }
+ }
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a varint.
+ * {@code value} is treated as unsigned, so it won't be sign-extended if
+ * negative.
+ */
+ public static int computeRawVarint32Size(final int value) {
+ if ((value & (0xffffffff << 7)) == 0) return 1;
+ if ((value & (0xffffffff << 14)) == 0) return 2;
+ if ((value & (0xffffffff << 21)) == 0) return 3;
+ if ((value & (0xffffffff << 28)) == 0) return 4;
+ return 5;
+ }
+
+ /** Encode and write a varint. */
+ public void writeRawVarint64(long value) throws IOException {
+ while (true) {
+ if ((value & ~0x7FL) == 0) {
+ writeRawByte((int)value);
+ return;
+ } else {
+ writeRawByte(((int)value & 0x7F) | 0x80);
+ value >>>= 7;
+ }
+ }
+ }
+
+ /** Compute the number of bytes that would be needed to encode a varint. */
+ public static int computeRawVarint64Size(final long value) {
+ if ((value & (0xffffffffffffffffL << 7)) == 0) return 1;
+ if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
+ if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
+ if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
+ if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
+ if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
+ if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
+ if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
+ if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
+ return 10;
+ }
+
+ /** Write a little-endian 32-bit integer. */
+ public void writeRawLittleEndian32(final int value) throws IOException {
+ writeRawByte((value ) & 0xFF);
+ writeRawByte((value >> 8) & 0xFF);
+ writeRawByte((value >> 16) & 0xFF);
+ writeRawByte((value >> 24) & 0xFF);
+ }
+
+ public static final int LITTLE_ENDIAN_32_SIZE = 4;
+
+ /** Write a little-endian 64-bit integer. */
+ public void writeRawLittleEndian64(final long value) throws IOException {
+ writeRawByte((int)(value ) & 0xFF);
+ writeRawByte((int)(value >> 8) & 0xFF);
+ writeRawByte((int)(value >> 16) & 0xFF);
+ writeRawByte((int)(value >> 24) & 0xFF);
+ writeRawByte((int)(value >> 32) & 0xFF);
+ writeRawByte((int)(value >> 40) & 0xFF);
+ writeRawByte((int)(value >> 48) & 0xFF);
+ writeRawByte((int)(value >> 56) & 0xFF);
+ }
+
+ public static final int LITTLE_ENDIAN_64_SIZE = 8;
+
+ /**
+ * Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
+ * into values that can be efficiently encoded with varint. (Otherwise,
+ * negative values must be sign-extended to 64 bits to be varint encoded,
+ * thus always taking 10 bytes on the wire.)
+ *
+ * @param n A signed 32-bit integer.
+ * @return An unsigned 32-bit integer, stored in a signed int because
+ * Java has no explicit unsigned support.
+ */
+ public static int encodeZigZag32(final int n) {
+ // Note: the right-shift must be arithmetic
+ return (n << 1) ^ (n >> 31);
+ }
+
+ /**
+ * Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
+ * into values that can be efficiently encoded with varint. (Otherwise,
+ * negative values must be sign-extended to 64 bits to be varint encoded,
+ * thus always taking 10 bytes on the wire.)
+ *
+ * @param n A signed 64-bit integer.
+ * @return An unsigned 64-bit integer, stored in a signed int because
+ * Java has no explicit unsigned support.
+ */
+ public static long encodeZigZag64(final long n) {
+ // Note: the right-shift must be arithmetic
+ return (n << 1) ^ (n >> 63);
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Descriptors.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Descriptors.java
new file mode 100644
index 0000000..2ee8459
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Descriptors.java
@@ -0,0 +1,1887 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.DescriptorProtos.*;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Contains a collection of classes which describe protocol message types.
+ *
+ * Every message type has a {@link Descriptor}, which lists all
+ * its fields and other information about a type. You can get a message
+ * type's descriptor by calling {@code MessageType.getDescriptor()}, or
+ * (given a message object of the type) {@code message.getDescriptorForType()}.
+ * Furthermore, each message is associated with a {@link FileDescriptor} for
+ * a relevant {@code .proto} file. You can obtain it by calling
+ * {@code Descriptor.getFile()}. A {@link FileDescriptor} contains descriptors
+ * for all the messages defined in that file, and file descriptors for all the
+ * imported {@code .proto} files.
+ *
+ * Descriptors are built from DescriptorProtos, as defined in
+ * {@code google/protobuf/descriptor.proto}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class Descriptors {
+ /**
+ * Describes a {@code .proto} file, including everything defined within.
+ * That includes, in particular, descriptors for all the messages and
+ * file descriptors for all other imported {@code .proto} files
+ * (dependencies).
+ */
+ public static final class FileDescriptor {
+ /** Convert the descriptor to its protocol message representation. */
+ public FileDescriptorProto toProto() { return proto; }
+
+ /** Get the file name. */
+ public String getName() { return proto.getName(); }
+
+ /**
+ * Get the proto package name. This is the package name given by the
+ * {@code package} statement in the {@code .proto} file, which differs
+ * from the Java package.
+ */
+ public String getPackage() { return proto.getPackage(); }
+
+ /** Get the {@code FileOptions}, defined in {@code descriptor.proto}. */
+ public FileOptions getOptions() { return proto.getOptions(); }
+
+ /** Get a list of top-level message types declared in this file. */
+ public List<Descriptor> getMessageTypes() {
+ return Collections.unmodifiableList(Arrays.asList(messageTypes));
+ }
+
+ /** Get a list of top-level enum types declared in this file. */
+ public List<EnumDescriptor> getEnumTypes() {
+ return Collections.unmodifiableList(Arrays.asList(enumTypes));
+ }
+
+ /** Get a list of top-level services declared in this file. */
+ public List<ServiceDescriptor> getServices() {
+ return Collections.unmodifiableList(Arrays.asList(services));
+ }
+
+ /** Get a list of top-level extensions declared in this file. */
+ public List<FieldDescriptor> getExtensions() {
+ return Collections.unmodifiableList(Arrays.asList(extensions));
+ }
+
+ /** Get a list of this file's dependencies (imports). */
+ public List<FileDescriptor> getDependencies() {
+ return Collections.unmodifiableList(Arrays.asList(dependencies));
+ }
+
+ /**
+ * Find a message type in the file by name. Does not find nested types.
+ *
+ * @param name The unqualified type name to look for.
+ * @return The message type's descriptor, or {@code null} if not found.
+ */
+ public Descriptor findMessageTypeByName(String name) {
+ // Don't allow looking up nested types. This will make optimization
+ // easier later.
+ if (name.indexOf('.') != -1) {
+ return null;
+ }
+ if (getPackage().length() > 0) {
+ name = getPackage() + '.' + name;
+ }
+ final GenericDescriptor result = pool.findSymbol(name);
+ if (result != null && result instanceof Descriptor &&
+ result.getFile() == this) {
+ return (Descriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Find an enum type in the file by name. Does not find nested types.
+ *
+ * @param name The unqualified type name to look for.
+ * @return The enum type's descriptor, or {@code null} if not found.
+ */
+ public EnumDescriptor findEnumTypeByName(String name) {
+ // Don't allow looking up nested types. This will make optimization
+ // easier later.
+ if (name.indexOf('.') != -1) {
+ return null;
+ }
+ if (getPackage().length() > 0) {
+ name = getPackage() + '.' + name;
+ }
+ final GenericDescriptor result = pool.findSymbol(name);
+ if (result != null && result instanceof EnumDescriptor &&
+ result.getFile() == this) {
+ return (EnumDescriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Find a service type in the file by name.
+ *
+ * @param name The unqualified type name to look for.
+ * @return The service type's descriptor, or {@code null} if not found.
+ */
+ public ServiceDescriptor findServiceByName(String name) {
+ // Don't allow looking up nested types. This will make optimization
+ // easier later.
+ if (name.indexOf('.') != -1) {
+ return null;
+ }
+ if (getPackage().length() > 0) {
+ name = getPackage() + '.' + name;
+ }
+ final GenericDescriptor result = pool.findSymbol(name);
+ if (result != null && result instanceof ServiceDescriptor &&
+ result.getFile() == this) {
+ return (ServiceDescriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Find an extension in the file by name. Does not find extensions nested
+ * inside message types.
+ *
+ * @param name The unqualified extension name to look for.
+ * @return The extension's descriptor, or {@code null} if not found.
+ */
+ public FieldDescriptor findExtensionByName(String name) {
+ if (name.indexOf('.') != -1) {
+ return null;
+ }
+ if (getPackage().length() > 0) {
+ name = getPackage() + '.' + name;
+ }
+ final GenericDescriptor result = pool.findSymbol(name);
+ if (result != null && result instanceof FieldDescriptor &&
+ result.getFile() == this) {
+ return (FieldDescriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Construct a {@code FileDescriptor}.
+ *
+ * @param proto The protocol message form of the FileDescriptor.
+ * @param dependencies {@code FileDescriptor}s corresponding to all of
+ * the file's dependencies, in the exact order listed
+ * in {@code proto}.
+ * @throws DescriptorValidationException {@code proto} is not a valid
+ * descriptor. This can occur for a number of reasons, e.g.
+ * because a field has an undefined type or because two messages
+ * were defined with the same name.
+ */
+ public static FileDescriptor buildFrom(final FileDescriptorProto proto,
+ final FileDescriptor[] dependencies)
+ throws DescriptorValidationException {
+ // Building decsriptors involves two steps: translating and linking.
+ // In the translation step (implemented by FileDescriptor's
+ // constructor), we build an object tree mirroring the
+ // FileDescriptorProto's tree and put all of the descriptors into the
+ // DescriptorPool's lookup tables. In the linking step, we look up all
+ // type references in the DescriptorPool, so that, for example, a
+ // FieldDescriptor for an embedded message contains a pointer directly
+ // to the Descriptor for that message's type. We also detect undefined
+ // types in the linking step.
+ final DescriptorPool pool = new DescriptorPool(dependencies);
+ final FileDescriptor result =
+ new FileDescriptor(proto, dependencies, pool);
+
+ if (dependencies.length != proto.getDependencyCount()) {
+ throw new DescriptorValidationException(result,
+ "Dependencies passed to FileDescriptor.buildFrom() don't match " +
+ "those listed in the FileDescriptorProto.");
+ }
+ for (int i = 0; i < proto.getDependencyCount(); i++) {
+ if (!dependencies[i].getName().equals(proto.getDependency(i))) {
+ throw new DescriptorValidationException(result,
+ "Dependencies passed to FileDescriptor.buildFrom() don't match " +
+ "those listed in the FileDescriptorProto.");
+ }
+ }
+
+ result.crossLink();
+ return result;
+ }
+
+ /**
+ * This method is to be called by generated code only. It is equivalent
+ * to {@code buildFrom} except that the {@code FileDescriptorProto} is
+ * encoded in protocol buffer wire format.
+ */
+ public static void internalBuildGeneratedFileFrom(
+ final String[] descriptorDataParts,
+ final FileDescriptor[] dependencies,
+ final InternalDescriptorAssigner descriptorAssigner) {
+ // Hack: We can't embed a raw byte array inside generated Java code
+ // (at least, not efficiently), but we can embed Strings. So, the
+ // protocol compiler embeds the FileDescriptorProto as a giant
+ // string literal which is passed to this function to construct the
+ // file's FileDescriptor. The string literal contains only 8-bit
+ // characters, each one representing a byte of the FileDescriptorProto's
+ // serialized form. So, if we convert it to bytes in ISO-8859-1, we
+ // should get the original bytes that we want.
+
+ // descriptorData may contain multiple strings in order to get around the
+ // Java 64k string literal limit.
+ StringBuilder descriptorData = new StringBuilder();
+ for (String part : descriptorDataParts) {
+ descriptorData.append(part);
+ }
+
+ final byte[] descriptorBytes;
+ try {
+ descriptorBytes = descriptorData.toString().getBytes("ISO-8859-1");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(
+ "Standard encoding ISO-8859-1 not supported by JVM.", e);
+ }
+
+ FileDescriptorProto proto;
+ try {
+ proto = FileDescriptorProto.parseFrom(descriptorBytes);
+ } catch (InvalidProtocolBufferException e) {
+ throw new IllegalArgumentException(
+ "Failed to parse protocol buffer descriptor for generated code.", e);
+ }
+
+ final FileDescriptor result;
+ try {
+ result = buildFrom(proto, dependencies);
+ } catch (DescriptorValidationException e) {
+ throw new IllegalArgumentException(
+ "Invalid embedded descriptor for \"" + proto.getName() + "\".", e);
+ }
+
+ final ExtensionRegistry registry =
+ descriptorAssigner.assignDescriptors(result);
+
+ if (registry != null) {
+ // We must re-parse the proto using the registry.
+ try {
+ proto = FileDescriptorProto.parseFrom(descriptorBytes, registry);
+ } catch (InvalidProtocolBufferException e) {
+ throw new IllegalArgumentException(
+ "Failed to parse protocol buffer descriptor for generated code.",
+ e);
+ }
+
+ result.setProto(proto);
+ }
+ }
+
+ /**
+ * This class should be used by generated code only. When calling
+ * {@link FileDescriptor#internalBuildGeneratedFileFrom}, the caller
+ * provides a callback implementing this interface. The callback is called
+ * after the FileDescriptor has been constructed, in order to assign all
+ * the global variales defined in the generated code which point at parts
+ * of the FileDescriptor. The callback returns an ExtensionRegistry which
+ * contains any extensions which might be used in the descriptor -- that
+ * is, extensions of the various "Options" messages defined in
+ * descriptor.proto. The callback may also return null to indicate that
+ * no extensions are used in the decsriptor.
+ */
+ public interface InternalDescriptorAssigner {
+ ExtensionRegistry assignDescriptors(FileDescriptor root);
+ }
+
+ private FileDescriptorProto proto;
+ private final Descriptor[] messageTypes;
+ private final EnumDescriptor[] enumTypes;
+ private final ServiceDescriptor[] services;
+ private final FieldDescriptor[] extensions;
+ private final FileDescriptor[] dependencies;
+ private final DescriptorPool pool;
+
+ private FileDescriptor(final FileDescriptorProto proto,
+ final FileDescriptor[] dependencies,
+ final DescriptorPool pool)
+ throws DescriptorValidationException {
+ this.pool = pool;
+ this.proto = proto;
+ this.dependencies = dependencies.clone();
+
+ pool.addPackage(getPackage(), this);
+
+ messageTypes = new Descriptor[proto.getMessageTypeCount()];
+ for (int i = 0; i < proto.getMessageTypeCount(); i++) {
+ messageTypes[i] =
+ new Descriptor(proto.getMessageType(i), this, null, i);
+ }
+
+ enumTypes = new EnumDescriptor[proto.getEnumTypeCount()];
+ for (int i = 0; i < proto.getEnumTypeCount(); i++) {
+ enumTypes[i] = new EnumDescriptor(proto.getEnumType(i), this, null, i);
+ }
+
+ services = new ServiceDescriptor[proto.getServiceCount()];
+ for (int i = 0; i < proto.getServiceCount(); i++) {
+ services[i] = new ServiceDescriptor(proto.getService(i), this, i);
+ }
+
+ extensions = new FieldDescriptor[proto.getExtensionCount()];
+ for (int i = 0; i < proto.getExtensionCount(); i++) {
+ extensions[i] = new FieldDescriptor(
+ proto.getExtension(i), this, null, i, true);
+ }
+ }
+
+ /** Look up and cross-link all field types, etc. */
+ private void crossLink() throws DescriptorValidationException {
+ for (final Descriptor messageType : messageTypes) {
+ messageType.crossLink();
+ }
+
+ for (final ServiceDescriptor service : services) {
+ service.crossLink();
+ }
+
+ for (final FieldDescriptor extension : extensions) {
+ extension.crossLink();
+ }
+ }
+
+ /**
+ * Replace our {@link FileDescriptorProto} with the given one, which is
+ * identical except that it might contain extensions that weren't present
+ * in the original. This method is needed for bootstrapping when a file
+ * defines custom options. The options may be defined in the file itself,
+ * so we can't actually parse them until we've constructed the descriptors,
+ * but to construct the decsriptors we have to have parsed the descriptor
+ * protos. So, we have to parse the descriptor protos a second time after
+ * constructing the descriptors.
+ */
+ private void setProto(final FileDescriptorProto proto) {
+ this.proto = proto;
+
+ for (int i = 0; i < messageTypes.length; i++) {
+ messageTypes[i].setProto(proto.getMessageType(i));
+ }
+
+ for (int i = 0; i < enumTypes.length; i++) {
+ enumTypes[i].setProto(proto.getEnumType(i));
+ }
+
+ for (int i = 0; i < services.length; i++) {
+ services[i].setProto(proto.getService(i));
+ }
+
+ for (int i = 0; i < extensions.length; i++) {
+ extensions[i].setProto(proto.getExtension(i));
+ }
+ }
+ }
+
+ // =================================================================
+
+ /** Describes a message type. */
+ public static final class Descriptor implements GenericDescriptor {
+ /**
+ * Get the index of this descriptor within its parent. In other words,
+ * given a {@link FileDescriptor} {@code file}, the following is true:
+ * <pre>
+ * for all i in [0, file.getMessageTypeCount()):
+ * file.getMessageType(i).getIndex() == i
+ * </pre>
+ * Similarly, for a {@link Descriptor} {@code messageType}:
+ * <pre>
+ * for all i in [0, messageType.getNestedTypeCount()):
+ * messageType.getNestedType(i).getIndex() == i
+ * </pre>
+ */
+ public int getIndex() { return index; }
+
+ /** Convert the descriptor to its protocol message representation. */
+ public DescriptorProto toProto() { return proto; }
+
+ /** Get the type's unqualified name. */
+ public String getName() { return proto.getName(); }
+
+ /**
+ * Get the type's fully-qualified name, within the proto language's
+ * namespace. This differs from the Java name. For example, given this
+ * {@code .proto}:
+ * <pre>
+ * package foo.bar;
+ * option java_package = "com.example.protos"
+ * message Baz {}
+ * </pre>
+ * {@code Baz}'s full name is "foo.bar.Baz".
+ */
+ public String getFullName() { return fullName; }
+
+ /** Get the {@link FileDescriptor} containing this descriptor. */
+ public FileDescriptor getFile() { return file; }
+
+ /** If this is a nested type, get the outer descriptor, otherwise null. */
+ public Descriptor getContainingType() { return containingType; }
+
+ /** Get the {@code MessageOptions}, defined in {@code descriptor.proto}. */
+ public MessageOptions getOptions() { return proto.getOptions(); }
+
+ /** Get a list of this message type's fields. */
+ public List<FieldDescriptor> getFields() {
+ return Collections.unmodifiableList(Arrays.asList(fields));
+ }
+
+ /** Get a list of this message type's extensions. */
+ public List<FieldDescriptor> getExtensions() {
+ return Collections.unmodifiableList(Arrays.asList(extensions));
+ }
+
+ /** Get a list of message types nested within this one. */
+ public List<Descriptor> getNestedTypes() {
+ return Collections.unmodifiableList(Arrays.asList(nestedTypes));
+ }
+
+ /** Get a list of enum types nested within this one. */
+ public List<EnumDescriptor> getEnumTypes() {
+ return Collections.unmodifiableList(Arrays.asList(enumTypes));
+ }
+
+ /** Determines if the given field number is an extension. */
+ public boolean isExtensionNumber(final int number) {
+ for (final DescriptorProto.ExtensionRange range :
+ proto.getExtensionRangeList()) {
+ if (range.getStart() <= number && number < range.getEnd()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Finds a field by name.
+ * @param name The unqualified name of the field (e.g. "foo").
+ * @return The field's descriptor, or {@code null} if not found.
+ */
+ public FieldDescriptor findFieldByName(final String name) {
+ final GenericDescriptor result =
+ file.pool.findSymbol(fullName + '.' + name);
+ if (result != null && result instanceof FieldDescriptor) {
+ return (FieldDescriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Finds a field by field number.
+ * @param number The field number within this message type.
+ * @return The field's descriptor, or {@code null} if not found.
+ */
+ public FieldDescriptor findFieldByNumber(final int number) {
+ return file.pool.fieldsByNumber.get(
+ new DescriptorPool.DescriptorIntPair(this, number));
+ }
+
+ /**
+ * Finds a nested message type by name.
+ * @param name The unqualified name of the nested type (e.g. "Foo").
+ * @return The types's descriptor, or {@code null} if not found.
+ */
+ public Descriptor findNestedTypeByName(final String name) {
+ final GenericDescriptor result =
+ file.pool.findSymbol(fullName + '.' + name);
+ if (result != null && result instanceof Descriptor) {
+ return (Descriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Finds a nested enum type by name.
+ * @param name The unqualified name of the nested type (e.g. "Foo").
+ * @return The types's descriptor, or {@code null} if not found.
+ */
+ public EnumDescriptor findEnumTypeByName(final String name) {
+ final GenericDescriptor result =
+ file.pool.findSymbol(fullName + '.' + name);
+ if (result != null && result instanceof EnumDescriptor) {
+ return (EnumDescriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ private final int index;
+ private DescriptorProto proto;
+ private final String fullName;
+ private final FileDescriptor file;
+ private final Descriptor containingType;
+ private final Descriptor[] nestedTypes;
+ private final EnumDescriptor[] enumTypes;
+ private final FieldDescriptor[] fields;
+ private final FieldDescriptor[] extensions;
+
+ private Descriptor(final DescriptorProto proto,
+ final FileDescriptor file,
+ final Descriptor parent,
+ final int index)
+ throws DescriptorValidationException {
+ this.index = index;
+ this.proto = proto;
+ fullName = computeFullName(file, parent, proto.getName());
+ this.file = file;
+ containingType = parent;
+
+ nestedTypes = new Descriptor[proto.getNestedTypeCount()];
+ for (int i = 0; i < proto.getNestedTypeCount(); i++) {
+ nestedTypes[i] = new Descriptor(
+ proto.getNestedType(i), file, this, i);
+ }
+
+ enumTypes = new EnumDescriptor[proto.getEnumTypeCount()];
+ for (int i = 0; i < proto.getEnumTypeCount(); i++) {
+ enumTypes[i] = new EnumDescriptor(
+ proto.getEnumType(i), file, this, i);
+ }
+
+ fields = new FieldDescriptor[proto.getFieldCount()];
+ for (int i = 0; i < proto.getFieldCount(); i++) {
+ fields[i] = new FieldDescriptor(
+ proto.getField(i), file, this, i, false);
+ }
+
+ extensions = new FieldDescriptor[proto.getExtensionCount()];
+ for (int i = 0; i < proto.getExtensionCount(); i++) {
+ extensions[i] = new FieldDescriptor(
+ proto.getExtension(i), file, this, i, true);
+ }
+
+ file.pool.addSymbol(this);
+ }
+
+ /** Look up and cross-link all field types, etc. */
+ private void crossLink() throws DescriptorValidationException {
+ for (final Descriptor nestedType : nestedTypes) {
+ nestedType.crossLink();
+ }
+
+ for (final FieldDescriptor field : fields) {
+ field.crossLink();
+ }
+
+ for (final FieldDescriptor extension : extensions) {
+ extension.crossLink();
+ }
+ }
+
+ /** See {@link FileDescriptor#setProto}. */
+ private void setProto(final DescriptorProto proto) {
+ this.proto = proto;
+
+ for (int i = 0; i < nestedTypes.length; i++) {
+ nestedTypes[i].setProto(proto.getNestedType(i));
+ }
+
+ for (int i = 0; i < enumTypes.length; i++) {
+ enumTypes[i].setProto(proto.getEnumType(i));
+ }
+
+ for (int i = 0; i < fields.length; i++) {
+ fields[i].setProto(proto.getField(i));
+ }
+
+ for (int i = 0; i < extensions.length; i++) {
+ extensions[i].setProto(proto.getExtension(i));
+ }
+ }
+ }
+
+ // =================================================================
+
+ /** Describes a field of a message type. */
+ public static final class FieldDescriptor
+ implements GenericDescriptor, Comparable<FieldDescriptor>,
+ FieldSet.FieldDescriptorLite<FieldDescriptor> {
+ /**
+ * Get the index of this descriptor within its parent.
+ * @see Descriptor#getIndex()
+ */
+ public int getIndex() { return index; }
+
+ /** Convert the descriptor to its protocol message representation. */
+ public FieldDescriptorProto toProto() { return proto; }
+
+ /** Get the field's unqualified name. */
+ public String getName() { return proto.getName(); }
+
+ /** Get the field's number. */
+ public int getNumber() { return proto.getNumber(); }
+
+ /**
+ * Get the field's fully-qualified name.
+ * @see Descriptor#getFullName()
+ */
+ public String getFullName() { return fullName; }
+
+ /**
+ * Get the field's java type. This is just for convenience. Every
+ * {@code FieldDescriptorProto.Type} maps to exactly one Java type.
+ */
+ public JavaType getJavaType() { return type.getJavaType(); }
+
+ /** For internal use only. */
+ public WireFormat.JavaType getLiteJavaType() {
+ return getLiteType().getJavaType();
+ }
+
+ /** Get the {@code FileDescriptor} containing this descriptor. */
+ public FileDescriptor getFile() { return file; }
+
+ /** Get the field's declared type. */
+ public Type getType() { return type; }
+
+ /** For internal use only. */
+ public WireFormat.FieldType getLiteType() {
+ return table[type.ordinal()];
+ }
+ // I'm pretty sure values() constructs a new array every time, since there
+ // is nothing stopping the caller from mutating the array. Therefore we
+ // make a static copy here.
+ private static final WireFormat.FieldType[] table =
+ WireFormat.FieldType.values();
+
+ /** Is this field declared required? */
+ public boolean isRequired() {
+ return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REQUIRED;
+ }
+
+ /** Is this field declared optional? */
+ public boolean isOptional() {
+ return proto.getLabel() == FieldDescriptorProto.Label.LABEL_OPTIONAL;
+ }
+
+ /** Is this field declared repeated? */
+ public boolean isRepeated() {
+ return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED;
+ }
+
+ /** Does this field have the {@code [packed = true]} option? */
+ public boolean isPacked() {
+ return getOptions().getPacked();
+ }
+
+ /** Can this field be packed? i.e. is it a repeated primitive field? */
+ public boolean isPackable() {
+ return isRepeated() && getLiteType().isPackable();
+ }
+
+ /** Returns true if the field had an explicitly-defined default value. */
+ public boolean hasDefaultValue() { return proto.hasDefaultValue(); }
+
+ /**
+ * Returns the field's default value. Valid for all types except for
+ * messages and groups. For all other types, the object returned is of
+ * the same class that would returned by Message.getField(this).
+ */
+ public Object getDefaultValue() {
+ if (getJavaType() == JavaType.MESSAGE) {
+ throw new UnsupportedOperationException(
+ "FieldDescriptor.getDefaultValue() called on an embedded message " +
+ "field.");
+ }
+ return defaultValue;
+ }
+
+ /** Get the {@code FieldOptions}, defined in {@code descriptor.proto}. */
+ public FieldOptions getOptions() { return proto.getOptions(); }
+
+ /** Is this field an extension? */
+ public boolean isExtension() { return proto.hasExtendee(); }
+
+ /**
+ * Get the field's containing type. For extensions, this is the type being
+ * extended, not the location where the extension was defined. See
+ * {@link #getExtensionScope()}.
+ */
+ public Descriptor getContainingType() { return containingType; }
+
+ /**
+ * For extensions defined nested within message types, gets the outer
+ * type. Not valid for non-extension fields. For example, consider
+ * this {@code .proto} file:
+ * <pre>
+ * message Foo {
+ * extensions 1000 to max;
+ * }
+ * extend Foo {
+ * optional int32 baz = 1234;
+ * }
+ * message Bar {
+ * extend Foo {
+ * optional int32 qux = 4321;
+ * }
+ * }
+ * </pre>
+ * Both {@code baz}'s and {@code qux}'s containing type is {@code Foo}.
+ * However, {@code baz}'s extension scope is {@code null} while
+ * {@code qux}'s extension scope is {@code Bar}.
+ */
+ public Descriptor getExtensionScope() {
+ if (!isExtension()) {
+ throw new UnsupportedOperationException(
+ "This field is not an extension.");
+ }
+ return extensionScope;
+ }
+
+ /** For embedded message and group fields, gets the field's type. */
+ public Descriptor getMessageType() {
+ if (getJavaType() != JavaType.MESSAGE) {
+ throw new UnsupportedOperationException(
+ "This field is not of message type.");
+ }
+ return messageType;
+ }
+
+ /** For enum fields, gets the field's type. */
+ public EnumDescriptor getEnumType() {
+ if (getJavaType() != JavaType.ENUM) {
+ throw new UnsupportedOperationException(
+ "This field is not of enum type.");
+ }
+ return enumType;
+ }
+
+ /**
+ * Compare with another {@code FieldDescriptor}. This orders fields in
+ * "canonical" order, which simply means ascending order by field number.
+ * {@code other} must be a field of the same type -- i.e.
+ * {@code getContainingType()} must return the same {@code Descriptor} for
+ * both fields.
+ *
+ * @return negative, zero, or positive if {@code this} is less than,
+ * equal to, or greater than {@code other}, respectively.
+ */
+ public int compareTo(final FieldDescriptor other) {
+ if (other.containingType != containingType) {
+ throw new IllegalArgumentException(
+ "FieldDescriptors can only be compared to other FieldDescriptors " +
+ "for fields of the same message type.");
+ }
+ return getNumber() - other.getNumber();
+ }
+
+ private final int index;
+
+ private FieldDescriptorProto proto;
+ private final String fullName;
+ private final FileDescriptor file;
+ private final Descriptor extensionScope;
+
+ // Possibly initialized during cross-linking.
+ private Type type;
+ private Descriptor containingType;
+ private Descriptor messageType;
+ private EnumDescriptor enumType;
+ private Object defaultValue;
+
+ public enum Type {
+ DOUBLE (JavaType.DOUBLE ),
+ FLOAT (JavaType.FLOAT ),
+ INT64 (JavaType.LONG ),
+ UINT64 (JavaType.LONG ),
+ INT32 (JavaType.INT ),
+ FIXED64 (JavaType.LONG ),
+ FIXED32 (JavaType.INT ),
+ BOOL (JavaType.BOOLEAN ),
+ STRING (JavaType.STRING ),
+ GROUP (JavaType.MESSAGE ),
+ MESSAGE (JavaType.MESSAGE ),
+ BYTES (JavaType.BYTE_STRING),
+ UINT32 (JavaType.INT ),
+ ENUM (JavaType.ENUM ),
+ SFIXED32(JavaType.INT ),
+ SFIXED64(JavaType.LONG ),
+ SINT32 (JavaType.INT ),
+ SINT64 (JavaType.LONG );
+
+ Type(final JavaType javaType) {
+ this.javaType = javaType;
+ }
+
+ private JavaType javaType;
+
+ public FieldDescriptorProto.Type toProto() {
+ return FieldDescriptorProto.Type.valueOf(ordinal() + 1);
+ }
+ public JavaType getJavaType() { return javaType; }
+
+ public static Type valueOf(final FieldDescriptorProto.Type type) {
+ return values()[type.getNumber() - 1];
+ }
+ }
+
+ static {
+ // Refuse to init if someone added a new declared type.
+ if (Type.values().length != FieldDescriptorProto.Type.values().length) {
+ throw new RuntimeException(
+ "descriptor.proto has a new declared type but Desrciptors.java " +
+ "wasn't updated.");
+ }
+ }
+
+ public enum JavaType {
+ INT(0),
+ LONG(0L),
+ FLOAT(0F),
+ DOUBLE(0D),
+ BOOLEAN(false),
+ STRING(""),
+ BYTE_STRING(ByteString.EMPTY),
+ ENUM(null),
+ MESSAGE(null);
+
+ JavaType(final Object defaultDefault) {
+ this.defaultDefault = defaultDefault;
+ }
+
+ /**
+ * The default default value for fields of this type, if it's a primitive
+ * type. This is meant for use inside this file only, hence is private.
+ */
+ private final Object defaultDefault;
+ }
+
+ private FieldDescriptor(final FieldDescriptorProto proto,
+ final FileDescriptor file,
+ final Descriptor parent,
+ final int index,
+ final boolean isExtension)
+ throws DescriptorValidationException {
+ this.index = index;
+ this.proto = proto;
+ fullName = computeFullName(file, parent, proto.getName());
+ this.file = file;
+
+ if (proto.hasType()) {
+ type = Type.valueOf(proto.getType());
+ }
+
+ if (getNumber() <= 0) {
+ throw new DescriptorValidationException(this,
+ "Field numbers must be positive integers.");
+ }
+
+ // Only repeated primitive fields may be packed.
+ if (proto.getOptions().getPacked() && !isPackable()) {
+ throw new DescriptorValidationException(this,
+ "[packed = true] can only be specified for repeated primitive " +
+ "fields.");
+ }
+
+ if (isExtension) {
+ if (!proto.hasExtendee()) {
+ throw new DescriptorValidationException(this,
+ "FieldDescriptorProto.extendee not set for extension field.");
+ }
+ containingType = null; // Will be filled in when cross-linking
+ if (parent != null) {
+ extensionScope = parent;
+ } else {
+ extensionScope = null;
+ }
+ } else {
+ if (proto.hasExtendee()) {
+ throw new DescriptorValidationException(this,
+ "FieldDescriptorProto.extendee set for non-extension field.");
+ }
+ containingType = parent;
+ extensionScope = null;
+ }
+
+ file.pool.addSymbol(this);
+ }
+
+ /** Look up and cross-link all field types, etc. */
+ private void crossLink() throws DescriptorValidationException {
+ if (proto.hasExtendee()) {
+ final GenericDescriptor extendee =
+ file.pool.lookupSymbol(proto.getExtendee(), this);
+ if (!(extendee instanceof Descriptor)) {
+ throw new DescriptorValidationException(this,
+ '\"' + proto.getExtendee() + "\" is not a message type.");
+ }
+ containingType = (Descriptor)extendee;
+
+ if (!getContainingType().isExtensionNumber(getNumber())) {
+ throw new DescriptorValidationException(this,
+ '\"' + getContainingType().getFullName() +
+ "\" does not declare " + getNumber() +
+ " as an extension number.");
+ }
+ }
+
+ if (proto.hasTypeName()) {
+ final GenericDescriptor typeDescriptor =
+ file.pool.lookupSymbol(proto.getTypeName(), this);
+
+ if (!proto.hasType()) {
+ // Choose field type based on symbol.
+ if (typeDescriptor instanceof Descriptor) {
+ type = Type.MESSAGE;
+ } else if (typeDescriptor instanceof EnumDescriptor) {
+ type = Type.ENUM;
+ } else {
+ throw new DescriptorValidationException(this,
+ '\"' + proto.getTypeName() + "\" is not a type.");
+ }
+ }
+
+ if (getJavaType() == JavaType.MESSAGE) {
+ if (!(typeDescriptor instanceof Descriptor)) {
+ throw new DescriptorValidationException(this,
+ '\"' + proto.getTypeName() + "\" is not a message type.");
+ }
+ messageType = (Descriptor)typeDescriptor;
+
+ if (proto.hasDefaultValue()) {
+ throw new DescriptorValidationException(this,
+ "Messages can't have default values.");
+ }
+ } else if (getJavaType() == JavaType.ENUM) {
+ if (!(typeDescriptor instanceof EnumDescriptor)) {
+ throw new DescriptorValidationException(this,
+ '\"' + proto.getTypeName() + "\" is not an enum type.");
+ }
+ enumType = (EnumDescriptor)typeDescriptor;
+ } else {
+ throw new DescriptorValidationException(this,
+ "Field with primitive type has type_name.");
+ }
+ } else {
+ if (getJavaType() == JavaType.MESSAGE ||
+ getJavaType() == JavaType.ENUM) {
+ throw new DescriptorValidationException(this,
+ "Field with message or enum type missing type_name.");
+ }
+ }
+
+ // We don't attempt to parse the default value until here because for
+ // enums we need the enum type's descriptor.
+ if (proto.hasDefaultValue()) {
+ if (isRepeated()) {
+ throw new DescriptorValidationException(this,
+ "Repeated fields cannot have default values.");
+ }
+
+ try {
+ switch (getType()) {
+ case INT32:
+ case SINT32:
+ case SFIXED32:
+ defaultValue = TextFormat.parseInt32(proto.getDefaultValue());
+ break;
+ case UINT32:
+ case FIXED32:
+ defaultValue = TextFormat.parseUInt32(proto.getDefaultValue());
+ break;
+ case INT64:
+ case SINT64:
+ case SFIXED64:
+ defaultValue = TextFormat.parseInt64(proto.getDefaultValue());
+ break;
+ case UINT64:
+ case FIXED64:
+ defaultValue = TextFormat.parseUInt64(proto.getDefaultValue());
+ break;
+ case FLOAT:
+ if (proto.getDefaultValue().equals("inf")) {
+ defaultValue = Float.POSITIVE_INFINITY;
+ } else if (proto.getDefaultValue().equals("-inf")) {
+ defaultValue = Float.NEGATIVE_INFINITY;
+ } else if (proto.getDefaultValue().equals("nan")) {
+ defaultValue = Float.NaN;
+ } else {
+ defaultValue = Float.valueOf(proto.getDefaultValue());
+ }
+ break;
+ case DOUBLE:
+ if (proto.getDefaultValue().equals("inf")) {
+ defaultValue = Double.POSITIVE_INFINITY;
+ } else if (proto.getDefaultValue().equals("-inf")) {
+ defaultValue = Double.NEGATIVE_INFINITY;
+ } else if (proto.getDefaultValue().equals("nan")) {
+ defaultValue = Double.NaN;
+ } else {
+ defaultValue = Double.valueOf(proto.getDefaultValue());
+ }
+ break;
+ case BOOL:
+ defaultValue = Boolean.valueOf(proto.getDefaultValue());
+ break;
+ case STRING:
+ defaultValue = proto.getDefaultValue();
+ break;
+ case BYTES:
+ try {
+ defaultValue =
+ TextFormat.unescapeBytes(proto.getDefaultValue());
+ } catch (TextFormat.InvalidEscapeSequenceException e) {
+ throw new DescriptorValidationException(this,
+ "Couldn't parse default value: " + e.getMessage(), e);
+ }
+ break;
+ case ENUM:
+ defaultValue = enumType.findValueByName(proto.getDefaultValue());
+ if (defaultValue == null) {
+ throw new DescriptorValidationException(this,
+ "Unknown enum default value: \"" +
+ proto.getDefaultValue() + '\"');
+ }
+ break;
+ case MESSAGE:
+ case GROUP:
+ throw new DescriptorValidationException(this,
+ "Message type had default value.");
+ }
+ } catch (NumberFormatException e) {
+ throw new DescriptorValidationException(this,
+ "Could not parse default value: \"" +
+ proto.getDefaultValue() + '\"', e);
+ }
+ } else {
+ // Determine the default default for this field.
+ if (isRepeated()) {
+ defaultValue = Collections.emptyList();
+ } else {
+ switch (getJavaType()) {
+ case ENUM:
+ // We guarantee elsewhere that an enum type always has at least
+ // one possible value.
+ defaultValue = enumType.getValues().get(0);
+ break;
+ case MESSAGE:
+ defaultValue = null;
+ break;
+ default:
+ defaultValue = getJavaType().defaultDefault;
+ break;
+ }
+ }
+ }
+
+ if (!isExtension()) {
+ file.pool.addFieldByNumber(this);
+ }
+
+ if (containingType != null &&
+ containingType.getOptions().getMessageSetWireFormat()) {
+ if (isExtension()) {
+ if (!isOptional() || getType() != Type.MESSAGE) {
+ throw new DescriptorValidationException(this,
+ "Extensions of MessageSets must be optional messages.");
+ }
+ } else {
+ throw new DescriptorValidationException(this,
+ "MessageSets cannot have fields, only extensions.");
+ }
+ }
+ }
+
+ /** See {@link FileDescriptor#setProto}. */
+ private void setProto(final FieldDescriptorProto proto) {
+ this.proto = proto;
+ }
+
+ /**
+ * For internal use only. This is to satisfy the FieldDescriptorLite
+ * interface.
+ */
+ public MessageLite.Builder internalMergeFrom(
+ MessageLite.Builder to, MessageLite from) {
+ // FieldDescriptors are only used with non-lite messages so we can just
+ // down-cast and call mergeFrom directly.
+ return ((Message.Builder) to).mergeFrom((Message) from);
+ }
+ }
+
+ // =================================================================
+
+ /** Describes an enum type. */
+ public static final class EnumDescriptor
+ implements GenericDescriptor, Internal.EnumLiteMap<EnumValueDescriptor> {
+ /**
+ * Get the index of this descriptor within its parent.
+ * @see Descriptor#getIndex()
+ */
+ public int getIndex() { return index; }
+
+ /** Convert the descriptor to its protocol message representation. */
+ public EnumDescriptorProto toProto() { return proto; }
+
+ /** Get the type's unqualified name. */
+ public String getName() { return proto.getName(); }
+
+ /**
+ * Get the type's fully-qualified name.
+ * @see Descriptor#getFullName()
+ */
+ public String getFullName() { return fullName; }
+
+ /** Get the {@link FileDescriptor} containing this descriptor. */
+ public FileDescriptor getFile() { return file; }
+
+ /** If this is a nested type, get the outer descriptor, otherwise null. */
+ public Descriptor getContainingType() { return containingType; }
+
+ /** Get the {@code EnumOptions}, defined in {@code descriptor.proto}. */
+ public EnumOptions getOptions() { return proto.getOptions(); }
+
+ /** Get a list of defined values for this enum. */
+ public List<EnumValueDescriptor> getValues() {
+ return Collections.unmodifiableList(Arrays.asList(values));
+ }
+
+ /**
+ * Find an enum value by name.
+ * @param name The unqualified name of the value (e.g. "FOO").
+ * @return the value's decsriptor, or {@code null} if not found.
+ */
+ public EnumValueDescriptor findValueByName(final String name) {
+ final GenericDescriptor result =
+ file.pool.findSymbol(fullName + '.' + name);
+ if (result != null && result instanceof EnumValueDescriptor) {
+ return (EnumValueDescriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Find an enum value by number. If multiple enum values have the same
+ * number, this returns the first defined value with that number.
+ * @param number The value's number.
+ * @return the value's decsriptor, or {@code null} if not found.
+ */
+ public EnumValueDescriptor findValueByNumber(final int number) {
+ return file.pool.enumValuesByNumber.get(
+ new DescriptorPool.DescriptorIntPair(this, number));
+ }
+
+ private final int index;
+ private EnumDescriptorProto proto;
+ private final String fullName;
+ private final FileDescriptor file;
+ private final Descriptor containingType;
+ private EnumValueDescriptor[] values;
+
+ private EnumDescriptor(final EnumDescriptorProto proto,
+ final FileDescriptor file,
+ final Descriptor parent,
+ final int index)
+ throws DescriptorValidationException {
+ this.index = index;
+ this.proto = proto;
+ fullName = computeFullName(file, parent, proto.getName());
+ this.file = file;
+ containingType = parent;
+
+ if (proto.getValueCount() == 0) {
+ // We cannot allow enums with no values because this would mean there
+ // would be no valid default value for fields of this type.
+ throw new DescriptorValidationException(this,
+ "Enums must contain at least one value.");
+ }
+
+ values = new EnumValueDescriptor[proto.getValueCount()];
+ for (int i = 0; i < proto.getValueCount(); i++) {
+ values[i] = new EnumValueDescriptor(
+ proto.getValue(i), file, this, i);
+ }
+
+ file.pool.addSymbol(this);
+ }
+
+ /** See {@link FileDescriptor#setProto}. */
+ private void setProto(final EnumDescriptorProto proto) {
+ this.proto = proto;
+
+ for (int i = 0; i < values.length; i++) {
+ values[i].setProto(proto.getValue(i));
+ }
+ }
+ }
+
+ // =================================================================
+
+ /**
+ * Describes one value within an enum type. Note that multiple defined
+ * values may have the same number. In generated Java code, all values
+ * with the same number after the first become aliases of the first.
+ * However, they still have independent EnumValueDescriptors.
+ */
+ public static final class EnumValueDescriptor
+ implements GenericDescriptor, Internal.EnumLite {
+ /**
+ * Get the index of this descriptor within its parent.
+ * @see Descriptor#getIndex()
+ */
+ public int getIndex() { return index; }
+
+ /** Convert the descriptor to its protocol message representation. */
+ public EnumValueDescriptorProto toProto() { return proto; }
+
+ /** Get the value's unqualified name. */
+ public String getName() { return proto.getName(); }
+
+ /** Get the value's number. */
+ public int getNumber() { return proto.getNumber(); }
+
+ /**
+ * Get the value's fully-qualified name.
+ * @see Descriptor#getFullName()
+ */
+ public String getFullName() { return fullName; }
+
+ /** Get the {@link FileDescriptor} containing this descriptor. */
+ public FileDescriptor getFile() { return file; }
+
+ /** Get the value's enum type. */
+ public EnumDescriptor getType() { return type; }
+
+ /**
+ * Get the {@code EnumValueOptions}, defined in {@code descriptor.proto}.
+ */
+ public EnumValueOptions getOptions() { return proto.getOptions(); }
+
+ private final int index;
+ private EnumValueDescriptorProto proto;
+ private final String fullName;
+ private final FileDescriptor file;
+ private final EnumDescriptor type;
+
+ private EnumValueDescriptor(final EnumValueDescriptorProto proto,
+ final FileDescriptor file,
+ final EnumDescriptor parent,
+ final int index)
+ throws DescriptorValidationException {
+ this.index = index;
+ this.proto = proto;
+ this.file = file;
+ type = parent;
+
+ fullName = parent.getFullName() + '.' + proto.getName();
+
+ file.pool.addSymbol(this);
+ file.pool.addEnumValueByNumber(this);
+ }
+
+ /** See {@link FileDescriptor#setProto}. */
+ private void setProto(final EnumValueDescriptorProto proto) {
+ this.proto = proto;
+ }
+ }
+
+ // =================================================================
+
+ /** Describes a service type. */
+ public static final class ServiceDescriptor implements GenericDescriptor {
+ /**
+ * Get the index of this descriptor within its parent.
+ * * @see Descriptors.Descriptor#getIndex()
+ */
+ public int getIndex() { return index; }
+
+ /** Convert the descriptor to its protocol message representation. */
+ public ServiceDescriptorProto toProto() { return proto; }
+
+ /** Get the type's unqualified name. */
+ public String getName() { return proto.getName(); }
+
+ /**
+ * Get the type's fully-qualified name.
+ * @see Descriptor#getFullName()
+ */
+ public String getFullName() { return fullName; }
+
+ /** Get the {@link FileDescriptor} containing this descriptor. */
+ public FileDescriptor getFile() { return file; }
+
+ /** Get the {@code ServiceOptions}, defined in {@code descriptor.proto}. */
+ public ServiceOptions getOptions() { return proto.getOptions(); }
+
+ /** Get a list of methods for this service. */
+ public List<MethodDescriptor> getMethods() {
+ return Collections.unmodifiableList(Arrays.asList(methods));
+ }
+
+ /**
+ * Find a method by name.
+ * @param name The unqualified name of the method (e.g. "Foo").
+ * @return the method's decsriptor, or {@code null} if not found.
+ */
+ public MethodDescriptor findMethodByName(final String name) {
+ final GenericDescriptor result =
+ file.pool.findSymbol(fullName + '.' + name);
+ if (result != null && result instanceof MethodDescriptor) {
+ return (MethodDescriptor)result;
+ } else {
+ return null;
+ }
+ }
+
+ private final int index;
+ private ServiceDescriptorProto proto;
+ private final String fullName;
+ private final FileDescriptor file;
+ private MethodDescriptor[] methods;
+
+ private ServiceDescriptor(final ServiceDescriptorProto proto,
+ final FileDescriptor file,
+ final int index)
+ throws DescriptorValidationException {
+ this.index = index;
+ this.proto = proto;
+ fullName = computeFullName(file, null, proto.getName());
+ this.file = file;
+
+ methods = new MethodDescriptor[proto.getMethodCount()];
+ for (int i = 0; i < proto.getMethodCount(); i++) {
+ methods[i] = new MethodDescriptor(
+ proto.getMethod(i), file, this, i);
+ }
+
+ file.pool.addSymbol(this);
+ }
+
+ private void crossLink() throws DescriptorValidationException {
+ for (final MethodDescriptor method : methods) {
+ method.crossLink();
+ }
+ }
+
+ /** See {@link FileDescriptor#setProto}. */
+ private void setProto(final ServiceDescriptorProto proto) {
+ this.proto = proto;
+
+ for (int i = 0; i < methods.length; i++) {
+ methods[i].setProto(proto.getMethod(i));
+ }
+ }
+ }
+
+ // =================================================================
+
+ /**
+ * Describes one method within a service type.
+ */
+ public static final class MethodDescriptor implements GenericDescriptor {
+ /**
+ * Get the index of this descriptor within its parent.
+ * * @see Descriptors.Descriptor#getIndex()
+ */
+ public int getIndex() { return index; }
+
+ /** Convert the descriptor to its protocol message representation. */
+ public MethodDescriptorProto toProto() { return proto; }
+
+ /** Get the method's unqualified name. */
+ public String getName() { return proto.getName(); }
+
+ /**
+ * Get the method's fully-qualified name.
+ * @see Descriptor#getFullName()
+ */
+ public String getFullName() { return fullName; }
+
+ /** Get the {@link FileDescriptor} containing this descriptor. */
+ public FileDescriptor getFile() { return file; }
+
+ /** Get the method's service type. */
+ public ServiceDescriptor getService() { return service; }
+
+ /** Get the method's input type. */
+ public Descriptor getInputType() { return inputType; }
+
+ /** Get the method's output type. */
+ public Descriptor getOutputType() { return outputType; }
+
+ /**
+ * Get the {@code MethodOptions}, defined in {@code descriptor.proto}.
+ */
+ public MethodOptions getOptions() { return proto.getOptions(); }
+
+ private final int index;
+ private MethodDescriptorProto proto;
+ private final String fullName;
+ private final FileDescriptor file;
+ private final ServiceDescriptor service;
+
+ // Initialized during cross-linking.
+ private Descriptor inputType;
+ private Descriptor outputType;
+
+ private MethodDescriptor(final MethodDescriptorProto proto,
+ final FileDescriptor file,
+ final ServiceDescriptor parent,
+ final int index)
+ throws DescriptorValidationException {
+ this.index = index;
+ this.proto = proto;
+ this.file = file;
+ service = parent;
+
+ fullName = parent.getFullName() + '.' + proto.getName();
+
+ file.pool.addSymbol(this);
+ }
+
+ private void crossLink() throws DescriptorValidationException {
+ final GenericDescriptor input =
+ file.pool.lookupSymbol(proto.getInputType(), this);
+ if (!(input instanceof Descriptor)) {
+ throw new DescriptorValidationException(this,
+ '\"' + proto.getInputType() + "\" is not a message type.");
+ }
+ inputType = (Descriptor)input;
+
+ final GenericDescriptor output =
+ file.pool.lookupSymbol(proto.getOutputType(), this);
+ if (!(output instanceof Descriptor)) {
+ throw new DescriptorValidationException(this,
+ '\"' + proto.getOutputType() + "\" is not a message type.");
+ }
+ outputType = (Descriptor)output;
+ }
+
+ /** See {@link FileDescriptor#setProto}. */
+ private void setProto(final MethodDescriptorProto proto) {
+ this.proto = proto;
+ }
+ }
+
+ // =================================================================
+
+ private static String computeFullName(final FileDescriptor file,
+ final Descriptor parent,
+ final String name) {
+ if (parent != null) {
+ return parent.getFullName() + '.' + name;
+ } else if (file.getPackage().length() > 0) {
+ return file.getPackage() + '.' + name;
+ } else {
+ return name;
+ }
+ }
+
+ // =================================================================
+
+ /**
+ * All descriptors except {@code FileDescriptor} implement this to make
+ * {@code DescriptorPool}'s life easier.
+ */
+ private interface GenericDescriptor {
+ Message toProto();
+ String getName();
+ String getFullName();
+ FileDescriptor getFile();
+ }
+
+ /**
+ * Thrown when building descriptors fails because the source DescriptorProtos
+ * are not valid.
+ */
+ public static class DescriptorValidationException extends Exception {
+ private static final long serialVersionUID = 5750205775490483148L;
+
+ /** Gets the full name of the descriptor where the error occurred. */
+ public String getProblemSymbolName() { return name; }
+
+ /**
+ * Gets the the protocol message representation of the invalid descriptor.
+ */
+ public Message getProblemProto() { return proto; }
+
+ /**
+ * Gets a human-readable description of the error.
+ */
+ public String getDescription() { return description; }
+
+ private final String name;
+ private final Message proto;
+ private final String description;
+
+ private DescriptorValidationException(
+ final GenericDescriptor problemDescriptor,
+ final String description) {
+ super(problemDescriptor.getFullName() + ": " + description);
+
+ // Note that problemDescriptor may be partially uninitialized, so we
+ // don't want to expose it directly to the user. So, we only provide
+ // the name and the original proto.
+ name = problemDescriptor.getFullName();
+ proto = problemDescriptor.toProto();
+ this.description = description;
+ }
+
+ private DescriptorValidationException(
+ final GenericDescriptor problemDescriptor,
+ final String description,
+ final Throwable cause) {
+ this(problemDescriptor, description);
+ initCause(cause);
+ }
+
+ private DescriptorValidationException(
+ final FileDescriptor problemDescriptor,
+ final String description) {
+ super(problemDescriptor.getName() + ": " + description);
+
+ // Note that problemDescriptor may be partially uninitialized, so we
+ // don't want to expose it directly to the user. So, we only provide
+ // the name and the original proto.
+ name = problemDescriptor.getName();
+ proto = problemDescriptor.toProto();
+ this.description = description;
+ }
+ }
+
+ // =================================================================
+
+ /**
+ * A private helper class which contains lookup tables containing all the
+ * descriptors defined in a particular file.
+ */
+ private static final class DescriptorPool {
+ DescriptorPool(final FileDescriptor[] dependencies) {
+ this.dependencies = new DescriptorPool[dependencies.length];
+
+ for (int i = 0; i < dependencies.length; i++) {
+ this.dependencies[i] = dependencies[i].pool;
+ }
+
+ for (final FileDescriptor dependency : dependencies) {
+ try {
+ addPackage(dependency.getPackage(), dependency);
+ } catch (DescriptorValidationException e) {
+ // Can't happen, because addPackage() only fails when the name
+ // conflicts with a non-package, but we have not yet added any
+ // non-packages at this point.
+ assert false;
+ }
+ }
+ }
+
+ private final DescriptorPool[] dependencies;
+
+ private final Map<String, GenericDescriptor> descriptorsByName =
+ new HashMap<String, GenericDescriptor>();
+ private final Map<DescriptorIntPair, FieldDescriptor> fieldsByNumber =
+ new HashMap<DescriptorIntPair, FieldDescriptor>();
+ private final Map<DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber
+ = new HashMap<DescriptorIntPair, EnumValueDescriptor>();
+
+ /** Find a generic descriptor by fully-qualified name. */
+ GenericDescriptor findSymbol(final String fullName) {
+ GenericDescriptor result = descriptorsByName.get(fullName);
+ if (result != null) {
+ return result;
+ }
+
+ for (final DescriptorPool dependency : dependencies) {
+ result = dependency.descriptorsByName.get(fullName);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Look up a descriptor by name, relative to some other descriptor.
+ * The name may be fully-qualified (with a leading '.'),
+ * partially-qualified, or unqualified. C++-like name lookup semantics
+ * are used to search for the matching descriptor.
+ */
+ GenericDescriptor lookupSymbol(final String name,
+ final GenericDescriptor relativeTo)
+ throws DescriptorValidationException {
+ // TODO(kenton): This could be optimized in a number of ways.
+
+ GenericDescriptor result;
+ if (name.startsWith(".")) {
+ // Fully-qualified name.
+ result = findSymbol(name.substring(1));
+ } else {
+ // If "name" is a compound identifier, we want to search for the
+ // first component of it, then search within it for the rest.
+ final int firstPartLength = name.indexOf('.');
+ final String firstPart;
+ if (firstPartLength == -1) {
+ firstPart = name;
+ } else {
+ firstPart = name.substring(0, firstPartLength);
+ }
+
+ // We will search each parent scope of "relativeTo" looking for the
+ // symbol.
+ final StringBuilder scopeToTry =
+ new StringBuilder(relativeTo.getFullName());
+
+ while (true) {
+ // Chop off the last component of the scope.
+ final int dotpos = scopeToTry.lastIndexOf(".");
+ if (dotpos == -1) {
+ result = findSymbol(name);
+ break;
+ } else {
+ scopeToTry.setLength(dotpos + 1);
+
+ // Append firstPart and try to find.
+ scopeToTry.append(firstPart);
+ result = findSymbol(scopeToTry.toString());
+
+ if (result != null) {
+ if (firstPartLength != -1) {
+ // We only found the first part of the symbol. Now look for
+ // the whole thing. If this fails, we *don't* want to keep
+ // searching parent scopes.
+ scopeToTry.setLength(dotpos + 1);
+ scopeToTry.append(name);
+ result = findSymbol(scopeToTry.toString());
+ }
+ break;
+ }
+
+ // Not found. Remove the name so we can try again.
+ scopeToTry.setLength(dotpos);
+ }
+ }
+ }
+
+ if (result == null) {
+ throw new DescriptorValidationException(relativeTo,
+ '\"' + name + "\" is not defined.");
+ } else {
+ return result;
+ }
+ }
+
+ /**
+ * Adds a symbol to the symbol table. If a symbol with the same name
+ * already exists, throws an error.
+ */
+ void addSymbol(final GenericDescriptor descriptor)
+ throws DescriptorValidationException {
+ validateSymbolName(descriptor);
+
+ final String fullName = descriptor.getFullName();
+ final int dotpos = fullName.lastIndexOf('.');
+
+ final GenericDescriptor old = descriptorsByName.put(fullName, descriptor);
+ if (old != null) {
+ descriptorsByName.put(fullName, old);
+
+ if (descriptor.getFile() == old.getFile()) {
+ if (dotpos == -1) {
+ throw new DescriptorValidationException(descriptor,
+ '\"' + fullName + "\" is already defined.");
+ } else {
+ throw new DescriptorValidationException(descriptor,
+ '\"' + fullName.substring(dotpos + 1) +
+ "\" is already defined in \"" +
+ fullName.substring(0, dotpos) + "\".");
+ }
+ } else {
+ throw new DescriptorValidationException(descriptor,
+ '\"' + fullName + "\" is already defined in file \"" +
+ old.getFile().getName() + "\".");
+ }
+ }
+ }
+
+ /**
+ * Represents a package in the symbol table. We use PackageDescriptors
+ * just as placeholders so that someone cannot define, say, a message type
+ * that has the same name as an existing package.
+ */
+ private static final class PackageDescriptor implements GenericDescriptor {
+ public Message toProto() { return file.toProto(); }
+ public String getName() { return name; }
+ public String getFullName() { return fullName; }
+ public FileDescriptor getFile() { return file; }
+
+ PackageDescriptor(final String name, final String fullName,
+ final FileDescriptor file) {
+ this.file = file;
+ this.fullName = fullName;
+ this.name = name;
+ }
+
+ private final String name;
+ private final String fullName;
+ private final FileDescriptor file;
+ }
+
+ /**
+ * Adds a package to the symbol tables. If a package by the same name
+ * already exists, that is fine, but if some other kind of symbol exists
+ * under the same name, an exception is thrown. If the package has
+ * multiple components, this also adds the parent package(s).
+ */
+ void addPackage(final String fullName, final FileDescriptor file)
+ throws DescriptorValidationException {
+ final int dotpos = fullName.lastIndexOf('.');
+ final String name;
+ if (dotpos == -1) {
+ name = fullName;
+ } else {
+ addPackage(fullName.substring(0, dotpos), file);
+ name = fullName.substring(dotpos + 1);
+ }
+
+ final GenericDescriptor old =
+ descriptorsByName.put(fullName,
+ new PackageDescriptor(name, fullName, file));
+ if (old != null) {
+ descriptorsByName.put(fullName, old);
+ if (!(old instanceof PackageDescriptor)) {
+ throw new DescriptorValidationException(file,
+ '\"' + name + "\" is already defined (as something other than a "
+ + "package) in file \"" + old.getFile().getName() + "\".");
+ }
+ }
+ }
+
+ /** A (GenericDescriptor, int) pair, used as a map key. */
+ private static final class DescriptorIntPair {
+ private final GenericDescriptor descriptor;
+ private final int number;
+
+ DescriptorIntPair(final GenericDescriptor descriptor, final int number) {
+ this.descriptor = descriptor;
+ this.number = number;
+ }
+
+ @Override
+ public int hashCode() {
+ return descriptor.hashCode() * ((1 << 16) - 1) + number;
+ }
+ @Override
+ public boolean equals(final Object obj) {
+ if (!(obj instanceof DescriptorIntPair)) {
+ return false;
+ }
+ final DescriptorIntPair other = (DescriptorIntPair)obj;
+ return descriptor == other.descriptor && number == other.number;
+ }
+ }
+
+ /**
+ * Adds a field to the fieldsByNumber table. Throws an exception if a
+ * field with hte same containing type and number already exists.
+ */
+ void addFieldByNumber(final FieldDescriptor field)
+ throws DescriptorValidationException {
+ final DescriptorIntPair key =
+ new DescriptorIntPair(field.getContainingType(), field.getNumber());
+ final FieldDescriptor old = fieldsByNumber.put(key, field);
+ if (old != null) {
+ fieldsByNumber.put(key, old);
+ throw new DescriptorValidationException(field,
+ "Field number " + field.getNumber() +
+ "has already been used in \"" +
+ field.getContainingType().getFullName() +
+ "\" by field \"" + old.getName() + "\".");
+ }
+ }
+
+ /**
+ * Adds an enum value to the enumValuesByNumber table. If an enum value
+ * with the same type and number already exists, does nothing. (This is
+ * allowed; the first value define with the number takes precedence.)
+ */
+ void addEnumValueByNumber(final EnumValueDescriptor value) {
+ final DescriptorIntPair key =
+ new DescriptorIntPair(value.getType(), value.getNumber());
+ final EnumValueDescriptor old = enumValuesByNumber.put(key, value);
+ if (old != null) {
+ enumValuesByNumber.put(key, old);
+ // Not an error: Multiple enum values may have the same number, but
+ // we only want the first one in the map.
+ }
+ }
+
+ /**
+ * Verifies that the descriptor's name is valid (i.e. it contains only
+ * letters, digits, and underscores, and does not start with a digit).
+ */
+ static void validateSymbolName(final GenericDescriptor descriptor)
+ throws DescriptorValidationException {
+ final String name = descriptor.getName();
+ if (name.length() == 0) {
+ throw new DescriptorValidationException(descriptor, "Missing name.");
+ } else {
+ boolean valid = true;
+ for (int i = 0; i < name.length(); i++) {
+ final char c = name.charAt(i);
+ // Non-ASCII characters are not valid in protobuf identifiers, even
+ // if they are letters or digits.
+ if (c >= 128) {
+ valid = false;
+ }
+ // First character must be letter or _. Subsequent characters may
+ // be letters, numbers, or digits.
+ if (Character.isLetter(c) || c == '_' ||
+ (Character.isDigit(c) && i > 0)) {
+ // Valid
+ } else {
+ valid = false;
+ }
+ }
+ if (!valid) {
+ throw new DescriptorValidationException(descriptor,
+ '\"' + name + "\" is not a valid identifier.");
+ }
+ }
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/DynamicMessage.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/DynamicMessage.java
new file mode 100644
index 0000000..c106b66
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -0,0 +1,438 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * An implementation of {@link Message} that can represent arbitrary types,
+ * given a {@link Descriptors.Descriptor}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class DynamicMessage extends AbstractMessage {
+ private final Descriptor type;
+ private final FieldSet<FieldDescriptor> fields;
+ private final UnknownFieldSet unknownFields;
+ private int memoizedSize = -1;
+
+ /**
+ * Construct a {@code DynamicMessage} using the given {@code FieldSet}.
+ */
+ private DynamicMessage(Descriptor type, FieldSet<FieldDescriptor> fields,
+ UnknownFieldSet unknownFields) {
+ this.type = type;
+ this.fields = fields;
+ this.unknownFields = unknownFields;
+ }
+
+ /**
+ * Get a {@code DynamicMessage} representing the default instance of the
+ * given type.
+ */
+ public static DynamicMessage getDefaultInstance(Descriptor type) {
+ return new DynamicMessage(type, FieldSet.<FieldDescriptor>emptySet(),
+ UnknownFieldSet.getDefaultInstance());
+ }
+
+ /** Parse a message of the given type from the given input stream. */
+ public static DynamicMessage parseFrom(Descriptor type,
+ CodedInputStream input)
+ throws IOException {
+ return newBuilder(type).mergeFrom(input).buildParsed();
+ }
+
+ /** Parse a message of the given type from the given input stream. */
+ public static DynamicMessage parseFrom(
+ Descriptor type,
+ CodedInputStream input,
+ ExtensionRegistry extensionRegistry)
+ throws IOException {
+ return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
+ }
+
+ /** Parse {@code data} as a message of the given type and return it. */
+ public static DynamicMessage parseFrom(Descriptor type, ByteString data)
+ throws InvalidProtocolBufferException {
+ return newBuilder(type).mergeFrom(data).buildParsed();
+ }
+
+ /** Parse {@code data} as a message of the given type and return it. */
+ public static DynamicMessage parseFrom(Descriptor type, ByteString data,
+ ExtensionRegistry extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed();
+ }
+
+ /** Parse {@code data} as a message of the given type and return it. */
+ public static DynamicMessage parseFrom(Descriptor type, byte[] data)
+ throws InvalidProtocolBufferException {
+ return newBuilder(type).mergeFrom(data).buildParsed();
+ }
+
+ /** Parse {@code data} as a message of the given type and return it. */
+ public static DynamicMessage parseFrom(Descriptor type, byte[] data,
+ ExtensionRegistry extensionRegistry)
+ throws InvalidProtocolBufferException {
+ return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed();
+ }
+
+ /** Parse a message of the given type from {@code input} and return it. */
+ public static DynamicMessage parseFrom(Descriptor type, InputStream input)
+ throws IOException {
+ return newBuilder(type).mergeFrom(input).buildParsed();
+ }
+
+ /** Parse a message of the given type from {@code input} and return it. */
+ public static DynamicMessage parseFrom(Descriptor type, InputStream input,
+ ExtensionRegistry extensionRegistry)
+ throws IOException {
+ return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
+ }
+
+ /** Construct a {@link Message.Builder} for the given type. */
+ public static Builder newBuilder(Descriptor type) {
+ return new Builder(type);
+ }
+
+ /**
+ * Construct a {@link Message.Builder} for a message of the same type as
+ * {@code prototype}, and initialize it with {@code prototype}'s contents.
+ */
+ public static Builder newBuilder(Message prototype) {
+ return new Builder(prototype.getDescriptorForType()).mergeFrom(prototype);
+ }
+
+ // -----------------------------------------------------------------
+ // Implementation of Message interface.
+
+ public Descriptor getDescriptorForType() {
+ return type;
+ }
+
+ public DynamicMessage getDefaultInstanceForType() {
+ return getDefaultInstance(type);
+ }
+
+ public Map<FieldDescriptor, Object> getAllFields() {
+ return fields.getAllFields();
+ }
+
+ public boolean hasField(FieldDescriptor field) {
+ verifyContainingType(field);
+ return fields.hasField(field);
+ }
+
+ public Object getField(FieldDescriptor field) {
+ verifyContainingType(field);
+ Object result = fields.getField(field);
+ if (result == null) {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ result = getDefaultInstance(field.getMessageType());
+ } else {
+ result = field.getDefaultValue();
+ }
+ }
+ return result;
+ }
+
+ public int getRepeatedFieldCount(FieldDescriptor field) {
+ verifyContainingType(field);
+ return fields.getRepeatedFieldCount(field);
+ }
+
+ public Object getRepeatedField(FieldDescriptor field, int index) {
+ verifyContainingType(field);
+ return fields.getRepeatedField(field, index);
+ }
+
+ public UnknownFieldSet getUnknownFields() {
+ return unknownFields;
+ }
+
+ private static boolean isInitialized(Descriptor type,
+ FieldSet<FieldDescriptor> fields) {
+ // Check that all required fields are present.
+ for (final FieldDescriptor field : type.getFields()) {
+ if (field.isRequired()) {
+ if (!fields.hasField(field)) {
+ return false;
+ }
+ }
+ }
+
+ // Check that embedded messages are initialized.
+ return fields.isInitialized();
+ }
+
+ public boolean isInitialized() {
+ return isInitialized(type, fields);
+ }
+
+ public void writeTo(CodedOutputStream output) throws IOException {
+ if (type.getOptions().getMessageSetWireFormat()) {
+ fields.writeMessageSetTo(output);
+ unknownFields.writeAsMessageSetTo(output);
+ } else {
+ fields.writeTo(output);
+ unknownFields.writeTo(output);
+ }
+ }
+
+ public int getSerializedSize() {
+ int size = memoizedSize;
+ if (size != -1) return size;
+
+ if (type.getOptions().getMessageSetWireFormat()) {
+ size = fields.getMessageSetSerializedSize();
+ size += unknownFields.getSerializedSizeAsMessageSet();
+ } else {
+ size = fields.getSerializedSize();
+ size += unknownFields.getSerializedSize();
+ }
+
+ memoizedSize = size;
+ return size;
+ }
+
+ public Builder newBuilderForType() {
+ return new Builder(type);
+ }
+
+ public Builder toBuilder() {
+ return newBuilderForType().mergeFrom(this);
+ }
+
+ /** Verifies that the field is a field of this message. */
+ private void verifyContainingType(FieldDescriptor field) {
+ if (field.getContainingType() != type) {
+ throw new IllegalArgumentException(
+ "FieldDescriptor does not match message type.");
+ }
+ }
+
+ // =================================================================
+
+ /**
+ * Builder for {@link DynamicMessage}s.
+ */
+ public static final class Builder extends AbstractMessage.Builder<Builder> {
+ private final Descriptor type;
+ private FieldSet<FieldDescriptor> fields;
+ private UnknownFieldSet unknownFields;
+
+ /** Construct a {@code Builder} for the given type. */
+ private Builder(Descriptor type) {
+ this.type = type;
+ this.fields = FieldSet.newFieldSet();
+ this.unknownFields = UnknownFieldSet.getDefaultInstance();
+ }
+
+ // ---------------------------------------------------------------
+ // Implementation of Message.Builder interface.
+
+ public Builder clear() {
+ if (fields == null) {
+ throw new IllegalStateException("Cannot call clear() after build().");
+ }
+ fields.clear();
+ return this;
+ }
+
+ public Builder mergeFrom(Message other) {
+ if (other instanceof DynamicMessage) {
+ // This should be somewhat faster than calling super.mergeFrom().
+ DynamicMessage otherDynamicMessage = (DynamicMessage) other;
+ if (otherDynamicMessage.type != type) {
+ throw new IllegalArgumentException(
+ "mergeFrom(Message) can only merge messages of the same type.");
+ }
+ fields.mergeFrom(otherDynamicMessage.fields);
+ mergeUnknownFields(otherDynamicMessage.unknownFields);
+ return this;
+ } else {
+ return super.mergeFrom(other);
+ }
+ }
+
+ public DynamicMessage build() {
+ // If fields == null, we'll throw an appropriate exception later.
+ if (fields != null && !isInitialized()) {
+ throw newUninitializedMessageException(
+ new DynamicMessage(type, fields, unknownFields));
+ }
+ return buildPartial();
+ }
+
+ /**
+ * Helper for DynamicMessage.parseFrom() methods to call. Throws
+ * {@link InvalidProtocolBufferException} instead of
+ * {@link UninitializedMessageException}.
+ */
+ private DynamicMessage buildParsed() throws InvalidProtocolBufferException {
+ if (!isInitialized()) {
+ throw newUninitializedMessageException(
+ new DynamicMessage(type, fields, unknownFields))
+ .asInvalidProtocolBufferException();
+ }
+ return buildPartial();
+ }
+
+ public DynamicMessage buildPartial() {
+ if (fields == null) {
+ throw new IllegalStateException(
+ "build() has already been called on this Builder.");
+ }
+ fields.makeImmutable();
+ DynamicMessage result =
+ new DynamicMessage(type, fields, unknownFields);
+ fields = null;
+ unknownFields = null;
+ return result;
+ }
+
+ public Builder clone() {
+ Builder result = new Builder(type);
+ result.fields.mergeFrom(fields);
+ return result;
+ }
+
+ public boolean isInitialized() {
+ return DynamicMessage.isInitialized(type, fields);
+ }
+
+ public Descriptor getDescriptorForType() {
+ return type;
+ }
+
+ public DynamicMessage getDefaultInstanceForType() {
+ return getDefaultInstance(type);
+ }
+
+ public Map<FieldDescriptor, Object> getAllFields() {
+ return fields.getAllFields();
+ }
+
+ public Builder newBuilderForField(FieldDescriptor field) {
+ verifyContainingType(field);
+
+ if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
+ throw new IllegalArgumentException(
+ "newBuilderForField is only valid for fields with message type.");
+ }
+
+ return new Builder(field.getMessageType());
+ }
+
+ public boolean hasField(FieldDescriptor field) {
+ verifyContainingType(field);
+ return fields.hasField(field);
+ }
+
+ public Object getField(FieldDescriptor field) {
+ verifyContainingType(field);
+ Object result = fields.getField(field);
+ if (result == null) {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ result = getDefaultInstance(field.getMessageType());
+ } else {
+ result = field.getDefaultValue();
+ }
+ }
+ return result;
+ }
+
+ public Builder setField(FieldDescriptor field, Object value) {
+ verifyContainingType(field);
+ fields.setField(field, value);
+ return this;
+ }
+
+ public Builder clearField(FieldDescriptor field) {
+ verifyContainingType(field);
+ fields.clearField(field);
+ return this;
+ }
+
+ public int getRepeatedFieldCount(FieldDescriptor field) {
+ verifyContainingType(field);
+ return fields.getRepeatedFieldCount(field);
+ }
+
+ public Object getRepeatedField(FieldDescriptor field, int index) {
+ verifyContainingType(field);
+ return fields.getRepeatedField(field, index);
+ }
+
+ public Builder setRepeatedField(FieldDescriptor field,
+ int index, Object value) {
+ verifyContainingType(field);
+ fields.setRepeatedField(field, index, value);
+ return this;
+ }
+
+ public Builder addRepeatedField(FieldDescriptor field, Object value) {
+ verifyContainingType(field);
+ fields.addRepeatedField(field, value);
+ return this;
+ }
+
+ public UnknownFieldSet getUnknownFields() {
+ return unknownFields;
+ }
+
+ public Builder setUnknownFields(UnknownFieldSet unknownFields) {
+ this.unknownFields = unknownFields;
+ return this;
+ }
+
+ public Builder mergeUnknownFields(UnknownFieldSet unknownFields) {
+ this.unknownFields =
+ UnknownFieldSet.newBuilder(this.unknownFields)
+ .mergeFrom(unknownFields)
+ .build();
+ return this;
+ }
+
+ /** Verifies that the field is a field of this message. */
+ private void verifyContainingType(FieldDescriptor field) {
+ if (field.getContainingType() != type) {
+ throw new IllegalArgumentException(
+ "FieldDescriptor does not match message type.");
+ }
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistry.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
new file mode 100644
index 0000000..d4f6ba9
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
@@ -0,0 +1,266 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A table of known extensions, searchable by name or field number. When
+ * parsing a protocol message that might have extensions, you must provide
+ * an {@code ExtensionRegistry} in which you have registered any extensions
+ * that you want to be able to parse. Otherwise, those extensions will just
+ * be treated like unknown fields.
+ *
+ * <p>For example, if you had the {@code .proto} file:
+ *
+ * <pre>
+ * option java_class = "MyProto";
+ *
+ * message Foo {
+ * extensions 1000 to max;
+ * }
+ *
+ * extend Foo {
+ * optional int32 bar;
+ * }
+ * </pre>
+ *
+ * Then you might write code like:
+ *
+ * <pre>
+ * ExtensionRegistry registry = ExtensionRegistry.newInstance();
+ * registry.add(MyProto.bar);
+ * MyProto.Foo message = MyProto.Foo.parseFrom(input, registry);
+ * </pre>
+ *
+ * <p>Background:
+ *
+ * <p>You might wonder why this is necessary. Two alternatives might come to
+ * mind. First, you might imagine a system where generated extensions are
+ * automatically registered when their containing classes are loaded. This
+ * is a popular technique, but is bad design; among other things, it creates a
+ * situation where behavior can change depending on what classes happen to be
+ * loaded. It also introduces a security vulnerability, because an
+ * unprivileged class could cause its code to be called unexpectedly from a
+ * privileged class by registering itself as an extension of the right type.
+ *
+ * <p>Another option you might consider is lazy parsing: do not parse an
+ * extension until it is first requested, at which point the caller must
+ * provide a type to use. This introduces a different set of problems. First,
+ * it would require a mutex lock any time an extension was accessed, which
+ * would be slow. Second, corrupt data would not be detected until first
+ * access, at which point it would be much harder to deal with it. Third, it
+ * could violate the expectation that message objects are immutable, since the
+ * type provided could be any arbitrary message class. An unprivileged user
+ * could take advantage of this to inject a mutable object into a message
+ * belonging to privileged code and create mischief.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class ExtensionRegistry extends ExtensionRegistryLite {
+ /** Construct a new, empty instance. */
+ public static ExtensionRegistry newInstance() {
+ return new ExtensionRegistry();
+ }
+
+ /** Get the unmodifiable singleton empty instance. */
+ public static ExtensionRegistry getEmptyRegistry() {
+ return EMPTY;
+ }
+
+ /** Returns an unmodifiable view of the registry. */
+ @Override
+ public ExtensionRegistry getUnmodifiable() {
+ return new ExtensionRegistry(this);
+ }
+
+ /** A (Descriptor, Message) pair, returned by lookup methods. */
+ public static final class ExtensionInfo {
+ /** The extension's descriptor. */
+ public final FieldDescriptor descriptor;
+
+ /**
+ * A default instance of the extension's type, if it has a message type.
+ * Otherwise, {@code null}.
+ */
+ public final Message defaultInstance;
+
+ private ExtensionInfo(final FieldDescriptor descriptor) {
+ this.descriptor = descriptor;
+ defaultInstance = null;
+ }
+ private ExtensionInfo(final FieldDescriptor descriptor,
+ final Message defaultInstance) {
+ this.descriptor = descriptor;
+ this.defaultInstance = defaultInstance;
+ }
+ }
+
+ /**
+ * Find an extension by fully-qualified field name, in the proto namespace.
+ * I.e. {@code result.descriptor.fullName()} will match {@code fullName} if
+ * a match is found.
+ *
+ * @return Information about the extension if found, or {@code null}
+ * otherwise.
+ */
+ public ExtensionInfo findExtensionByName(final String fullName) {
+ return extensionsByName.get(fullName);
+ }
+
+ /**
+ * Find an extension by containing type and field number.
+ *
+ * @return Information about the extension if found, or {@code null}
+ * otherwise.
+ */
+ public ExtensionInfo findExtensionByNumber(final Descriptor containingType,
+ final int fieldNumber) {
+ return extensionsByNumber.get(
+ new DescriptorIntPair(containingType, fieldNumber));
+ }
+
+ /** Add an extension from a generated file to the registry. */
+ public void add(final GeneratedMessage.GeneratedExtension<?, ?> extension) {
+ if (extension.getDescriptor().getJavaType() ==
+ FieldDescriptor.JavaType.MESSAGE) {
+ if (extension.getMessageDefaultInstance() == null) {
+ throw new IllegalStateException(
+ "Registered message-type extension had null default instance: " +
+ extension.getDescriptor().getFullName());
+ }
+ add(new ExtensionInfo(extension.getDescriptor(),
+ extension.getMessageDefaultInstance()));
+ } else {
+ add(new ExtensionInfo(extension.getDescriptor(), null));
+ }
+ }
+
+ /** Add a non-message-type extension to the registry by descriptor. */
+ public void add(final FieldDescriptor type) {
+ if (type.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ throw new IllegalArgumentException(
+ "ExtensionRegistry.add() must be provided a default instance when " +
+ "adding an embedded message extension.");
+ }
+ add(new ExtensionInfo(type, null));
+ }
+
+ /** Add a message-type extension to the registry by descriptor. */
+ public void add(final FieldDescriptor type, final Message defaultInstance) {
+ if (type.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
+ throw new IllegalArgumentException(
+ "ExtensionRegistry.add() provided a default instance for a " +
+ "non-message extension.");
+ }
+ add(new ExtensionInfo(type, defaultInstance));
+ }
+
+ // =================================================================
+ // Private stuff.
+
+ private ExtensionRegistry() {
+ this.extensionsByName = new HashMap<String, ExtensionInfo>();
+ this.extensionsByNumber = new HashMap<DescriptorIntPair, ExtensionInfo>();
+ }
+
+ private ExtensionRegistry(ExtensionRegistry other) {
+ super(other);
+ this.extensionsByName = Collections.unmodifiableMap(other.extensionsByName);
+ this.extensionsByNumber =
+ Collections.unmodifiableMap(other.extensionsByNumber);
+ }
+
+ private final Map<String, ExtensionInfo> extensionsByName;
+ private final Map<DescriptorIntPair, ExtensionInfo> extensionsByNumber;
+
+ private ExtensionRegistry(boolean empty) {
+ super(ExtensionRegistryLite.getEmptyRegistry());
+ this.extensionsByName = Collections.<String, ExtensionInfo>emptyMap();
+ this.extensionsByNumber =
+ Collections.<DescriptorIntPair, ExtensionInfo>emptyMap();
+ }
+ private static final ExtensionRegistry EMPTY = new ExtensionRegistry(true);
+
+ private void add(final ExtensionInfo extension) {
+ if (!extension.descriptor.isExtension()) {
+ throw new IllegalArgumentException(
+ "ExtensionRegistry.add() was given a FieldDescriptor for a regular " +
+ "(non-extension) field.");
+ }
+
+ extensionsByName.put(extension.descriptor.getFullName(), extension);
+ extensionsByNumber.put(
+ new DescriptorIntPair(extension.descriptor.getContainingType(),
+ extension.descriptor.getNumber()),
+ extension);
+
+ final FieldDescriptor field = extension.descriptor;
+ if (field.getContainingType().getOptions().getMessageSetWireFormat() &&
+ field.getType() == FieldDescriptor.Type.MESSAGE &&
+ field.isOptional() &&
+ field.getExtensionScope() == field.getMessageType()) {
+ // This is an extension of a MessageSet type defined within the extension
+ // type's own scope. For backwards-compatibility, allow it to be looked
+ // up by type name.
+ extensionsByName.put(field.getMessageType().getFullName(), extension);
+ }
+ }
+
+ /** A (GenericDescriptor, int) pair, used as a map key. */
+ private static final class DescriptorIntPair {
+ private final Descriptor descriptor;
+ private final int number;
+
+ DescriptorIntPair(final Descriptor descriptor, final int number) {
+ this.descriptor = descriptor;
+ this.number = number;
+ }
+
+ @Override
+ public int hashCode() {
+ return descriptor.hashCode() * ((1 << 16) - 1) + number;
+ }
+ @Override
+ public boolean equals(final Object obj) {
+ if (!(obj instanceof DescriptorIntPair)) {
+ return false;
+ }
+ final DescriptorIntPair other = (DescriptorIntPair)obj;
+ return descriptor == other.descriptor && number == other.number;
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
new file mode 100644
index 0000000..d5288dd
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
@@ -0,0 +1,169 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Equivalent to {@link ExtensionRegistry} but supports only "lite" types.
+ * <p>
+ * If all of your types are lite types, then you only need to use
+ * {@code ExtensionRegistryLite}. Similarly, if all your types are regular
+ * types, then you only need {@link ExtensionRegistry}. Typically it does not
+ * make sense to mix the two, since if you have any regular types in your
+ * program, you then require the full runtime and lose all the benefits of
+ * the lite runtime, so you might as well make all your types be regular types.
+ * However, in some cases (e.g. when depending on multiple third-patry libraries
+ * where one uses lite types and one uses regular), you may find yourself
+ * wanting to mix the two. In this case things get more complicated.
+ * <p>
+ * There are three factors to consider: Whether the type being extended is
+ * lite, whether the embedded type (in the case of a message-typed extension)
+ * is lite, and whether the extension itself is lite. Since all three are
+ * declared in different files, they could all be different. Here are all
+ * the combinations and which type of registry to use:
+ * <pre>
+ * Extended type Inner type Extension Use registry
+ * =======================================================================
+ * lite lite lite ExtensionRegistryLite
+ * lite regular lite ExtensionRegistry
+ * regular regular regular ExtensionRegistry
+ * all other combinations not supported
+ * </pre>
+ * <p>
+ * Note that just as regular types are not allowed to contain lite-type fields,
+ * they are also not allowed to contain lite-type extensions. This is because
+ * regular types must be fully accessible via reflection, which in turn means
+ * that all the inner messages must also support reflection. On the other hand,
+ * since regular types implement the entire lite interface, there is no problem
+ * with embedding regular types inside lite types.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class ExtensionRegistryLite {
+ /** Construct a new, empty instance. */
+ public static ExtensionRegistryLite newInstance() {
+ return new ExtensionRegistryLite();
+ }
+
+ /** Get the unmodifiable singleton empty instance. */
+ public static ExtensionRegistryLite getEmptyRegistry() {
+ return EMPTY;
+ }
+
+ /** Returns an unmodifiable view of the registry. */
+ public ExtensionRegistryLite getUnmodifiable() {
+ return new ExtensionRegistryLite(this);
+ }
+
+ /**
+ * Find an extension by containing type and field number.
+ *
+ * @return Information about the extension if found, or {@code null}
+ * otherwise.
+ */
+ @SuppressWarnings("unchecked")
+ public <ContainingType extends MessageLite>
+ GeneratedMessageLite.GeneratedExtension<ContainingType, ?>
+ findLiteExtensionByNumber(
+ final ContainingType containingTypeDefaultInstance,
+ final int fieldNumber) {
+ return (GeneratedMessageLite.GeneratedExtension<ContainingType, ?>)
+ extensionsByNumber.get(
+ new ObjectIntPair(containingTypeDefaultInstance, fieldNumber));
+ }
+
+ /** Add an extension from a lite generated file to the registry. */
+ public final void add(
+ final GeneratedMessageLite.GeneratedExtension<?, ?> extension) {
+ extensionsByNumber.put(
+ new ObjectIntPair(extension.getContainingTypeDefaultInstance(),
+ extension.getNumber()),
+ extension);
+ }
+
+ // =================================================================
+ // Private stuff.
+
+ // Constructors are package-private so that ExtensionRegistry can subclass
+ // this.
+
+ ExtensionRegistryLite() {
+ this.extensionsByNumber =
+ new HashMap<ObjectIntPair,
+ GeneratedMessageLite.GeneratedExtension<?, ?>>();
+ }
+
+ ExtensionRegistryLite(ExtensionRegistryLite other) {
+ if (other == EMPTY) {
+ this.extensionsByNumber = Collections.emptyMap();
+ } else {
+ this.extensionsByNumber =
+ Collections.unmodifiableMap(other.extensionsByNumber);
+ }
+ }
+
+ private final Map<ObjectIntPair,
+ GeneratedMessageLite.GeneratedExtension<?, ?>>
+ extensionsByNumber;
+
+ private ExtensionRegistryLite(boolean empty) {
+ this.extensionsByNumber = Collections.emptyMap();
+ }
+ private static final ExtensionRegistryLite EMPTY =
+ new ExtensionRegistryLite(true);
+
+ /** A (Object, int) pair, used as a map key. */
+ private static final class ObjectIntPair {
+ private final Object object;
+ private final int number;
+
+ ObjectIntPair(final Object object, final int number) {
+ this.object = object;
+ this.number = number;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(object) * ((1 << 16) - 1) + number;
+ }
+ @Override
+ public boolean equals(final Object obj) {
+ if (!(obj instanceof ObjectIntPair)) {
+ return false;
+ }
+ final ObjectIntPair other = (ObjectIntPair)obj;
+ return object == other.object && number == other.number;
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/FieldSet.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/FieldSet.java
new file mode 100644
index 0000000..a85dbaa
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/FieldSet.java
@@ -0,0 +1,788 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+
+/**
+ * A class which represents an arbitrary set of fields of some message type.
+ * This is used to implement {@link DynamicMessage}, and also to represent
+ * extensions in {@link GeneratedMessage}. This class is package-private,
+ * since outside users should probably be using {@link DynamicMessage}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+final class FieldSet<FieldDescriptorType extends
+ FieldSet.FieldDescriptorLite<FieldDescriptorType>> {
+ /**
+ * Interface for a FieldDescriptor or lite extension descriptor. This
+ * prevents FieldSet from depending on {@link Descriptors.FieldDescriptor}.
+ */
+ public interface FieldDescriptorLite<T extends FieldDescriptorLite<T>>
+ extends Comparable<T> {
+ int getNumber();
+ WireFormat.FieldType getLiteType();
+ WireFormat.JavaType getLiteJavaType();
+ boolean isRepeated();
+ boolean isPacked();
+ Internal.EnumLiteMap<?> getEnumType();
+
+ // If getLiteJavaType() == MESSAGE, this merges a message object of the
+ // type into a builder of the type. Returns {@code to}.
+ MessageLite.Builder internalMergeFrom(
+ MessageLite.Builder to, MessageLite from);
+ }
+
+ private final SmallSortedMap<FieldDescriptorType, Object> fields;
+ private boolean isImmutable;
+
+ /** Construct a new FieldSet. */
+ private FieldSet() {
+ this.fields = SmallSortedMap.newFieldMap(16);
+ }
+
+ /**
+ * Construct an empty FieldSet. This is only used to initialize
+ * DEFAULT_INSTANCE.
+ */
+ private FieldSet(final boolean dummy) {
+ this.fields = SmallSortedMap.newFieldMap(0);
+ makeImmutable();
+ }
+
+ /** Construct a new FieldSet. */
+ public static <T extends FieldSet.FieldDescriptorLite<T>>
+ FieldSet<T> newFieldSet() {
+ return new FieldSet<T>();
+ }
+
+ /** Get an immutable empty FieldSet. */
+ @SuppressWarnings("unchecked")
+ public static <T extends FieldSet.FieldDescriptorLite<T>>
+ FieldSet<T> emptySet() {
+ return DEFAULT_INSTANCE;
+ }
+ @SuppressWarnings("unchecked")
+ private static final FieldSet DEFAULT_INSTANCE = new FieldSet(true);
+
+ /** Make this FieldSet immutable from this point forward. */
+ @SuppressWarnings("unchecked")
+ public void makeImmutable() {
+ if (isImmutable) {
+ return;
+ }
+ fields.makeImmutable();
+ isImmutable = true;
+ }
+
+ /**
+ * Retuns whether the FieldSet is immutable. This is true if it is the
+ * {@link #emptySet} or if {@link #makeImmutable} were called.
+ *
+ * @return whether the FieldSet is immutable.
+ */
+ public boolean isImmutable() {
+ return isImmutable;
+ }
+
+ /**
+ * Clones the FieldSet. The returned FieldSet will be mutable even if the
+ * original FieldSet was immutable.
+ *
+ * @return the newly cloned FieldSet
+ */
+ @Override
+ public FieldSet<FieldDescriptorType> clone() {
+ // We can't just call fields.clone because List objects in the map
+ // should not be shared.
+ FieldSet<FieldDescriptorType> clone = FieldSet.newFieldSet();
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ Map.Entry<FieldDescriptorType, Object> entry = fields.getArrayEntryAt(i);
+ FieldDescriptorType descriptor = entry.getKey();
+ clone.setField(descriptor, entry.getValue());
+ }
+ for (Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ FieldDescriptorType descriptor = entry.getKey();
+ clone.setField(descriptor, entry.getValue());
+ }
+ return clone;
+ }
+
+ // =================================================================
+
+ /** See {@link Message.Builder#clear()}. */
+ public void clear() {
+ fields.clear();
+ }
+
+ /**
+ * Get a simple map containing all the fields.
+ */
+ public Map<FieldDescriptorType, Object> getAllFields() {
+ return fields.isImmutable() ? fields : Collections.unmodifiableMap(fields);
+ }
+
+ /**
+ * Get an iterator to the field map. This iterator should not be leaked out
+ * of the protobuf library as it is not protected from mutation when
+ * fields is not immutable.
+ */
+ public Iterator<Map.Entry<FieldDescriptorType, Object>> iterator() {
+ return fields.entrySet().iterator();
+ }
+
+ /**
+ * Useful for implementing
+ * {@link Message#hasField(Descriptors.FieldDescriptor)}.
+ */
+ public boolean hasField(final FieldDescriptorType descriptor) {
+ if (descriptor.isRepeated()) {
+ throw new IllegalArgumentException(
+ "hasField() can only be called on non-repeated fields.");
+ }
+
+ return fields.get(descriptor) != null;
+ }
+
+ /**
+ * Useful for implementing
+ * {@link Message#getField(Descriptors.FieldDescriptor)}. This method
+ * returns {@code null} if the field is not set; in this case it is up
+ * to the caller to fetch the field's default value.
+ */
+ public Object getField(final FieldDescriptorType descriptor) {
+ return fields.get(descriptor);
+ }
+
+ /**
+ * Useful for implementing
+ * {@link Message.Builder#setField(Descriptors.FieldDescriptor,Object)}.
+ */
+ @SuppressWarnings("unchecked")
+ public void setField(final FieldDescriptorType descriptor,
+ Object value) {
+ if (descriptor.isRepeated()) {
+ if (!(value instanceof List)) {
+ throw new IllegalArgumentException(
+ "Wrong object type used with protocol message reflection.");
+ }
+
+ // Wrap the contents in a new list so that the caller cannot change
+ // the list's contents after setting it.
+ final List newList = new ArrayList();
+ newList.addAll((List)value);
+ for (final Object element : newList) {
+ verifyType(descriptor.getLiteType(), element);
+ }
+ value = newList;
+ } else {
+ verifyType(descriptor.getLiteType(), value);
+ }
+
+ fields.put(descriptor, value);
+ }
+
+ /**
+ * Useful for implementing
+ * {@link Message.Builder#clearField(Descriptors.FieldDescriptor)}.
+ */
+ public void clearField(final FieldDescriptorType descriptor) {
+ fields.remove(descriptor);
+ }
+
+ /**
+ * Useful for implementing
+ * {@link Message#getRepeatedFieldCount(Descriptors.FieldDescriptor)}.
+ */
+ public int getRepeatedFieldCount(final FieldDescriptorType descriptor) {
+ if (!descriptor.isRepeated()) {
+ throw new IllegalArgumentException(
+ "getRepeatedField() can only be called on repeated fields.");
+ }
+
+ final Object value = fields.get(descriptor);
+ if (value == null) {
+ return 0;
+ } else {
+ return ((List<?>) value).size();
+ }
+ }
+
+ /**
+ * Useful for implementing
+ * {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)}.
+ */
+ public Object getRepeatedField(final FieldDescriptorType descriptor,
+ final int index) {
+ if (!descriptor.isRepeated()) {
+ throw new IllegalArgumentException(
+ "getRepeatedField() can only be called on repeated fields.");
+ }
+
+ final Object value = fields.get(descriptor);
+
+ if (value == null) {
+ throw new IndexOutOfBoundsException();
+ } else {
+ return ((List<?>) value).get(index);
+ }
+ }
+
+ /**
+ * Useful for implementing
+ * {@link Message.Builder#setRepeatedField(Descriptors.FieldDescriptor,int,Object)}.
+ */
+ @SuppressWarnings("unchecked")
+ public void setRepeatedField(final FieldDescriptorType descriptor,
+ final int index,
+ final Object value) {
+ if (!descriptor.isRepeated()) {
+ throw new IllegalArgumentException(
+ "getRepeatedField() can only be called on repeated fields.");
+ }
+
+ final Object list = fields.get(descriptor);
+ if (list == null) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ verifyType(descriptor.getLiteType(), value);
+ ((List) list).set(index, value);
+ }
+
+ /**
+ * Useful for implementing
+ * {@link Message.Builder#addRepeatedField(Descriptors.FieldDescriptor,Object)}.
+ */
+ @SuppressWarnings("unchecked")
+ public void addRepeatedField(final FieldDescriptorType descriptor,
+ final Object value) {
+ if (!descriptor.isRepeated()) {
+ throw new IllegalArgumentException(
+ "addRepeatedField() can only be called on repeated fields.");
+ }
+
+ verifyType(descriptor.getLiteType(), value);
+
+ final Object existingValue = fields.get(descriptor);
+ List list;
+ if (existingValue == null) {
+ list = new ArrayList();
+ fields.put(descriptor, list);
+ } else {
+ list = (List) existingValue;
+ }
+
+ list.add(value);
+ }
+
+ /**
+ * Verifies that the given object is of the correct type to be a valid
+ * value for the given field. (For repeated fields, this checks if the
+ * object is the right type to be one element of the field.)
+ *
+ * @throws IllegalArgumentException The value is not of the right type.
+ */
+ private static void verifyType(final WireFormat.FieldType type,
+ final Object value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ boolean isValid = false;
+ switch (type.getJavaType()) {
+ case INT: isValid = value instanceof Integer ; break;
+ case LONG: isValid = value instanceof Long ; break;
+ case FLOAT: isValid = value instanceof Float ; break;
+ case DOUBLE: isValid = value instanceof Double ; break;
+ case BOOLEAN: isValid = value instanceof Boolean ; break;
+ case STRING: isValid = value instanceof String ; break;
+ case BYTE_STRING: isValid = value instanceof ByteString; break;
+ case ENUM:
+ // TODO(kenton): Caller must do type checking here, I guess.
+ isValid = value instanceof Internal.EnumLite;
+ break;
+ case MESSAGE:
+ // TODO(kenton): Caller must do type checking here, I guess.
+ isValid = value instanceof MessageLite;
+ break;
+ }
+
+ if (!isValid) {
+ // TODO(kenton): When chaining calls to setField(), it can be hard to
+ // tell from the stack trace which exact call failed, since the whole
+ // chain is considered one line of code. It would be nice to print
+ // more information here, e.g. naming the field. We used to do that.
+ // But we can't now that FieldSet doesn't use descriptors. Maybe this
+ // isn't a big deal, though, since it would only really apply when using
+ // reflection and generally people don't chain reflection setters.
+ throw new IllegalArgumentException(
+ "Wrong object type used with protocol message reflection.");
+ }
+ }
+
+ // =================================================================
+ // Parsing and serialization
+
+ /**
+ * See {@link Message#isInitialized()}. Note: Since {@code FieldSet}
+ * itself does not have any way of knowing about required fields that
+ * aren't actually present in the set, it is up to the caller to check
+ * that all required fields are present.
+ */
+ public boolean isInitialized() {
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ if (!isInitialized(fields.getArrayEntryAt(i))) {
+ return false;
+ }
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ if (!isInitialized(entry)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ private boolean isInitialized(
+ final Map.Entry<FieldDescriptorType, Object> entry) {
+ final FieldDescriptorType descriptor = entry.getKey();
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
+ if (descriptor.isRepeated()) {
+ for (final MessageLite element:
+ (List<MessageLite>) entry.getValue()) {
+ if (!element.isInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (!((MessageLite) entry.getValue()).isInitialized()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Given a field type, return the wire type.
+ *
+ * @returns One of the {@code WIRETYPE_} constants defined in
+ * {@link WireFormat}.
+ */
+ static int getWireFormatForFieldType(final WireFormat.FieldType type,
+ boolean isPacked) {
+ if (isPacked) {
+ return WireFormat.WIRETYPE_LENGTH_DELIMITED;
+ } else {
+ return type.getWireType();
+ }
+ }
+
+ /**
+ * Like {@link #mergeFrom(Message)}, but merges from another {@link FieldSet}.
+ */
+ public void mergeFrom(final FieldSet<FieldDescriptorType> other) {
+ for (int i = 0; i < other.fields.getNumArrayEntries(); i++) {
+ mergeFromField(other.fields.getArrayEntryAt(i));
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ other.fields.getOverflowEntries()) {
+ mergeFromField(entry);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void mergeFromField(
+ final Map.Entry<FieldDescriptorType, Object> entry) {
+ final FieldDescriptorType descriptor = entry.getKey();
+ final Object otherValue = entry.getValue();
+
+ if (descriptor.isRepeated()) {
+ Object value = fields.get(descriptor);
+ if (value == null) {
+ // Our list is empty, but we still need to make a defensive copy of
+ // the other list since we don't know if the other FieldSet is still
+ // mutable.
+ fields.put(descriptor, new ArrayList((List) otherValue));
+ } else {
+ // Concatenate the lists.
+ ((List) value).addAll((List) otherValue);
+ }
+ } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
+ Object value = fields.get(descriptor);
+ if (value == null) {
+ fields.put(descriptor, otherValue);
+ } else {
+ // Merge the messages.
+ fields.put(
+ descriptor,
+ descriptor.internalMergeFrom(
+ ((MessageLite) value).toBuilder(), (MessageLite) otherValue)
+ .build());
+ }
+
+ } else {
+ fields.put(descriptor, otherValue);
+ }
+ }
+
+ // TODO(kenton): Move static parsing and serialization methods into some
+ // other class. Probably WireFormat.
+
+ /**
+ * Read a field of any primitive type from a CodedInputStream. Enums,
+ * groups, and embedded messages are not handled by this method.
+ *
+ * @param input The stream from which to read.
+ * @param type Declared type of the field.
+ * @return An object representing the field's value, of the exact
+ * type which would be returned by
+ * {@link Message#getField(Descriptors.FieldDescriptor)} for
+ * this field.
+ */
+ public static Object readPrimitiveField(
+ CodedInputStream input,
+ final WireFormat.FieldType type) throws IOException {
+ switch (type) {
+ case DOUBLE : return input.readDouble ();
+ case FLOAT : return input.readFloat ();
+ case INT64 : return input.readInt64 ();
+ case UINT64 : return input.readUInt64 ();
+ case INT32 : return input.readInt32 ();
+ case FIXED64 : return input.readFixed64 ();
+ case FIXED32 : return input.readFixed32 ();
+ case BOOL : return input.readBool ();
+ case STRING : return input.readString ();
+ case BYTES : return input.readBytes ();
+ case UINT32 : return input.readUInt32 ();
+ case SFIXED32: return input.readSFixed32();
+ case SFIXED64: return input.readSFixed64();
+ case SINT32 : return input.readSInt32 ();
+ case SINT64 : return input.readSInt64 ();
+
+ case GROUP:
+ throw new IllegalArgumentException(
+ "readPrimitiveField() cannot handle nested groups.");
+ case MESSAGE:
+ throw new IllegalArgumentException(
+ "readPrimitiveField() cannot handle embedded messages.");
+ case ENUM:
+ // We don't handle enums because we don't know what to do if the
+ // value is not recognized.
+ throw new IllegalArgumentException(
+ "readPrimitiveField() cannot handle enums.");
+ }
+
+ throw new RuntimeException(
+ "There is no way to get here, but the compiler thinks otherwise.");
+ }
+
+ /** See {@link Message#writeTo(CodedOutputStream)}. */
+ public void writeTo(final CodedOutputStream output)
+ throws IOException {
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ final Map.Entry<FieldDescriptorType, Object> entry =
+ fields.getArrayEntryAt(i);
+ writeField(entry.getKey(), entry.getValue(), output);
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ writeField(entry.getKey(), entry.getValue(), output);
+ }
+ }
+
+ /**
+ * Like {@link #writeTo} but uses MessageSet wire format.
+ */
+ public void writeMessageSetTo(final CodedOutputStream output)
+ throws IOException {
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ writeMessageSetTo(fields.getArrayEntryAt(i), output);
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ writeMessageSetTo(entry, output);
+ }
+ }
+
+ private void writeMessageSetTo(
+ final Map.Entry<FieldDescriptorType, Object> entry,
+ final CodedOutputStream output) throws IOException {
+ final FieldDescriptorType descriptor = entry.getKey();
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE &&
+ !descriptor.isRepeated() && !descriptor.isPacked()) {
+ output.writeMessageSetExtension(entry.getKey().getNumber(),
+ (MessageLite) entry.getValue());
+ } else {
+ writeField(descriptor, entry.getValue(), output);
+ }
+ }
+
+ /**
+ * Write a single tag-value pair to the stream.
+ *
+ * @param output The output stream.
+ * @param type The field's type.
+ * @param number The field's number.
+ * @param value Object representing the field's value. Must be of the exact
+ * type which would be returned by
+ * {@link Message#getField(Descriptors.FieldDescriptor)} for
+ * this field.
+ */
+ private static void writeElement(final CodedOutputStream output,
+ final WireFormat.FieldType type,
+ final int number,
+ final Object value) throws IOException {
+ // Special case for groups, which need a start and end tag; other fields
+ // can just use writeTag() and writeFieldNoTag().
+ if (type == WireFormat.FieldType.GROUP) {
+ output.writeGroup(number, (MessageLite) value);
+ } else {
+ output.writeTag(number, getWireFormatForFieldType(type, false));
+ writeElementNoTag(output, type, value);
+ }
+ }
+
+ /**
+ * Write a field of arbitrary type, without its tag, to the stream.
+ *
+ * @param output The output stream.
+ * @param type The field's type.
+ * @param value Object representing the field's value. Must be of the exact
+ * type which would be returned by
+ * {@link Message#getField(Descriptors.FieldDescriptor)} for
+ * this field.
+ */
+ private static void writeElementNoTag(
+ final CodedOutputStream output,
+ final WireFormat.FieldType type,
+ final Object value) throws IOException {
+ switch (type) {
+ case DOUBLE : output.writeDoubleNoTag ((Double ) value); break;
+ case FLOAT : output.writeFloatNoTag ((Float ) value); break;
+ case INT64 : output.writeInt64NoTag ((Long ) value); break;
+ case UINT64 : output.writeUInt64NoTag ((Long ) value); break;
+ case INT32 : output.writeInt32NoTag ((Integer ) value); break;
+ case FIXED64 : output.writeFixed64NoTag ((Long ) value); break;
+ case FIXED32 : output.writeFixed32NoTag ((Integer ) value); break;
+ case BOOL : output.writeBoolNoTag ((Boolean ) value); break;
+ case STRING : output.writeStringNoTag ((String ) value); break;
+ case GROUP : output.writeGroupNoTag ((MessageLite) value); break;
+ case MESSAGE : output.writeMessageNoTag ((MessageLite) value); break;
+ case BYTES : output.writeBytesNoTag ((ByteString ) value); break;
+ case UINT32 : output.writeUInt32NoTag ((Integer ) value); break;
+ case SFIXED32: output.writeSFixed32NoTag((Integer ) value); break;
+ case SFIXED64: output.writeSFixed64NoTag((Long ) value); break;
+ case SINT32 : output.writeSInt32NoTag ((Integer ) value); break;
+ case SINT64 : output.writeSInt64NoTag ((Long ) value); break;
+
+ case ENUM:
+ output.writeEnumNoTag(((Internal.EnumLite) value).getNumber());
+ break;
+ }
+ }
+
+ /** Write a single field. */
+ public static void writeField(final FieldDescriptorLite<?> descriptor,
+ final Object value,
+ final CodedOutputStream output)
+ throws IOException {
+ WireFormat.FieldType type = descriptor.getLiteType();
+ int number = descriptor.getNumber();
+ if (descriptor.isRepeated()) {
+ final List<?> valueList = (List<?>)value;
+ if (descriptor.isPacked()) {
+ output.writeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ // Compute the total data size so the length can be written.
+ int dataSize = 0;
+ for (final Object element : valueList) {
+ dataSize += computeElementSizeNoTag(type, element);
+ }
+ output.writeRawVarint32(dataSize);
+ // Write the data itself, without any tags.
+ for (final Object element : valueList) {
+ writeElementNoTag(output, type, element);
+ }
+ } else {
+ for (final Object element : valueList) {
+ writeElement(output, type, number, element);
+ }
+ }
+ } else {
+ writeElement(output, type, number, value);
+ }
+ }
+
+ /**
+ * See {@link Message#getSerializedSize()}. It's up to the caller to cache
+ * the resulting size if desired.
+ */
+ public int getSerializedSize() {
+ int size = 0;
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ final Map.Entry<FieldDescriptorType, Object> entry =
+ fields.getArrayEntryAt(i);
+ size += computeFieldSize(entry.getKey(), entry.getValue());
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ size += computeFieldSize(entry.getKey(), entry.getValue());
+ }
+ return size;
+ }
+
+ /**
+ * Like {@link #getSerializedSize} but uses MessageSet wire format.
+ */
+ public int getMessageSetSerializedSize() {
+ int size = 0;
+ for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+ size += getMessageSetSerializedSize(fields.getArrayEntryAt(i));
+ }
+ for (final Map.Entry<FieldDescriptorType, Object> entry :
+ fields.getOverflowEntries()) {
+ size += getMessageSetSerializedSize(entry);
+ }
+ return size;
+ }
+
+ private int getMessageSetSerializedSize(
+ final Map.Entry<FieldDescriptorType, Object> entry) {
+ final FieldDescriptorType descriptor = entry.getKey();
+ if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE &&
+ !descriptor.isRepeated() && !descriptor.isPacked()) {
+ return CodedOutputStream.computeMessageSetExtensionSize(
+ entry.getKey().getNumber(), (MessageLite) entry.getValue());
+ } else {
+ return computeFieldSize(descriptor, entry.getValue());
+ }
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * single tag/value pair of arbitrary type.
+ *
+ * @param type The field's type.
+ * @param number The field's number.
+ * @param value Object representing the field's value. Must be of the exact
+ * type which would be returned by
+ * {@link Message#getField(Descriptors.FieldDescriptor)} for
+ * this field.
+ */
+ private static int computeElementSize(
+ final WireFormat.FieldType type,
+ final int number, final Object value) {
+ int tagSize = CodedOutputStream.computeTagSize(number);
+ if (type == WireFormat.FieldType.GROUP) {
+ tagSize *= 2;
+ }
+ return tagSize + computeElementSizeNoTag(type, value);
+ }
+
+ /**
+ * Compute the number of bytes that would be needed to encode a
+ * particular value of arbitrary type, excluding tag.
+ *
+ * @param type The field's type.
+ * @param value Object representing the field's value. Must be of the exact
+ * type which would be returned by
+ * {@link Message#getField(Descriptors.FieldDescriptor)} for
+ * this field.
+ */
+ private static int computeElementSizeNoTag(
+ final WireFormat.FieldType type, final Object value) {
+ switch (type) {
+ // Note: Minor violation of 80-char limit rule here because this would
+ // actually be harder to read if we wrapped the lines.
+ case DOUBLE : return CodedOutputStream.computeDoubleSizeNoTag ((Double )value);
+ case FLOAT : return CodedOutputStream.computeFloatSizeNoTag ((Float )value);
+ case INT64 : return CodedOutputStream.computeInt64SizeNoTag ((Long )value);
+ case UINT64 : return CodedOutputStream.computeUInt64SizeNoTag ((Long )value);
+ case INT32 : return CodedOutputStream.computeInt32SizeNoTag ((Integer )value);
+ case FIXED64 : return CodedOutputStream.computeFixed64SizeNoTag ((Long )value);
+ case FIXED32 : return CodedOutputStream.computeFixed32SizeNoTag ((Integer )value);
+ case BOOL : return CodedOutputStream.computeBoolSizeNoTag ((Boolean )value);
+ case STRING : return CodedOutputStream.computeStringSizeNoTag ((String )value);
+ case GROUP : return CodedOutputStream.computeGroupSizeNoTag ((MessageLite)value);
+ case MESSAGE : return CodedOutputStream.computeMessageSizeNoTag ((MessageLite)value);
+ case BYTES : return CodedOutputStream.computeBytesSizeNoTag ((ByteString )value);
+ case UINT32 : return CodedOutputStream.computeUInt32SizeNoTag ((Integer )value);
+ case SFIXED32: return CodedOutputStream.computeSFixed32SizeNoTag((Integer )value);
+ case SFIXED64: return CodedOutputStream.computeSFixed64SizeNoTag((Long )value);
+ case SINT32 : return CodedOutputStream.computeSInt32SizeNoTag ((Integer )value);
+ case SINT64 : return CodedOutputStream.computeSInt64SizeNoTag ((Long )value);
+
+ case ENUM:
+ return CodedOutputStream.computeEnumSizeNoTag(
+ ((Internal.EnumLite) value).getNumber());
+ }
+
+ throw new RuntimeException(
+ "There is no way to get here, but the compiler thinks otherwise.");
+ }
+
+ /**
+ * Compute the number of bytes needed to encode a particular field.
+ */
+ public static int computeFieldSize(final FieldDescriptorLite<?> descriptor,
+ final Object value) {
+ WireFormat.FieldType type = descriptor.getLiteType();
+ int number = descriptor.getNumber();
+ if (descriptor.isRepeated()) {
+ if (descriptor.isPacked()) {
+ int dataSize = 0;
+ for (final Object element : (List<?>)value) {
+ dataSize += computeElementSizeNoTag(type, element);
+ }
+ return dataSize +
+ CodedOutputStream.computeTagSize(number) +
+ CodedOutputStream.computeRawVarint32Size(dataSize);
+ } else {
+ int size = 0;
+ for (final Object element : (List<?>)value) {
+ size += computeElementSize(type, number, element);
+ }
+ return size;
+ }
+ } else {
+ return computeElementSize(type, number, value);
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessage.java
new file mode 100644
index 0000000..b5eaded
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -0,0 +1,1834 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.io.IOException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * All generated protocol message classes extend this class. This class
+ * implements most of the Message and Builder interfaces using Java reflection.
+ * Users can ignore this class and pretend that generated messages implement
+ * the Message interface directly.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class GeneratedMessage extends AbstractMessage
+ implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private final UnknownFieldSet unknownFields;
+
+ /**
+ * For testing. Allows a test to disable the optimization that avoids using
+ * field builders for nested messages until they are requested. By disabling
+ * this optimization, existing tests can be reused to test the field builders.
+ */
+ protected static boolean alwaysUseFieldBuilders = false;
+
+ protected GeneratedMessage() {
+ this.unknownFields = UnknownFieldSet.getDefaultInstance();
+ }
+
+ protected GeneratedMessage(Builder<?> builder) {
+ this.unknownFields = builder.getUnknownFields();
+ }
+
+ /**
+ * For testing. Allows a test to disable the optimization that avoids using
+ * field builders for nested messages until they are requested. By disabling
+ * this optimization, existing tests can be reused to test the field builders.
+ * See {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder}.
+ */
+ static void enableAlwaysUseFieldBuildersForTesting() {
+ alwaysUseFieldBuilders = true;
+ }
+
+ /**
+ * Get the FieldAccessorTable for this type. We can't have the message
+ * class pass this in to the constructor because of bootstrapping trouble
+ * with DescriptorProtos.
+ */
+ protected abstract FieldAccessorTable internalGetFieldAccessorTable();
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Descriptor getDescriptorForType() {
+ return internalGetFieldAccessorTable().descriptor;
+ }
+
+ /** Internal helper which returns a mutable map. */
+ private Map<FieldDescriptor, Object> getAllFieldsMutable() {
+ final TreeMap<FieldDescriptor, Object> result =
+ new TreeMap<FieldDescriptor, Object>();
+ final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
+ for (final FieldDescriptor field : descriptor.getFields()) {
+ if (field.isRepeated()) {
+ final List<?> value = (List<?>) getField(field);
+ if (!value.isEmpty()) {
+ result.put(field, value);
+ }
+ } else {
+ if (hasField(field)) {
+ result.put(field, getField(field));
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean isInitialized() {
+ for (final FieldDescriptor field : getDescriptorForType().getFields()) {
+ // Check that all required fields are present.
+ if (field.isRequired()) {
+ if (!hasField(field)) {
+ return false;
+ }
+ }
+ // Check that embedded messages are initialized.
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ @SuppressWarnings("unchecked") final
+ List<Message> messageList = (List<Message>) getField(field);
+ for (final Message element : messageList) {
+ if (!element.isInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (hasField(field) && !((Message) getField(field)).isInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Map<FieldDescriptor, Object> getAllFields() {
+ return Collections.unmodifiableMap(getAllFieldsMutable());
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasField(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).has(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Object getField(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).get(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public int getRepeatedFieldCount(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeatedCount(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Object getRepeatedField(final FieldDescriptor field, final int index) {
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeated(this, index);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final UnknownFieldSet getUnknownFields() {
+ return unknownFields;
+ }
+
+ protected abstract Message.Builder newBuilderForType(BuilderParent parent);
+
+ /**
+ * Interface for the parent of a Builder that allows the builder to
+ * communicate invalidations back to the parent for use when using nested
+ * builders.
+ */
+ protected interface BuilderParent {
+
+ /**
+ * A builder becomes dirty whenever a field is modified -- including fields
+ * in nested builders -- and becomes clean when build() is called. Thus,
+ * when a builder becomes dirty, all its parents become dirty as well, and
+ * when it becomes clean, all its children become clean. The dirtiness
+ * state is used to invalidate certain cached values.
+ * <br>
+ * To this end, a builder calls markAsDirty() on its parent whenever it
+ * transitions from clean to dirty. The parent must propagate this call to
+ * its own parent, unless it was already dirty, in which case the
+ * grandparent must necessarily already be dirty as well. The parent can
+ * only transition back to "clean" after calling build() on all children.
+ */
+ void markDirty();
+ }
+
+ @SuppressWarnings("unchecked")
+ public abstract static class Builder <BuilderType extends Builder>
+ extends AbstractMessage.Builder<BuilderType> {
+
+ private BuilderParent builderParent;
+
+ private BuilderParentImpl meAsParent;
+
+ // Indicates that we've built a message and so we are now obligated
+ // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
+ private boolean isClean;
+
+ private UnknownFieldSet unknownFields =
+ UnknownFieldSet.getDefaultInstance();
+
+ protected Builder() {
+ this(null);
+ }
+
+ protected Builder(BuilderParent builderParent) {
+ this.builderParent = builderParent;
+ }
+
+ void dispose() {
+ builderParent = null;
+ }
+
+ /**
+ * Called by the subclass when a message is built.
+ */
+ protected void onBuilt() {
+ if (builderParent != null) {
+ markClean();
+ }
+ }
+
+ /**
+ * Called by the subclass or a builder to notify us that a message was
+ * built and may be cached and therefore invalidations are needed.
+ */
+ protected void markClean() {
+ this.isClean = true;
+ }
+
+ /**
+ * Gets whether invalidations are needed
+ *
+ * @return whether invalidations are needed
+ */
+ protected boolean isClean() {
+ return isClean;
+ }
+
+ // This is implemented here only to work around an apparent bug in the
+ // Java compiler and/or build system. See bug #1898463. The mere presence
+ // of this dummy clone() implementation makes it go away.
+ @Override
+ public BuilderType clone() {
+ throw new UnsupportedOperationException(
+ "This is supposed to be overridden by subclasses.");
+ }
+
+ /**
+ * Called by the initialization and clear code paths to allow subclasses to
+ * reset any of their builtin fields back to the initial values.
+ */
+ public BuilderType clear() {
+ unknownFields = UnknownFieldSet.getDefaultInstance();
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /**
+ * Get the FieldAccessorTable for this type. We can't have the message
+ * class pass this in to the constructor because of bootstrapping trouble
+ * with DescriptorProtos.
+ */
+ protected abstract FieldAccessorTable internalGetFieldAccessorTable();
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Descriptor getDescriptorForType() {
+ return internalGetFieldAccessorTable().descriptor;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Map<FieldDescriptor, Object> getAllFields() {
+ return Collections.unmodifiableMap(getAllFieldsMutable());
+ }
+
+ /** Internal helper which returns a mutable map. */
+ private Map<FieldDescriptor, Object> getAllFieldsMutable() {
+ final TreeMap<FieldDescriptor, Object> result =
+ new TreeMap<FieldDescriptor, Object>();
+ final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
+ for (final FieldDescriptor field : descriptor.getFields()) {
+ if (field.isRepeated()) {
+ final List value = (List) getField(field);
+ if (!value.isEmpty()) {
+ result.put(field, value);
+ }
+ } else {
+ if (hasField(field)) {
+ result.put(field, getField(field));
+ }
+ }
+ }
+ return result;
+ }
+
+ public Message.Builder newBuilderForField(
+ final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).newBuilder();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasField(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field).has(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Object getField(final FieldDescriptor field) {
+ Object object = internalGetFieldAccessorTable().getField(field).get(this);
+ if (field.isRepeated()) {
+ // The underlying list object is still modifiable at this point.
+ // Make sure not to expose the modifiable list to the caller.
+ return Collections.unmodifiableList((List) object);
+ } else {
+ return object;
+ }
+ }
+
+ public BuilderType setField(final FieldDescriptor field,
+ final Object value) {
+ internalGetFieldAccessorTable().getField(field).set(this, value);
+ return (BuilderType) this;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public BuilderType clearField(final FieldDescriptor field) {
+ internalGetFieldAccessorTable().getField(field).clear(this);
+ return (BuilderType) this;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public int getRepeatedFieldCount(final FieldDescriptor field) {
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeatedCount(this);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Object getRepeatedField(final FieldDescriptor field,
+ final int index) {
+ return internalGetFieldAccessorTable().getField(field)
+ .getRepeated(this, index);
+ }
+
+ public BuilderType setRepeatedField(final FieldDescriptor field,
+ final int index, final Object value) {
+ internalGetFieldAccessorTable().getField(field)
+ .setRepeated(this, index, value);
+ return (BuilderType) this;
+ }
+
+ public BuilderType addRepeatedField(final FieldDescriptor field,
+ final Object value) {
+ internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
+ return (BuilderType) this;
+ }
+
+ public final BuilderType setUnknownFields(
+ final UnknownFieldSet unknownFields) {
+ this.unknownFields = unknownFields;
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ @Override
+ public final BuilderType mergeUnknownFields(
+ final UnknownFieldSet unknownFields) {
+ this.unknownFields =
+ UnknownFieldSet.newBuilder(this.unknownFields)
+ .mergeFrom(unknownFields)
+ .build();
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean isInitialized() {
+ for (final FieldDescriptor field : getDescriptorForType().getFields()) {
+ // Check that all required fields are present.
+ if (field.isRequired()) {
+ if (!hasField(field)) {
+ return false;
+ }
+ }
+ // Check that embedded messages are initialized.
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (field.isRepeated()) {
+ @SuppressWarnings("unchecked") final
+ List<Message> messageList = (List<Message>) getField(field);
+ for (final Message element : messageList) {
+ if (!element.isInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (hasField(field) &&
+ !((Message) getField(field)).isInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final UnknownFieldSet getUnknownFields() {
+ return unknownFields;
+ }
+
+ /**
+ * Called by subclasses to parse an unknown field.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ protected boolean parseUnknownField(
+ final CodedInputStream input,
+ final UnknownFieldSet.Builder unknownFields,
+ final ExtensionRegistryLite extensionRegistry,
+ final int tag) throws IOException {
+ return unknownFields.mergeFieldFrom(tag, input);
+ }
+
+ /**
+ * Implementation of {@link BuilderParent} for giving to our children. This
+ * small inner class makes it so we don't publicly expose the BuilderParent
+ * methods.
+ */
+ private class BuilderParentImpl implements BuilderParent {
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void markDirty() {
+ onChanged();
+ }
+ }
+
+ /**
+ * Gets the {@link BuilderParent} for giving to our children.
+ * @return The builder parent for our children.
+ */
+ protected BuilderParent getParentForChildren() {
+ if (meAsParent == null) {
+ meAsParent = new BuilderParentImpl();
+ }
+ return meAsParent;
+ }
+
+ /**
+ * Called when a the builder or one of its nested children has changed
+ * and any parent should be notified of its invalidation.
+ */
+ protected final void onChanged() {
+ if (isClean && builderParent != null) {
+ builderParent.markDirty();
+
+ // Don't keep dispatching invalidations until build is called again.
+ isClean = false;
+ }
+ }
+ }
+
+ // =================================================================
+ // Extensions-related stuff
+
+ public interface ExtendableMessageOrBuilder<
+ MessageType extends ExtendableMessage> extends MessageOrBuilder {
+
+ /** Check if a singular extension is present. */
+ <Type> boolean hasExtension(
+ GeneratedExtension<MessageType, Type> extension);
+
+ /** Get the number of elements in a repeated extension. */
+ <Type> int getExtensionCount(
+ GeneratedExtension<MessageType, List<Type>> extension);
+
+ /** Get the value of an extension. */
+ <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);
+
+ /** Get one element of a repeated extension. */
+ <Type> Type getExtension(
+ GeneratedExtension<MessageType, List<Type>> extension,
+ int index);
+ }
+
+ /**
+ * Generated message classes for message types that contain extension ranges
+ * subclass this.
+ *
+ * <p>This class implements type-safe accessors for extensions. They
+ * implement all the same operations that you can do with normal fields --
+ * e.g. "has", "get", and "getCount" -- but for extensions. The extensions
+ * are identified using instances of the class {@link GeneratedExtension};
+ * the protocol compiler generates a static instance of this class for every
+ * extension in its input. Through the magic of generics, all is made
+ * type-safe.
+ *
+ * <p>For example, imagine you have the {@code .proto} file:
+ *
+ * <pre>
+ * option java_class = "MyProto";
+ *
+ * message Foo {
+ * extensions 1000 to max;
+ * }
+ *
+ * extend Foo {
+ * optional int32 bar;
+ * }
+ * </pre>
+ *
+ * <p>Then you might write code like:
+ *
+ * <pre>
+ * MyProto.Foo foo = getFoo();
+ * int i = foo.getExtension(MyProto.bar);
+ * </pre>
+ *
+ * <p>See also {@link ExtendableBuilder}.
+ */
+ public abstract static class ExtendableMessage<
+ MessageType extends ExtendableMessage>
+ extends GeneratedMessage
+ implements ExtendableMessageOrBuilder<MessageType> {
+
+ private final FieldSet<FieldDescriptor> extensions;
+
+ protected ExtendableMessage() {
+ this.extensions = FieldSet.newFieldSet();
+ }
+
+ protected ExtendableMessage(
+ ExtendableBuilder<MessageType, ?> builder) {
+ super(builder);
+ this.extensions = builder.buildExtensions();
+ }
+
+ private void verifyExtensionContainingType(
+ final GeneratedExtension<MessageType, ?> extension) {
+ if (extension.getDescriptor().getContainingType() !=
+ getDescriptorForType()) {
+ // This can only happen if someone uses unchecked operations.
+ throw new IllegalArgumentException(
+ "Extension is for type \"" +
+ extension.getDescriptor().getContainingType().getFullName() +
+ "\" which does not match message type \"" +
+ getDescriptorForType().getFullName() + "\".");
+ }
+ }
+
+ /** Check if a singular extension is present. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ return extensions.hasField(extension.getDescriptor());
+ }
+
+ /** Get the number of elements in a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> int getExtensionCount(
+ final GeneratedExtension<MessageType, List<Type>> extension) {
+ verifyExtensionContainingType(extension);
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ return extensions.getRepeatedFieldCount(descriptor);
+ }
+
+ /** Get the value of an extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @SuppressWarnings("unchecked")
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ FieldDescriptor descriptor = extension.getDescriptor();
+ final Object value = extensions.getField(descriptor);
+ if (value == null) {
+ if (descriptor.isRepeated()) {
+ return (Type) Collections.emptyList();
+ } else if (descriptor.getJavaType() ==
+ FieldDescriptor.JavaType.MESSAGE) {
+ return (Type) extension.getMessageDefaultInstance();
+ } else {
+ return (Type) extension.fromReflectionType(
+ descriptor.getDefaultValue());
+ }
+ } else {
+ return (Type) extension.fromReflectionType(value);
+ }
+ }
+
+ /** Get one element of a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @SuppressWarnings("unchecked")
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final int index) {
+ verifyExtensionContainingType(extension);
+ FieldDescriptor descriptor = extension.getDescriptor();
+ return (Type) extension.singularFromReflectionType(
+ extensions.getRepeatedField(descriptor, index));
+ }
+
+ /** Called by subclasses to check if all extensions are initialized. */
+ protected boolean extensionsAreInitialized() {
+ return extensions.isInitialized();
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return super.isInitialized() && extensionsAreInitialized();
+ }
+
+ /**
+ * Used by subclasses to serialize extensions. Extension ranges may be
+ * interleaved with field numbers, but we must write them in canonical
+ * (sorted by field number) order. ExtensionWriter helps us write
+ * individual ranges of extensions at once.
+ */
+ protected class ExtensionWriter {
+ // Imagine how much simpler this code would be if Java iterators had
+ // a way to get the next element without advancing the iterator.
+
+ private final Iterator<Map.Entry<FieldDescriptor, Object>> iter =
+ extensions.iterator();
+ private Map.Entry<FieldDescriptor, Object> next;
+ private final boolean messageSetWireFormat;
+
+ private ExtensionWriter(final boolean messageSetWireFormat) {
+ if (iter.hasNext()) {
+ next = iter.next();
+ }
+ this.messageSetWireFormat = messageSetWireFormat;
+ }
+
+ public void writeUntil(final int end, final CodedOutputStream output)
+ throws IOException {
+ while (next != null && next.getKey().getNumber() < end) {
+ FieldDescriptor descriptor = next.getKey();
+ if (messageSetWireFormat && descriptor.getLiteJavaType() ==
+ WireFormat.JavaType.MESSAGE &&
+ !descriptor.isRepeated()) {
+ output.writeMessageSetExtension(descriptor.getNumber(),
+ (Message) next.getValue());
+ } else {
+ FieldSet.writeField(descriptor, next.getValue(), output);
+ }
+ if (iter.hasNext()) {
+ next = iter.next();
+ } else {
+ next = null;
+ }
+ }
+ }
+ }
+
+ protected ExtensionWriter newExtensionWriter() {
+ return new ExtensionWriter(false);
+ }
+ protected ExtensionWriter newMessageSetExtensionWriter() {
+ return new ExtensionWriter(true);
+ }
+
+ /** Called by subclasses to compute the size of extensions. */
+ protected int extensionsSerializedSize() {
+ return extensions.getSerializedSize();
+ }
+ protected int extensionsSerializedSizeAsMessageSet() {
+ return extensions.getMessageSetSerializedSize();
+ }
+
+ // ---------------------------------------------------------------
+ // Reflection
+
+ protected Map<FieldDescriptor, Object> getExtensionFields() {
+ return extensions.getAllFields();
+ }
+
+ @Override
+ public Map<FieldDescriptor, Object> getAllFields() {
+ final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
+ result.putAll(getExtensionFields());
+ return Collections.unmodifiableMap(result);
+ }
+
+ @Override
+ public boolean hasField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.hasField(field);
+ } else {
+ return super.hasField(field);
+ }
+ }
+
+ @Override
+ public Object getField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ final Object value = extensions.getField(field);
+ if (value == null) {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ // Lacking an ExtensionRegistry, we have no way to determine the
+ // extension's real type, so we return a DynamicMessage.
+ return DynamicMessage.getDefaultInstance(field.getMessageType());
+ } else {
+ return field.getDefaultValue();
+ }
+ } else {
+ return value;
+ }
+ } else {
+ return super.getField(field);
+ }
+ }
+
+ @Override
+ public int getRepeatedFieldCount(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.getRepeatedFieldCount(field);
+ } else {
+ return super.getRepeatedFieldCount(field);
+ }
+ }
+
+ @Override
+ public Object getRepeatedField(final FieldDescriptor field,
+ final int index) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.getRepeatedField(field, index);
+ } else {
+ return super.getRepeatedField(field, index);
+ }
+ }
+
+ private void verifyContainingType(final FieldDescriptor field) {
+ if (field.getContainingType() != getDescriptorForType()) {
+ throw new IllegalArgumentException(
+ "FieldDescriptor does not match message type.");
+ }
+ }
+ }
+
+ /**
+ * Generated message builders for message types that contain extension ranges
+ * subclass this.
+ *
+ * <p>This class implements type-safe accessors for extensions. They
+ * implement all the same operations that you can do with normal fields --
+ * e.g. "get", "set", and "add" -- but for extensions. The extensions are
+ * identified using instances of the class {@link GeneratedExtension}; the
+ * protocol compiler generates a static instance of this class for every
+ * extension in its input. Through the magic of generics, all is made
+ * type-safe.
+ *
+ * <p>For example, imagine you have the {@code .proto} file:
+ *
+ * <pre>
+ * option java_class = "MyProto";
+ *
+ * message Foo {
+ * extensions 1000 to max;
+ * }
+ *
+ * extend Foo {
+ * optional int32 bar;
+ * }
+ * </pre>
+ *
+ * <p>Then you might write code like:
+ *
+ * <pre>
+ * MyProto.Foo foo =
+ * MyProto.Foo.newBuilder()
+ * .setExtension(MyProto.bar, 123)
+ * .build();
+ * </pre>
+ *
+ * <p>See also {@link ExtendableMessage}.
+ */
+ @SuppressWarnings("unchecked")
+ public abstract static class ExtendableBuilder<
+ MessageType extends ExtendableMessage,
+ BuilderType extends ExtendableBuilder>
+ extends Builder<BuilderType>
+ implements ExtendableMessageOrBuilder<MessageType> {
+
+ private FieldSet<FieldDescriptor> extensions = FieldSet.emptySet();
+
+ protected ExtendableBuilder() {}
+
+ protected ExtendableBuilder(
+ BuilderParent parent) {
+ super(parent);
+ }
+
+ @Override
+ public BuilderType clear() {
+ extensions = FieldSet.emptySet();
+ return super.clear();
+ }
+
+ // This is implemented here only to work around an apparent bug in the
+ // Java compiler and/or build system. See bug #1898463. The mere presence
+ // of this dummy clone() implementation makes it go away.
+ @Override
+ public BuilderType clone() {
+ throw new UnsupportedOperationException(
+ "This is supposed to be overridden by subclasses.");
+ }
+
+ private void ensureExtensionsIsMutable() {
+ if (extensions.isImmutable()) {
+ extensions = extensions.clone();
+ }
+ }
+
+ private void verifyExtensionContainingType(
+ final GeneratedExtension<MessageType, ?> extension) {
+ if (extension.getDescriptor().getContainingType() !=
+ getDescriptorForType()) {
+ // This can only happen if someone uses unchecked operations.
+ throw new IllegalArgumentException(
+ "Extension is for type \"" +
+ extension.getDescriptor().getContainingType().getFullName() +
+ "\" which does not match message type \"" +
+ getDescriptorForType().getFullName() + "\".");
+ }
+ }
+
+ /** Check if a singular extension is present. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ return extensions.hasField(extension.getDescriptor());
+ }
+
+ /** Get the number of elements in a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> int getExtensionCount(
+ final GeneratedExtension<MessageType, List<Type>> extension) {
+ verifyExtensionContainingType(extension);
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ return extensions.getRepeatedFieldCount(descriptor);
+ }
+
+ /** Get the value of an extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ FieldDescriptor descriptor = extension.getDescriptor();
+ final Object value = extensions.getField(descriptor);
+ if (value == null) {
+ if (descriptor.isRepeated()) {
+ return (Type) Collections.emptyList();
+ } else if (descriptor.getJavaType() ==
+ FieldDescriptor.JavaType.MESSAGE) {
+ return (Type) extension.getMessageDefaultInstance();
+ } else {
+ return (Type) extension.fromReflectionType(
+ descriptor.getDefaultValue());
+ }
+ } else {
+ return (Type) extension.fromReflectionType(value);
+ }
+ }
+
+ /** Get one element of a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final int index) {
+ verifyExtensionContainingType(extension);
+ FieldDescriptor descriptor = extension.getDescriptor();
+ return (Type) extension.singularFromReflectionType(
+ extensions.getRepeatedField(descriptor, index));
+ }
+
+ /** Set the value of an extension. */
+ public final <Type> BuilderType setExtension(
+ final GeneratedExtension<MessageType, Type> extension,
+ final Type value) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ extensions.setField(descriptor, extension.toReflectionType(value));
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /** Set the value of one element of a repeated extension. */
+ public final <Type> BuilderType setExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final int index, final Type value) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ extensions.setRepeatedField(
+ descriptor, index,
+ extension.singularToReflectionType(value));
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /** Append a value to a repeated extension. */
+ public final <Type> BuilderType addExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final Type value) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ final FieldDescriptor descriptor = extension.getDescriptor();
+ extensions.addRepeatedField(
+ descriptor, extension.singularToReflectionType(value));
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /** Clear an extension. */
+ public final <Type> BuilderType clearExtension(
+ final GeneratedExtension<MessageType, ?> extension) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.clearField(extension.getDescriptor());
+ onChanged();
+ return (BuilderType) this;
+ }
+
+ /** Called by subclasses to check if all extensions are initialized. */
+ protected boolean extensionsAreInitialized() {
+ return extensions.isInitialized();
+ }
+
+ /**
+ * Called by the build code path to create a copy of the extensions for
+ * building the message.
+ */
+ private FieldSet<FieldDescriptor> buildExtensions() {
+ extensions.makeImmutable();
+ return extensions;
+ }
+
+ @Override
+ public boolean isInitialized() {
+ return super.isInitialized() && extensionsAreInitialized();
+ }
+
+ /**
+ * Called by subclasses to parse an unknown field or an extension.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ @Override
+ protected boolean parseUnknownField(
+ final CodedInputStream input,
+ final UnknownFieldSet.Builder unknownFields,
+ final ExtensionRegistryLite extensionRegistry,
+ final int tag) throws IOException {
+ return AbstractMessage.Builder.mergeFieldFrom(
+ input, unknownFields, extensionRegistry, this, tag);
+ }
+
+ // ---------------------------------------------------------------
+ // Reflection
+
+ @Override
+ public Map<FieldDescriptor, Object> getAllFields() {
+ final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
+ result.putAll(extensions.getAllFields());
+ return Collections.unmodifiableMap(result);
+ }
+
+ @Override
+ public Object getField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ final Object value = extensions.getField(field);
+ if (value == null) {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ // Lacking an ExtensionRegistry, we have no way to determine the
+ // extension's real type, so we return a DynamicMessage.
+ return DynamicMessage.getDefaultInstance(field.getMessageType());
+ } else {
+ return field.getDefaultValue();
+ }
+ } else {
+ return value;
+ }
+ } else {
+ return super.getField(field);
+ }
+ }
+
+ @Override
+ public int getRepeatedFieldCount(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.getRepeatedFieldCount(field);
+ } else {
+ return super.getRepeatedFieldCount(field);
+ }
+ }
+
+ @Override
+ public Object getRepeatedField(final FieldDescriptor field,
+ final int index) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.getRepeatedField(field, index);
+ } else {
+ return super.getRepeatedField(field, index);
+ }
+ }
+
+ @Override
+ public boolean hasField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ return extensions.hasField(field);
+ } else {
+ return super.hasField(field);
+ }
+ }
+
+ @Override
+ public BuilderType setField(final FieldDescriptor field,
+ final Object value) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.setField(field, value);
+ onChanged();
+ return (BuilderType) this;
+ } else {
+ return super.setField(field, value);
+ }
+ }
+
+ @Override
+ public BuilderType clearField(final FieldDescriptor field) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.clearField(field);
+ onChanged();
+ return (BuilderType) this;
+ } else {
+ return super.clearField(field);
+ }
+ }
+
+ @Override
+ public BuilderType setRepeatedField(final FieldDescriptor field,
+ final int index, final Object value) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.setRepeatedField(field, index, value);
+ onChanged();
+ return (BuilderType) this;
+ } else {
+ return super.setRepeatedField(field, index, value);
+ }
+ }
+
+ @Override
+ public BuilderType addRepeatedField(final FieldDescriptor field,
+ final Object value) {
+ if (field.isExtension()) {
+ verifyContainingType(field);
+ ensureExtensionsIsMutable();
+ extensions.addRepeatedField(field, value);
+ onChanged();
+ return (BuilderType) this;
+ } else {
+ return super.addRepeatedField(field, value);
+ }
+ }
+
+ protected final void mergeExtensionFields(final ExtendableMessage other) {
+ ensureExtensionsIsMutable();
+ extensions.mergeFrom(other.extensions);
+ onChanged();
+ }
+
+ private void verifyContainingType(final FieldDescriptor field) {
+ if (field.getContainingType() != getDescriptorForType()) {
+ throw new IllegalArgumentException(
+ "FieldDescriptor does not match message type.");
+ }
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+ /**
+ * Gets the descriptor for an extension. The implementation depends on whether
+ * the extension is scoped in the top level of a file or scoped in a Message.
+ */
+ private static interface ExtensionDescriptorRetriever {
+ FieldDescriptor getDescriptor();
+ }
+
+ /** For use by generated code only. */
+ public static <ContainingType extends Message, Type>
+ GeneratedExtension<ContainingType, Type>
+ newMessageScopedGeneratedExtension(final Message scope,
+ final int descriptorIndex,
+ final Class singularType,
+ final Message defaultInstance) {
+ // For extensions scoped within a Message, we use the Message to resolve
+ // the outer class's descriptor, from which the extension descriptor is
+ // obtained.
+ return new GeneratedExtension<ContainingType, Type>(
+ new ExtensionDescriptorRetriever() {
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public FieldDescriptor getDescriptor() {
+ return scope.getDescriptorForType().getExtensions()
+ .get(descriptorIndex);
+ }
+ },
+ singularType,
+ defaultInstance);
+ }
+
+ /** For use by generated code only. */
+ public static <ContainingType extends Message, Type>
+ GeneratedExtension<ContainingType, Type>
+ newFileScopedGeneratedExtension(final Class singularType,
+ final Message defaultInstance) {
+ // For extensions scoped within a file, we rely on the outer class's
+ // static initializer to call internalInit() on the extension when the
+ // descriptor is available.
+ return new GeneratedExtension<ContainingType, Type>(
+ null, // ExtensionDescriptorRetriever is initialized in internalInit();
+ singularType,
+ defaultInstance);
+ }
+
+ /**
+ * Type used to represent generated extensions. The protocol compiler
+ * generates a static singleton instance of this class for each extension.
+ *
+ * <p>For example, imagine you have the {@code .proto} file:
+ *
+ * <pre>
+ * option java_class = "MyProto";
+ *
+ * message Foo {
+ * extensions 1000 to max;
+ * }
+ *
+ * extend Foo {
+ * optional int32 bar;
+ * }
+ * </pre>
+ *
+ * <p>Then, {@code MyProto.Foo.bar} has type
+ * {@code GeneratedExtension<MyProto.Foo, Integer>}.
+ *
+ * <p>In general, users should ignore the details of this type, and simply use
+ * these static singletons as parameters to the extension accessors defined
+ * in {@link ExtendableMessage} and {@link ExtendableBuilder}.
+ */
+ public static final class GeneratedExtension<
+ ContainingType extends Message, Type> {
+ // TODO(kenton): Find ways to avoid using Java reflection within this
+ // class. Also try to avoid suppressing unchecked warnings.
+
+ // We can't always initialize the descriptor of a GeneratedExtension when
+ // we first construct it due to initialization order difficulties (namely,
+ // the descriptor may not have been constructed yet, since it is often
+ // constructed by the initializer of a separate module).
+ //
+ // In the case of nested extensions, we initialize the
+ // ExtensionDescriptorRetriever with an instance that uses the scoping
+ // Message's default instance to retrieve the extension's descriptor.
+ //
+ // In the case of non-nested extensions, we initialize the
+ // ExtensionDescriptorRetriever to null and rely on the outer class's static
+ // initializer to call internalInit() after the descriptor has been parsed.
+ private GeneratedExtension(ExtensionDescriptorRetriever descriptorRetriever,
+ Class singularType,
+ Message messageDefaultInstance) {
+ if (Message.class.isAssignableFrom(singularType) &&
+ !singularType.isInstance(messageDefaultInstance)) {
+ throw new IllegalArgumentException(
+ "Bad messageDefaultInstance for " + singularType.getName());
+ }
+ this.descriptorRetriever = descriptorRetriever;
+ this.singularType = singularType;
+ this.messageDefaultInstance = messageDefaultInstance;
+
+ if (ProtocolMessageEnum.class.isAssignableFrom(singularType)) {
+ this.enumValueOf = getMethodOrDie(singularType, "valueOf",
+ EnumValueDescriptor.class);
+ this.enumGetValueDescriptor =
+ getMethodOrDie(singularType, "getValueDescriptor");
+ } else {
+ this.enumValueOf = null;
+ this.enumGetValueDescriptor = null;
+ }
+ }
+
+ /** For use by generated code only. */
+ public void internalInit(final FieldDescriptor descriptor) {
+ if (descriptorRetriever != null) {
+ throw new IllegalStateException("Already initialized.");
+ }
+ descriptorRetriever = new ExtensionDescriptorRetriever() {
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public FieldDescriptor getDescriptor() {
+ return descriptor;
+ }
+ };
+ }
+
+ private ExtensionDescriptorRetriever descriptorRetriever;
+ private final Class singularType;
+ private final Message messageDefaultInstance;
+ private final Method enumValueOf;
+ private final Method enumGetValueDescriptor;
+
+ public FieldDescriptor getDescriptor() {
+ if (descriptorRetriever == null) {
+ throw new IllegalStateException(
+ "getDescriptor() called before internalInit()");
+ }
+ return descriptorRetriever.getDescriptor();
+ }
+
+ /**
+ * If the extension is an embedded message or group, returns the default
+ * instance of the message.
+ */
+ public Message getMessageDefaultInstance() {
+ return messageDefaultInstance;
+ }
+
+ /**
+ * Convert from the type used by the reflection accessors to the type used
+ * by native accessors. E.g., for enums, the reflection accessors use
+ * EnumValueDescriptors but the native accessors use the generated enum
+ * type.
+ */
+ @SuppressWarnings("unchecked")
+ private Object fromReflectionType(final Object value) {
+ FieldDescriptor descriptor = getDescriptor();
+ if (descriptor.isRepeated()) {
+ if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE ||
+ descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+ // Must convert the whole list.
+ final List result = new ArrayList();
+ for (final Object element : (List) value) {
+ result.add(singularFromReflectionType(element));
+ }
+ return result;
+ } else {
+ return value;
+ }
+ } else {
+ return singularFromReflectionType(value);
+ }
+ }
+
+ /**
+ * Like {@link #fromReflectionType(Object)}, but if the type is a repeated
+ * type, this converts a single element.
+ */
+ private Object singularFromReflectionType(final Object value) {
+ FieldDescriptor descriptor = getDescriptor();
+ switch (descriptor.getJavaType()) {
+ case MESSAGE:
+ if (singularType.isInstance(value)) {
+ return value;
+ } else {
+ // It seems the copy of the embedded message stored inside the
+ // extended message is not of the exact type the user was
+ // expecting. This can happen if a user defines a
+ // GeneratedExtension manually and gives it a different type.
+ // This should not happen in normal use. But, to be nice, we'll
+ // copy the message to whatever type the caller was expecting.
+ return messageDefaultInstance.newBuilderForType()
+ .mergeFrom((Message) value).build();
+ }
+ case ENUM:
+ return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value);
+ default:
+ return value;
+ }
+ }
+
+ /**
+ * Convert from the type used by the native accessors to the type used
+ * by reflection accessors. E.g., for enums, the reflection accessors use
+ * EnumValueDescriptors but the native accessors use the generated enum
+ * type.
+ */
+ @SuppressWarnings("unchecked")
+ private Object toReflectionType(final Object value) {
+ FieldDescriptor descriptor = getDescriptor();
+ if (descriptor.isRepeated()) {
+ if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+ // Must convert the whole list.
+ final List result = new ArrayList();
+ for (final Object element : (List) value) {
+ result.add(singularToReflectionType(element));
+ }
+ return result;
+ } else {
+ return value;
+ }
+ } else {
+ return singularToReflectionType(value);
+ }
+ }
+
+ /**
+ * Like {@link #toReflectionType(Object)}, but if the type is a repeated
+ * type, this converts a single element.
+ */
+ private Object singularToReflectionType(final Object value) {
+ FieldDescriptor descriptor = getDescriptor();
+ switch (descriptor.getJavaType()) {
+ case ENUM:
+ return invokeOrDie(enumGetValueDescriptor, value);
+ default:
+ return value;
+ }
+ }
+ }
+
+ // =================================================================
+
+ /** Calls Class.getMethod and throws a RuntimeException if it fails. */
+ @SuppressWarnings("unchecked")
+ private static Method getMethodOrDie(
+ final Class clazz, final String name, final Class... params) {
+ try {
+ return clazz.getMethod(name, params);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(
+ "Generated message class \"" + clazz.getName() +
+ "\" missing method \"" + name + "\".", e);
+ }
+ }
+
+ /** Calls invoke and throws a RuntimeException if it fails. */
+ private static Object invokeOrDie(
+ final Method method, final Object object, final Object... params) {
+ try {
+ return method.invoke(object, params);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(
+ "Couldn't use Java reflection to implement protocol message " +
+ "reflection.", e);
+ } catch (InvocationTargetException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof RuntimeException) {
+ throw (RuntimeException) cause;
+ } else if (cause instanceof Error) {
+ throw (Error) cause;
+ } else {
+ throw new RuntimeException(
+ "Unexpected exception thrown by generated accessor method.", cause);
+ }
+ }
+ }
+
+ /**
+ * Users should ignore this class. This class provides the implementation
+ * with access to the fields of a message object using Java reflection.
+ */
+ public static final class FieldAccessorTable {
+
+ /**
+ * Construct a FieldAccessorTable for a particular message class. Only
+ * one FieldAccessorTable should ever be constructed per class.
+ *
+ * @param descriptor The type's descriptor.
+ * @param camelCaseNames The camelcase names of all fields in the message.
+ * These are used to derive the accessor method names.
+ * @param messageClass The message type.
+ * @param builderClass The builder type.
+ */
+ public FieldAccessorTable(
+ final Descriptor descriptor,
+ final String[] camelCaseNames,
+ final Class<? extends GeneratedMessage> messageClass,
+ final Class<? extends Builder> builderClass) {
+ this.descriptor = descriptor;
+ fields = new FieldAccessor[descriptor.getFields().size()];
+
+ for (int i = 0; i < fields.length; i++) {
+ final FieldDescriptor field = descriptor.getFields().get(i);
+ if (field.isRepeated()) {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ fields[i] = new RepeatedMessageFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+ fields[i] = new RepeatedEnumFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ } else {
+ fields[i] = new RepeatedFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ }
+ } else {
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ fields[i] = new SingularMessageFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+ fields[i] = new SingularEnumFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ } else {
+ fields[i] = new SingularFieldAccessor(
+ field, camelCaseNames[i], messageClass, builderClass);
+ }
+ }
+ }
+ }
+
+ private final Descriptor descriptor;
+ private final FieldAccessor[] fields;
+
+ /** Get the FieldAccessor for a particular field. */
+ private FieldAccessor getField(final FieldDescriptor field) {
+ if (field.getContainingType() != descriptor) {
+ throw new IllegalArgumentException(
+ "FieldDescriptor does not match message type.");
+ } else if (field.isExtension()) {
+ // If this type had extensions, it would subclass ExtendableMessage,
+ // which overrides the reflection interface to handle extensions.
+ throw new IllegalArgumentException(
+ "This type does not have extensions.");
+ }
+ return fields[field.getIndex()];
+ }
+
+ /**
+ * Abstract interface that provides access to a single field. This is
+ * implemented differently depending on the field type and cardinality.
+ */
+ private interface FieldAccessor {
+ Object get(GeneratedMessage message);
+ Object get(GeneratedMessage.Builder builder);
+ void set(Builder builder, Object value);
+ Object getRepeated(GeneratedMessage message, int index);
+ Object getRepeated(GeneratedMessage.Builder builder, int index);
+ void setRepeated(Builder builder,
+ int index, Object value);
+ void addRepeated(Builder builder, Object value);
+ boolean has(GeneratedMessage message);
+ boolean has(GeneratedMessage.Builder builder);
+ int getRepeatedCount(GeneratedMessage message);
+ int getRepeatedCount(GeneratedMessage.Builder builder);
+ void clear(Builder builder);
+ Message.Builder newBuilder();
+ }
+
+ // ---------------------------------------------------------------
+
+ private static class SingularFieldAccessor implements FieldAccessor {
+ SingularFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessage> messageClass,
+ final Class<? extends Builder> builderClass) {
+ getMethod = getMethodOrDie(messageClass, "get" + camelCaseName);
+ getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName);
+ type = getMethod.getReturnType();
+ setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type);
+ hasMethod =
+ getMethodOrDie(messageClass, "has" + camelCaseName);
+ hasMethodBuilder =
+ getMethodOrDie(builderClass, "has" + camelCaseName);
+ clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
+ }
+
+ // Note: We use Java reflection to call public methods rather than
+ // access private fields directly as this avoids runtime security
+ // checks.
+ protected final Class<?> type;
+ protected final Method getMethod;
+ protected final Method getMethodBuilder;
+ protected final Method setMethod;
+ protected final Method hasMethod;
+ protected final Method hasMethodBuilder;
+ protected final Method clearMethod;
+
+ public Object get(final GeneratedMessage message) {
+ return invokeOrDie(getMethod, message);
+ }
+ public Object get(GeneratedMessage.Builder builder) {
+ return invokeOrDie(getMethodBuilder, builder);
+ }
+ public void set(final Builder builder, final Object value) {
+ invokeOrDie(setMethod, builder, value);
+ }
+ public Object getRepeated(final GeneratedMessage message,
+ final int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedField() called on a singular field.");
+ }
+ public Object getRepeated(GeneratedMessage.Builder builder, int index) {
+ throw new UnsupportedOperationException(
+ "getRepeatedField() called on a singular field.");
+ }
+ public void setRepeated(final Builder builder,
+ final int index, final Object value) {
+ throw new UnsupportedOperationException(
+ "setRepeatedField() called on a singular field.");
+ }
+ public void addRepeated(final Builder builder, final Object value) {
+ throw new UnsupportedOperationException(
+ "addRepeatedField() called on a singular field.");
+ }
+ public boolean has(final GeneratedMessage message) {
+ return (Boolean) invokeOrDie(hasMethod, message);
+ }
+ public boolean has(GeneratedMessage.Builder builder) {
+ return (Boolean) invokeOrDie(hasMethodBuilder, builder);
+ }
+ public int getRepeatedCount(final GeneratedMessage message) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldSize() called on a singular field.");
+ }
+ public int getRepeatedCount(GeneratedMessage.Builder builder) {
+ throw new UnsupportedOperationException(
+ "getRepeatedFieldSize() called on a singular field.");
+ }
+ public void clear(final Builder builder) {
+ invokeOrDie(clearMethod, builder);
+ }
+ public Message.Builder newBuilder() {
+ throw new UnsupportedOperationException(
+ "newBuilderForField() called on a non-Message type.");
+ }
+ }
+
+ private static class RepeatedFieldAccessor implements FieldAccessor {
+ protected final Class type;
+ protected final Method getMethod;
+ protected final Method getMethodBuilder;
+ protected final Method getRepeatedMethod;
+ protected final Method getRepeatedMethodBuilder;
+ protected final Method setRepeatedMethod;
+ protected final Method addRepeatedMethod;
+ protected final Method getCountMethod;
+ protected final Method getCountMethodBuilder;
+ protected final Method clearMethod;
+
+ RepeatedFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessage> messageClass,
+ final Class<? extends Builder> builderClass) {
+ getMethod = getMethodOrDie(messageClass,
+ "get" + camelCaseName + "List");
+ getMethodBuilder = getMethodOrDie(builderClass,
+ "get" + camelCaseName + "List");
+
+
+ getRepeatedMethod =
+ getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE);
+ getRepeatedMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE);
+ type = getRepeatedMethod.getReturnType();
+ setRepeatedMethod =
+ getMethodOrDie(builderClass, "set" + camelCaseName,
+ Integer.TYPE, type);
+ addRepeatedMethod =
+ getMethodOrDie(builderClass, "add" + camelCaseName, type);
+ getCountMethod =
+ getMethodOrDie(messageClass, "get" + camelCaseName + "Count");
+ getCountMethodBuilder =
+ getMethodOrDie(builderClass, "get" + camelCaseName + "Count");
+
+ clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
+ }
+
+ public Object get(final GeneratedMessage message) {
+ return invokeOrDie(getMethod, message);
+ }
+ public Object get(GeneratedMessage.Builder builder) {
+ return invokeOrDie(getMethodBuilder, builder);
+ }
+ public void set(final Builder builder, final Object value) {
+ // Add all the elements individually. This serves two purposes:
+ // 1) Verifies that each element has the correct type.
+ // 2) Insures that the caller cannot modify the list later on and
+ // have the modifications be reflected in the message.
+ clear(builder);
+ for (final Object element : (List<?>) value) {
+ addRepeated(builder, element);
+ }
+ }
+ public Object getRepeated(final GeneratedMessage message,
+ final int index) {
+ return invokeOrDie(getRepeatedMethod, message, index);
+ }
+ public Object getRepeated(GeneratedMessage.Builder builder, int index) {
+ return invokeOrDie(getRepeatedMethodBuilder, builder, index);
+ }
+ public void setRepeated(final Builder builder,
+ final int index, final Object value) {
+ invokeOrDie(setRepeatedMethod, builder, index, value);
+ }
+ public void addRepeated(final Builder builder, final Object value) {
+ invokeOrDie(addRepeatedMethod, builder, value);
+ }
+ public boolean has(final GeneratedMessage message) {
+ throw new UnsupportedOperationException(
+ "hasField() called on a singular field.");
+ }
+ public boolean has(GeneratedMessage.Builder builder) {
+ throw new UnsupportedOperationException(
+ "hasField() called on a singular field.");
+ }
+ public int getRepeatedCount(final GeneratedMessage message) {
+ return (Integer) invokeOrDie(getCountMethod, message);
+ }
+ public int getRepeatedCount(GeneratedMessage.Builder builder) {
+ return (Integer) invokeOrDie(getCountMethodBuilder, builder);
+ }
+ public void clear(final Builder builder) {
+ invokeOrDie(clearMethod, builder);
+ }
+ public Message.Builder newBuilder() {
+ throw new UnsupportedOperationException(
+ "newBuilderForField() called on a non-Message type.");
+ }
+ }
+
+ // ---------------------------------------------------------------
+
+ private static final class SingularEnumFieldAccessor
+ extends SingularFieldAccessor {
+ SingularEnumFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessage> messageClass,
+ final Class<? extends Builder> builderClass) {
+ super(descriptor, camelCaseName, messageClass, builderClass);
+
+ valueOfMethod = getMethodOrDie(type, "valueOf",
+ EnumValueDescriptor.class);
+ getValueDescriptorMethod =
+ getMethodOrDie(type, "getValueDescriptor");
+ }
+
+ private Method valueOfMethod;
+ private Method getValueDescriptorMethod;
+
+ @Override
+ public Object get(final GeneratedMessage message) {
+ return invokeOrDie(getValueDescriptorMethod, super.get(message));
+ }
+
+ @Override
+ public Object get(final GeneratedMessage.Builder builder) {
+ return invokeOrDie(getValueDescriptorMethod, super.get(builder));
+ }
+
+ @Override
+ public void set(final Builder builder, final Object value) {
+ super.set(builder, invokeOrDie(valueOfMethod, null, value));
+ }
+ }
+
+ private static final class RepeatedEnumFieldAccessor
+ extends RepeatedFieldAccessor {
+ RepeatedEnumFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessage> messageClass,
+ final Class<? extends Builder> builderClass) {
+ super(descriptor, camelCaseName, messageClass, builderClass);
+
+ valueOfMethod = getMethodOrDie(type, "valueOf",
+ EnumValueDescriptor.class);
+ getValueDescriptorMethod =
+ getMethodOrDie(type, "getValueDescriptor");
+ }
+
+ private final Method valueOfMethod;
+ private final Method getValueDescriptorMethod;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object get(final GeneratedMessage message) {
+ final List newList = new ArrayList();
+ for (final Object element : (List) super.get(message)) {
+ newList.add(invokeOrDie(getValueDescriptorMethod, element));
+ }
+ return Collections.unmodifiableList(newList);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object get(final GeneratedMessage.Builder builder) {
+ final List newList = new ArrayList();
+ for (final Object element : (List) super.get(builder)) {
+ newList.add(invokeOrDie(getValueDescriptorMethod, element));
+ }
+ return Collections.unmodifiableList(newList);
+ }
+
+ @Override
+ public Object getRepeated(final GeneratedMessage message,
+ final int index) {
+ return invokeOrDie(getValueDescriptorMethod,
+ super.getRepeated(message, index));
+ }
+ @Override
+ public Object getRepeated(final GeneratedMessage.Builder builder,
+ final int index) {
+ return invokeOrDie(getValueDescriptorMethod,
+ super.getRepeated(builder, index));
+ }
+ @Override
+ public void setRepeated(final Builder builder,
+ final int index, final Object value) {
+ super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null,
+ value));
+ }
+ @Override
+ public void addRepeated(final Builder builder, final Object value) {
+ super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value));
+ }
+ }
+
+ // ---------------------------------------------------------------
+
+ private static final class SingularMessageFieldAccessor
+ extends SingularFieldAccessor {
+ SingularMessageFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessage> messageClass,
+ final Class<? extends Builder> builderClass) {
+ super(descriptor, camelCaseName, messageClass, builderClass);
+
+ newBuilderMethod = getMethodOrDie(type, "newBuilder");
+ }
+
+ private final Method newBuilderMethod;
+
+ private Object coerceType(final Object value) {
+ if (type.isInstance(value)) {
+ return value;
+ } else {
+ // The value is not the exact right message type. However, if it
+ // is an alternative implementation of the same type -- e.g. a
+ // DynamicMessage -- we should accept it. In this case we can make
+ // a copy of the message.
+ return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
+ .mergeFrom((Message) value).build();
+ }
+ }
+
+ @Override
+ public void set(final Builder builder, final Object value) {
+ super.set(builder, coerceType(value));
+ }
+ @Override
+ public Message.Builder newBuilder() {
+ return (Message.Builder) invokeOrDie(newBuilderMethod, null);
+ }
+ }
+
+ private static final class RepeatedMessageFieldAccessor
+ extends RepeatedFieldAccessor {
+ RepeatedMessageFieldAccessor(
+ final FieldDescriptor descriptor, final String camelCaseName,
+ final Class<? extends GeneratedMessage> messageClass,
+ final Class<? extends Builder> builderClass) {
+ super(descriptor, camelCaseName, messageClass, builderClass);
+
+ newBuilderMethod = getMethodOrDie(type, "newBuilder");
+ }
+
+ private final Method newBuilderMethod;
+
+ private Object coerceType(final Object value) {
+ if (type.isInstance(value)) {
+ return value;
+ } else {
+ // The value is not the exact right message type. However, if it
+ // is an alternative implementation of the same type -- e.g. a
+ // DynamicMessage -- we should accept it. In this case we can make
+ // a copy of the message.
+ return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
+ .mergeFrom((Message) value).build();
+ }
+ }
+
+ @Override
+ public void setRepeated(final Builder builder,
+ final int index, final Object value) {
+ super.setRepeated(builder, index, coerceType(value));
+ }
+ @Override
+ public void addRepeated(final Builder builder, final Object value) {
+ super.addRepeated(builder, coerceType(value));
+ }
+ @Override
+ public Message.Builder newBuilder() {
+ return (Message.Builder) invokeOrDie(newBuilderMethod, null);
+ }
+ }
+ }
+
+ /**
+ * Replaces this object in the output stream with a serialized form.
+ * Part of Java's serialization magic. Generated sub-classes must override
+ * this method by calling <code>return super.writeReplace();</code>
+ * @return a SerializedForm of this message
+ */
+ protected Object writeReplace() throws ObjectStreamException {
+ return new GeneratedMessageLite.SerializedForm(this);
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
new file mode 100644
index 0000000..1813e9b
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -0,0 +1,731 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Lite version of {@link GeneratedMessage}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class GeneratedMessageLite extends AbstractMessageLite
+ implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ protected GeneratedMessageLite() {
+ }
+
+ protected GeneratedMessageLite(Builder builder) {
+ }
+
+ @SuppressWarnings("unchecked")
+ public abstract static class Builder<MessageType extends GeneratedMessageLite,
+ BuilderType extends Builder>
+ extends AbstractMessageLite.Builder<BuilderType> {
+ protected Builder() {}
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public BuilderType clear() {
+ return (BuilderType) this;
+ }
+
+ // This is implemented here only to work around an apparent bug in the
+ // Java compiler and/or build system. See bug #1898463. The mere presence
+ // of this dummy clone() implementation makes it go away.
+ @Override
+ public BuilderType clone() {
+ throw new UnsupportedOperationException(
+ "This is supposed to be overridden by subclasses.");
+ }
+
+ /** All subclasses implement this. */
+ public abstract BuilderType mergeFrom(MessageType message);
+
+ // Defined here for return type covariance.
+ public abstract MessageType getDefaultInstanceForType();
+
+ /**
+ * Called by subclasses to parse an unknown field.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ protected boolean parseUnknownField(
+ final CodedInputStream input,
+ final ExtensionRegistryLite extensionRegistry,
+ final int tag) throws IOException {
+ return input.skipField(tag);
+ }
+ }
+
+ // =================================================================
+ // Extensions-related stuff
+
+ /**
+ * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
+ */
+ public interface ExtendableMessageOrBuilder<
+ MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {
+
+ /** Check if a singular extension is present. */
+ <Type> boolean hasExtension(
+ GeneratedExtension<MessageType, Type> extension);
+
+ /** Get the number of elements in a repeated extension. */
+ <Type> int getExtensionCount(
+ GeneratedExtension<MessageType, List<Type>> extension);
+
+ /** Get the value of an extension. */
+ <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);
+
+ /** Get one element of a repeated extension. */
+ <Type> Type getExtension(
+ GeneratedExtension<MessageType, List<Type>> extension,
+ int index);
+ }
+
+ /**
+ * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
+ */
+ public abstract static class ExtendableMessage<
+ MessageType extends ExtendableMessage<MessageType>>
+ extends GeneratedMessageLite
+ implements ExtendableMessageOrBuilder<MessageType> {
+
+ private final FieldSet<ExtensionDescriptor> extensions;
+
+ protected ExtendableMessage() {
+ this.extensions = FieldSet.newFieldSet();
+ }
+
+ protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) {
+ this.extensions = builder.buildExtensions();
+ }
+
+ private void verifyExtensionContainingType(
+ final GeneratedExtension<MessageType, ?> extension) {
+ if (extension.getContainingTypeDefaultInstance() !=
+ getDefaultInstanceForType()) {
+ // This can only happen if someone uses unchecked operations.
+ throw new IllegalArgumentException(
+ "This extension is for a different message type. Please make " +
+ "sure that you are not suppressing any generics type warnings.");
+ }
+ }
+
+ /** Check if a singular extension is present. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ return extensions.hasField(extension.descriptor);
+ }
+
+ /** Get the number of elements in a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> int getExtensionCount(
+ final GeneratedExtension<MessageType, List<Type>> extension) {
+ verifyExtensionContainingType(extension);
+ return extensions.getRepeatedFieldCount(extension.descriptor);
+ }
+
+ /** Get the value of an extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @SuppressWarnings("unchecked")
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ final Object value = extensions.getField(extension.descriptor);
+ if (value == null) {
+ return extension.defaultValue;
+ } else {
+ return (Type) value;
+ }
+ }
+
+ /** Get one element of a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @SuppressWarnings("unchecked")
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final int index) {
+ verifyExtensionContainingType(extension);
+ return (Type) extensions.getRepeatedField(extension.descriptor, index);
+ }
+
+ /** Called by subclasses to check if all extensions are initialized. */
+ protected boolean extensionsAreInitialized() {
+ return extensions.isInitialized();
+ }
+
+ /**
+ * Used by subclasses to serialize extensions. Extension ranges may be
+ * interleaved with field numbers, but we must write them in canonical
+ * (sorted by field number) order. ExtensionWriter helps us write
+ * individual ranges of extensions at once.
+ */
+ protected class ExtensionWriter {
+ // Imagine how much simpler this code would be if Java iterators had
+ // a way to get the next element without advancing the iterator.
+
+ private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter =
+ extensions.iterator();
+ private Map.Entry<ExtensionDescriptor, Object> next;
+ private final boolean messageSetWireFormat;
+
+ private ExtensionWriter(boolean messageSetWireFormat) {
+ if (iter.hasNext()) {
+ next = iter.next();
+ }
+ this.messageSetWireFormat = messageSetWireFormat;
+ }
+
+ public void writeUntil(final int end, final CodedOutputStream output)
+ throws IOException {
+ while (next != null && next.getKey().getNumber() < end) {
+ ExtensionDescriptor extension = next.getKey();
+ if (messageSetWireFormat && extension.getLiteJavaType() ==
+ WireFormat.JavaType.MESSAGE &&
+ !extension.isRepeated()) {
+ output.writeMessageSetExtension(extension.getNumber(),
+ (MessageLite) next.getValue());
+ } else {
+ FieldSet.writeField(extension, next.getValue(), output);
+ }
+ if (iter.hasNext()) {
+ next = iter.next();
+ } else {
+ next = null;
+ }
+ }
+ }
+ }
+
+ protected ExtensionWriter newExtensionWriter() {
+ return new ExtensionWriter(false);
+ }
+ protected ExtensionWriter newMessageSetExtensionWriter() {
+ return new ExtensionWriter(true);
+ }
+
+ /** Called by subclasses to compute the size of extensions. */
+ protected int extensionsSerializedSize() {
+ return extensions.getSerializedSize();
+ }
+ protected int extensionsSerializedSizeAsMessageSet() {
+ return extensions.getMessageSetSerializedSize();
+ }
+ }
+
+ /**
+ * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
+ */
+ @SuppressWarnings("unchecked")
+ public abstract static class ExtendableBuilder<
+ MessageType extends ExtendableMessage<MessageType>,
+ BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
+ extends Builder<MessageType, BuilderType>
+ implements ExtendableMessageOrBuilder<MessageType> {
+ protected ExtendableBuilder() {}
+
+ private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
+ private boolean extensionsIsMutable;
+
+ @Override
+ public BuilderType clear() {
+ extensions.clear();
+ extensionsIsMutable = false;
+ return super.clear();
+ }
+
+ private void ensureExtensionsIsMutable() {
+ if (!extensionsIsMutable) {
+ extensions = extensions.clone();
+ extensionsIsMutable = true;
+ }
+ }
+
+ /**
+ * Called by the build code path to create a copy of the extensions for
+ * building the message.
+ */
+ private FieldSet<ExtensionDescriptor> buildExtensions() {
+ extensions.makeImmutable();
+ extensionsIsMutable = false;
+ return extensions;
+ }
+
+ private void verifyExtensionContainingType(
+ final GeneratedExtension<MessageType, ?> extension) {
+ if (extension.getContainingTypeDefaultInstance() !=
+ getDefaultInstanceForType()) {
+ // This can only happen if someone uses unchecked operations.
+ throw new IllegalArgumentException(
+ "This extension is for a different message type. Please make " +
+ "sure that you are not suppressing any generics type warnings.");
+ }
+ }
+
+ /** Check if a singular extension is present. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> boolean hasExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ return extensions.hasField(extension.descriptor);
+ }
+
+ /** Get the number of elements in a repeated extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> int getExtensionCount(
+ final GeneratedExtension<MessageType, List<Type>> extension) {
+ verifyExtensionContainingType(extension);
+ return extensions.getRepeatedFieldCount(extension.descriptor);
+ }
+
+ /** Get the value of an extension. */
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ @SuppressWarnings("unchecked")
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, Type> extension) {
+ verifyExtensionContainingType(extension);
+ final Object value = extensions.getField(extension.descriptor);
+ if (value == null) {
+ return extension.defaultValue;
+ } else {
+ return (Type) value;
+ }
+ }
+
+ /** Get one element of a repeated extension. */
+ @SuppressWarnings("unchecked")
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public final <Type> Type getExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final int index) {
+ verifyExtensionContainingType(extension);
+ return (Type) extensions.getRepeatedField(extension.descriptor, index);
+ }
+
+ // This is implemented here only to work around an apparent bug in the
+ // Java compiler and/or build system. See bug #1898463. The mere presence
+ // of this dummy clone() implementation makes it go away.
+ @Override
+ public BuilderType clone() {
+ throw new UnsupportedOperationException(
+ "This is supposed to be overridden by subclasses.");
+ }
+
+ /** Set the value of an extension. */
+ public final <Type> BuilderType setExtension(
+ final GeneratedExtension<MessageType, Type> extension,
+ final Type value) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.setField(extension.descriptor, value);
+ return (BuilderType) this;
+ }
+
+ /** Set the value of one element of a repeated extension. */
+ public final <Type> BuilderType setExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final int index, final Type value) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.setRepeatedField(extension.descriptor, index, value);
+ return (BuilderType) this;
+ }
+
+ /** Append a value to a repeated extension. */
+ public final <Type> BuilderType addExtension(
+ final GeneratedExtension<MessageType, List<Type>> extension,
+ final Type value) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.addRepeatedField(extension.descriptor, value);
+ return (BuilderType) this;
+ }
+
+ /** Clear an extension. */
+ public final <Type> BuilderType clearExtension(
+ final GeneratedExtension<MessageType, ?> extension) {
+ verifyExtensionContainingType(extension);
+ ensureExtensionsIsMutable();
+ extensions.clearField(extension.descriptor);
+ return (BuilderType) this;
+ }
+
+ /** Called by subclasses to check if all extensions are initialized. */
+ protected boolean extensionsAreInitialized() {
+ return extensions.isInitialized();
+ }
+
+ /**
+ * Called by subclasses to parse an unknown field or an extension.
+ * @return {@code true} unless the tag is an end-group tag.
+ */
+ @Override
+ protected boolean parseUnknownField(
+ final CodedInputStream input,
+ final ExtensionRegistryLite extensionRegistry,
+ final int tag) throws IOException {
+ final int wireType = WireFormat.getTagWireType(tag);
+ final int fieldNumber = WireFormat.getTagFieldNumber(tag);
+
+ final GeneratedExtension<MessageType, ?> extension =
+ extensionRegistry.findLiteExtensionByNumber(
+ getDefaultInstanceForType(), fieldNumber);
+
+ boolean unknown = false;
+ boolean packed = false;
+ if (extension == null) {
+ unknown = true; // Unknown field.
+ } else if (wireType == FieldSet.getWireFormatForFieldType(
+ extension.descriptor.getLiteType(),
+ false /* isPacked */)) {
+ packed = false; // Normal, unpacked value.
+ } else if (extension.descriptor.isRepeated &&
+ extension.descriptor.type.isPackable() &&
+ wireType == FieldSet.getWireFormatForFieldType(
+ extension.descriptor.getLiteType(),
+ true /* isPacked */)) {
+ packed = true; // Packed value.
+ } else {
+ unknown = true; // Wrong wire type.
+ }
+
+ if (unknown) { // Unknown field or wrong wire type. Skip.
+ return input.skipField(tag);
+ }
+
+ if (packed) {
+ final int length = input.readRawVarint32();
+ final int limit = input.pushLimit(length);
+ if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
+ while (input.getBytesUntilLimit() > 0) {
+ final int rawValue = input.readEnum();
+ final Object value =
+ extension.descriptor.getEnumType().findValueByNumber(rawValue);
+ if (value == null) {
+ // If the number isn't recognized as a valid value for this
+ // enum, drop it (don't even add it to unknownFields).
+ return true;
+ }
+ ensureExtensionsIsMutable();
+ extensions.addRepeatedField(extension.descriptor, value);
+ }
+ } else {
+ while (input.getBytesUntilLimit() > 0) {
+ final Object value =
+ FieldSet.readPrimitiveField(input,
+ extension.descriptor.getLiteType());
+ ensureExtensionsIsMutable();
+ extensions.addRepeatedField(extension.descriptor, value);
+ }
+ }
+ input.popLimit(limit);
+ } else {
+ final Object value;
+ switch (extension.descriptor.getLiteJavaType()) {
+ case MESSAGE: {
+ MessageLite.Builder subBuilder = null;
+ if (!extension.descriptor.isRepeated()) {
+ MessageLite existingValue =
+ (MessageLite) extensions.getField(extension.descriptor);
+ if (existingValue != null) {
+ subBuilder = existingValue.toBuilder();
+ }
+ }
+ if (subBuilder == null) {
+ subBuilder = extension.messageDefaultInstance.newBuilderForType();
+ }
+ if (extension.descriptor.getLiteType() ==
+ WireFormat.FieldType.GROUP) {
+ input.readGroup(extension.getNumber(),
+ subBuilder, extensionRegistry);
+ } else {
+ input.readMessage(subBuilder, extensionRegistry);
+ }
+ value = subBuilder.build();
+ break;
+ }
+ case ENUM:
+ final int rawValue = input.readEnum();
+ value = extension.descriptor.getEnumType()
+ .findValueByNumber(rawValue);
+ // If the number isn't recognized as a valid value for this enum,
+ // drop it.
+ if (value == null) {
+ return true;
+ }
+ break;
+ default:
+ value = FieldSet.readPrimitiveField(input,
+ extension.descriptor.getLiteType());
+ break;
+ }
+
+ if (extension.descriptor.isRepeated()) {
+ ensureExtensionsIsMutable();
+ extensions.addRepeatedField(extension.descriptor, value);
+ } else {
+ ensureExtensionsIsMutable();
+ extensions.setField(extension.descriptor, value);
+ }
+ }
+
+ return true;
+ }
+
+ protected final void mergeExtensionFields(final MessageType other) {
+ ensureExtensionsIsMutable();
+ extensions.mergeFrom(((ExtendableMessage) other).extensions);
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+ /** For use by generated code only. */
+ public static <ContainingType extends MessageLite, Type>
+ GeneratedExtension<ContainingType, Type>
+ newSingularGeneratedExtension(
+ final ContainingType containingTypeDefaultInstance,
+ final Type defaultValue,
+ final MessageLite messageDefaultInstance,
+ final Internal.EnumLiteMap<?> enumTypeMap,
+ final int number,
+ final WireFormat.FieldType type) {
+ return new GeneratedExtension<ContainingType, Type>(
+ containingTypeDefaultInstance,
+ defaultValue,
+ messageDefaultInstance,
+ new ExtensionDescriptor(enumTypeMap, number, type,
+ false /* isRepeated */,
+ false /* isPacked */));
+ }
+
+ /** For use by generated code only. */
+ public static <ContainingType extends MessageLite, Type>
+ GeneratedExtension<ContainingType, Type>
+ newRepeatedGeneratedExtension(
+ final ContainingType containingTypeDefaultInstance,
+ final MessageLite messageDefaultInstance,
+ final Internal.EnumLiteMap<?> enumTypeMap,
+ final int number,
+ final WireFormat.FieldType type,
+ final boolean isPacked) {
+ @SuppressWarnings("unchecked") // Subclasses ensure Type is a List
+ Type emptyList = (Type) Collections.emptyList();
+ return new GeneratedExtension<ContainingType, Type>(
+ containingTypeDefaultInstance,
+ emptyList,
+ messageDefaultInstance,
+ new ExtensionDescriptor(
+ enumTypeMap, number, type, true /* isRepeated */, isPacked));
+ }
+
+ private static final class ExtensionDescriptor
+ implements FieldSet.FieldDescriptorLite<
+ ExtensionDescriptor> {
+ private ExtensionDescriptor(
+ final Internal.EnumLiteMap<?> enumTypeMap,
+ final int number,
+ final WireFormat.FieldType type,
+ final boolean isRepeated,
+ final boolean isPacked) {
+ this.enumTypeMap = enumTypeMap;
+ this.number = number;
+ this.type = type;
+ this.isRepeated = isRepeated;
+ this.isPacked = isPacked;
+ }
+
+ private final Internal.EnumLiteMap<?> enumTypeMap;
+ private final int number;
+ private final WireFormat.FieldType type;
+ private final boolean isRepeated;
+ private final boolean isPacked;
+
+ public int getNumber() {
+ return number;
+ }
+
+ public WireFormat.FieldType getLiteType() {
+ return type;
+ }
+
+ public WireFormat.JavaType getLiteJavaType() {
+ return type.getJavaType();
+ }
+
+ public boolean isRepeated() {
+ return isRepeated;
+ }
+
+ public boolean isPacked() {
+ return isPacked;
+ }
+
+ public Internal.EnumLiteMap<?> getEnumType() {
+ return enumTypeMap;
+ }
+
+ @SuppressWarnings("unchecked")
+ public MessageLite.Builder internalMergeFrom(
+ MessageLite.Builder to, MessageLite from) {
+ return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
+ }
+
+ public int compareTo(ExtensionDescriptor other) {
+ return number - other.number;
+ }
+ }
+
+ /**
+ * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
+ *
+ * Users should ignore the contents of this class and only use objects of
+ * this type as parameters to extension accessors and ExtensionRegistry.add().
+ */
+ public static final class GeneratedExtension<
+ ContainingType extends MessageLite, Type> {
+
+ private GeneratedExtension(
+ final ContainingType containingTypeDefaultInstance,
+ final Type defaultValue,
+ final MessageLite messageDefaultInstance,
+ final ExtensionDescriptor descriptor) {
+ // Defensive checks to verify the correct initialization order of
+ // GeneratedExtensions and their related GeneratedMessages.
+ if (containingTypeDefaultInstance == null) {
+ throw new IllegalArgumentException(
+ "Null containingTypeDefaultInstance");
+ }
+ if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE &&
+ messageDefaultInstance == null) {
+ throw new IllegalArgumentException(
+ "Null messageDefaultInstance");
+ }
+ this.containingTypeDefaultInstance = containingTypeDefaultInstance;
+ this.defaultValue = defaultValue;
+ this.messageDefaultInstance = messageDefaultInstance;
+ this.descriptor = descriptor;
+ }
+
+ private final ContainingType containingTypeDefaultInstance;
+ private final Type defaultValue;
+ private final MessageLite messageDefaultInstance;
+ private final ExtensionDescriptor descriptor;
+
+ /**
+ * Default instance of the type being extended, used to identify that type.
+ */
+ public ContainingType getContainingTypeDefaultInstance() {
+ return containingTypeDefaultInstance;
+ }
+
+ /** Get the field number. */
+ public int getNumber() {
+ return descriptor.getNumber();
+ }
+
+ /**
+ * If the extension is an embedded message, this is the default instance of
+ * that type.
+ */
+ public MessageLite getMessageDefaultInstance() {
+ return messageDefaultInstance;
+ }
+ }
+
+ /**
+ * A serialized (serializable) form of the generated message. Stores the
+ * message as a class name and a byte array.
+ */
+ static final class SerializedForm implements Serializable {
+ private static final long serialVersionUID = 0L;
+
+ private String messageClassName;
+ private byte[] asBytes;
+
+ /**
+ * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
+ * @param regularForm the message to serialize
+ */
+ SerializedForm(MessageLite regularForm) {
+ messageClassName = regularForm.getClass().getName();
+ asBytes = regularForm.toByteArray();
+ }
+
+ /**
+ * When read from an ObjectInputStream, this method converts this object
+ * back to the regular form. Part of Java's serialization magic.
+ * @return a GeneratedMessage of the type that was serialized
+ */
+ @SuppressWarnings("unchecked")
+ protected Object readResolve() throws ObjectStreamException {
+ try {
+ Class messageClass = Class.forName(messageClassName);
+ Method newBuilder = messageClass.getMethod("newBuilder");
+ MessageLite.Builder builder =
+ (MessageLite.Builder) newBuilder.invoke(null);
+ builder.mergeFrom(asBytes);
+ return builder.buildPartial();
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Unable to find proto buffer class", e);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("Unable to find newBuilder method", e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Unable to call newBuilder method", e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException("Error calling newBuilder", e.getCause());
+ } catch (InvalidProtocolBufferException e) {
+ throw new RuntimeException("Unable to understand proto buffer", e);
+ }
+ }
+ }
+
+ /**
+ * Replaces this object in the output stream with a serialized form.
+ * Part of Java's serialization magic. Generated sub-classes must override
+ * this method by calling <code>return super.writeReplace();</code>
+ * @return a SerializedForm of this message
+ */
+ protected Object writeReplace() throws ObjectStreamException {
+ return new SerializedForm(this);
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Internal.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Internal.java
new file mode 100644
index 0000000..05eab57
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Internal.java
@@ -0,0 +1,206 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * The classes contained within are used internally by the Protocol Buffer
+ * library and generated message implementations. They are public only because
+ * those generated messages do not reside in the {@code protobuf} package.
+ * Others should not use this class directly.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public class Internal {
+ /**
+ * Helper called by generated code to construct default values for string
+ * fields.
+ * <p>
+ * The protocol compiler does not actually contain a UTF-8 decoder -- it
+ * just pushes UTF-8-encoded text around without touching it. The one place
+ * where this presents a problem is when generating Java string literals.
+ * Unicode characters in the string literal would normally need to be encoded
+ * using a Unicode escape sequence, which would require decoding them.
+ * To get around this, protoc instead embeds the UTF-8 bytes into the
+ * generated code and leaves it to the runtime library to decode them.
+ * <p>
+ * It gets worse, though. If protoc just generated a byte array, like:
+ * new byte[] {0x12, 0x34, 0x56, 0x78}
+ * Java actually generates *code* which allocates an array and then fills
+ * in each value. This is much less efficient than just embedding the bytes
+ * directly into the bytecode. To get around this, we need another
+ * work-around. String literals are embedded directly, so protoc actually
+ * generates a string literal corresponding to the bytes. The easiest way
+ * to do this is to use the ISO-8859-1 character set, which corresponds to
+ * the first 256 characters of the Unicode range. Protoc can then use
+ * good old CEscape to generate the string.
+ * <p>
+ * So we have a string literal which represents a set of bytes which
+ * represents another string. This function -- stringDefaultValue --
+ * converts from the generated string to the string we actually want. The
+ * generated code calls this automatically.
+ */
+ public static String stringDefaultValue(String bytes) {
+ try {
+ return new String(bytes.getBytes("ISO-8859-1"), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // This should never happen since all JVMs are required to implement
+ // both of the above character sets.
+ throw new IllegalStateException(
+ "Java VM does not support a standard character set.", e);
+ }
+ }
+
+ /**
+ * Helper called by generated code to construct default values for bytes
+ * fields.
+ * <p>
+ * This is a lot like {@link #stringDefaultValue}, but for bytes fields.
+ * In this case we only need the second of the two hacks -- allowing us to
+ * embed raw bytes as a string literal with ISO-8859-1 encoding.
+ */
+ public static ByteString bytesDefaultValue(String bytes) {
+ try {
+ return ByteString.copyFrom(bytes.getBytes("ISO-8859-1"));
+ } catch (UnsupportedEncodingException e) {
+ // This should never happen since all JVMs are required to implement
+ // ISO-8859-1.
+ throw new IllegalStateException(
+ "Java VM does not support a standard character set.", e);
+ }
+ }
+
+ /**
+ * Helper called by generated code to determine if a byte array is a valid
+ * UTF-8 encoded string such that the original bytes can be converted to
+ * a String object and then back to a byte array round tripping the bytes
+ * without loss.
+ * <p>
+ * This is inspired by UTF_8.java in sun.nio.cs.
+ *
+ * @param byteString the string to check
+ * @return whether the byte array is round trippable
+ */
+ public static boolean isValidUtf8(ByteString byteString) {
+ int index = 0;
+ int size = byteString.size();
+ // To avoid the masking, we could change this to use bytes;
+ // Then X > 0xC2 gets turned into X < -0xC2; X < 0x80
+ // gets turned into X >= 0, etc.
+
+ while (index < size) {
+ int byte1 = byteString.byteAt(index++) & 0xFF;
+ if (byte1 < 0x80) {
+ // fast loop for single bytes
+ continue;
+
+ // we know from this point on that we have 2-4 byte forms
+ } else if (byte1 < 0xC2 || byte1 > 0xF4) {
+ // catch illegal first bytes: < C2 or > F4
+ return false;
+ }
+ if (index >= size) {
+ // fail if we run out of bytes
+ return false;
+ }
+ int byte2 = byteString.byteAt(index++) & 0xFF;
+ if (byte2 < 0x80 || byte2 > 0xBF) {
+ // general trail-byte test
+ return false;
+ }
+ if (byte1 <= 0xDF) {
+ // two-byte form; general trail-byte test is sufficient
+ continue;
+ }
+
+ // we know from this point on that we have 3 or 4 byte forms
+ if (index >= size) {
+ // fail if we run out of bytes
+ return false;
+ }
+ int byte3 = byteString.byteAt(index++) & 0xFF;
+ if (byte3 < 0x80 || byte3 > 0xBF) {
+ // general trail-byte test
+ return false;
+ }
+ if (byte1 <= 0xEF) {
+ // three-byte form. Vastly more frequent than four-byte forms
+ // The following has an extra test, but not worth restructuring
+ if (byte1 == 0xE0 && byte2 < 0xA0 ||
+ byte1 == 0xED && byte2 > 0x9F) {
+ // check special cases of byte2
+ return false;
+ }
+
+ } else {
+ // four-byte form
+
+ if (index >= size) {
+ // fail if we run out of bytes
+ return false;
+ }
+ int byte4 = byteString.byteAt(index++) & 0xFF;
+ if (byte4 < 0x80 || byte4 > 0xBF) {
+ // general trail-byte test
+ return false;
+ }
+ // The following has an extra test, but not worth restructuring
+ if (byte1 == 0xF0 && byte2 < 0x90 ||
+ byte1 == 0xF4 && byte2 > 0x8F) {
+ // check special cases of byte2
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Interface for an enum value or value descriptor, to be used in FieldSet.
+ * The lite library stores enum values directly in FieldSets but the full
+ * library stores EnumValueDescriptors in order to better support reflection.
+ */
+ public interface EnumLite {
+ int getNumber();
+ }
+
+ /**
+ * Interface for an object which maps integers to {@link EnumLite}s.
+ * {@link Descriptors.EnumDescriptor} implements this interface by mapping
+ * numbers to {@link Descriptors.EnumValueDescriptor}s. Additionally,
+ * every generated enum type has a static method internalGetValueMap() which
+ * returns an implementation of this type that maps numbers to enum values.
+ */
+ public interface EnumLiteMap<T extends EnumLite> {
+ T findValueByNumber(int number);
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
new file mode 100644
index 0000000..90f7ffb
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
@@ -0,0 +1,93 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a protocol message being parsed is invalid in some way,
+ * e.g. it contains a malformed varint or a negative byte length.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class InvalidProtocolBufferException extends IOException {
+ private static final long serialVersionUID = -1616151763072450476L;
+
+ public InvalidProtocolBufferException(final String description) {
+ super(description);
+ }
+
+ static InvalidProtocolBufferException truncatedMessage() {
+ return new InvalidProtocolBufferException(
+ "While parsing a protocol message, the input ended unexpectedly " +
+ "in the middle of a field. This could mean either than the " +
+ "input has been truncated or that an embedded message " +
+ "misreported its own length.");
+ }
+
+ static InvalidProtocolBufferException negativeSize() {
+ return new InvalidProtocolBufferException(
+ "CodedInputStream encountered an embedded string or message " +
+ "which claimed to have negative size.");
+ }
+
+ static InvalidProtocolBufferException malformedVarint() {
+ return new InvalidProtocolBufferException(
+ "CodedInputStream encountered a malformed varint.");
+ }
+
+ static InvalidProtocolBufferException invalidTag() {
+ return new InvalidProtocolBufferException(
+ "Protocol message contained an invalid tag (zero).");
+ }
+
+ static InvalidProtocolBufferException invalidEndTag() {
+ return new InvalidProtocolBufferException(
+ "Protocol message end-group tag did not match expected tag.");
+ }
+
+ static InvalidProtocolBufferException invalidWireType() {
+ return new InvalidProtocolBufferException(
+ "Protocol message tag had invalid wire type.");
+ }
+
+ static InvalidProtocolBufferException recursionLimitExceeded() {
+ return new InvalidProtocolBufferException(
+ "Protocol message had too many levels of nesting. May be malicious. " +
+ "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
+ }
+
+ static InvalidProtocolBufferException sizeLimitExceeded() {
+ return new InvalidProtocolBufferException(
+ "Protocol message was too large. May be malicious. " +
+ "Use CodedInputStream.setSizeLimit() to increase the size limit.");
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/LazyStringArrayList.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/LazyStringArrayList.java
new file mode 100644
index 0000000..1683a64
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/LazyStringArrayList.java
@@ -0,0 +1,155 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.List;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.RandomAccess;
+import java.util.Collection;
+
+/**
+ * An implementation of {@link LazyStringList} that wraps an ArrayList. Each
+ * element is either a ByteString or a String. It caches the last one requested
+ * which is most likely the one needed next. This minimizes memory usage while
+ * satisfying the most common use cases.
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong>
+ * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
+ * and at least one of the threads modifies the list structurally, it
+ * <i>must</i> be synchronized externally. (A structural modification is
+ * any operation that adds or deletes one or more elements, or explicitly
+ * resizes the backing array; merely setting the value of an element is not
+ * a structural modification.) This is typically accomplished by
+ * synchronizing on some object that naturally encapsulates the list.
+ * <p>
+ * If the implementation is accessed via concurrent reads, this is thread safe.
+ * Conversions are done in a thread safe manner. It's possible that the
+ * conversion may happen more than once if two threads attempt to access the
+ * same element and the modifications were not visible to each other, but this
+ * will not result in any corruption of the list or change in behavior other
+ * than performance.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringArrayList extends AbstractList<String>
+ implements LazyStringList, RandomAccess {
+
+ public final static LazyStringList EMPTY = new UnmodifiableLazyStringList(
+ new LazyStringArrayList());
+
+ private final List<Object> list;
+
+ public LazyStringArrayList() {
+ list = new ArrayList<Object>();
+ }
+
+ public LazyStringArrayList(List<String> from) {
+ list = new ArrayList<Object>(from);
+ }
+
+ @Override
+ public String get(int index) {
+ Object o = list.get(index);
+ if (o instanceof String) {
+ return (String) o;
+ } else {
+ ByteString bs = (ByteString) o;
+ String s = bs.toStringUtf8();
+ if (Internal.isValidUtf8(bs)) {
+ list.set(index, s);
+ }
+ return s;
+ }
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public String set(int index, String s) {
+ Object o = list.set(index, s);
+ return asString(o);
+ }
+
+ @Override
+ public void add(int index, String element) {
+ list.add(index, element);
+ modCount++;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends String> c) {
+ boolean ret = list.addAll(index, c);
+ modCount++;
+ return ret;
+ }
+
+ @Override
+ public String remove(int index) {
+ Object o = list.remove(index);
+ modCount++;
+ return asString(o);
+ }
+
+ public void clear() {
+ list.clear();
+ modCount++;
+ }
+
+ // @Override
+ public void add(ByteString element) {
+ list.add(element);
+ modCount++;
+ }
+
+ // @Override
+ public ByteString getByteString(int index) {
+ Object o = list.get(index);
+ if (o instanceof String) {
+ ByteString b = ByteString.copyFromUtf8((String) o);
+ list.set(index, b);
+ return b;
+ } else {
+ return (ByteString) o;
+ }
+ }
+
+ private String asString(Object o) {
+ if (o instanceof String) {
+ return (String) o;
+ } else {
+ return ((ByteString) o).toStringUtf8();
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/LazyStringList.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/LazyStringList.java
new file mode 100644
index 0000000..97139ca
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/LazyStringList.java
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.List;
+
+/**
+ * An interface extending List<String> that also provides access to the
+ * items of the list as UTF8-encoded ByteString objects. This is used by the
+ * protocol buffer implementation to support lazily converting bytes parsed
+ * over the wire to String objects until needed and also increases the
+ * efficiency of serialization if the String was never requested as the
+ * ByteString is already cached.
+ * <p>
+ * This only adds additional methods that are required for the use in the
+ * protocol buffer code in order to be able successfuly round trip byte arrays
+ * through parsing and serialization without conversion to strings. It's not
+ * attempting to support the functionality of say List<ByteString>, hence
+ * why only these two very specific methods are added.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public interface LazyStringList extends List<String> {
+
+ /**
+ * Returns the element at the specified position in this list as a ByteString.
+ *
+ * @param index index of the element to return
+ * @return the element at the specified position in this list
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * (<tt>index < 0 || index >= size()</tt>)
+ */
+ ByteString getByteString(int index);
+
+ /**
+ * Appends the specified element to the end of this list (optional
+ * operation).
+ *
+ * @param element element to be appended to this list
+ * @throws UnsupportedOperationException if the <tt>add</tt> operation
+ * is not supported by this list
+ */
+ void add(ByteString element);
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Message.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Message.java
new file mode 100644
index 0000000..67c4148
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Message.java
@@ -0,0 +1,215 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// TODO(kenton): Use generics? E.g. Builder<BuilderType extends Builder>, then
+// mergeFrom*() could return BuilderType for better type-safety.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * Abstract interface implemented by Protocol Message objects.
+ * <p>
+ * See also {@link MessageLite}, which defines most of the methods that typical
+ * users care about. {@link Message} adds to it methods that are not available
+ * in the "lite" runtime. The biggest added features are introspection and
+ * reflection -- i.e., getting descriptors for the message type and accessing
+ * the field values dynamically.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface Message extends MessageLite, MessageOrBuilder {
+
+ // -----------------------------------------------------------------
+ // Comparison and hashing
+
+ /**
+ * Compares the specified object with this message for equality. Returns
+ * <tt>true</tt> if the given object is a message of the same type (as
+ * defined by {@code getDescriptorForType()}) and has identical values for
+ * all of its fields. Subclasses must implement this; inheriting
+ * {@code Object.equals()} is incorrect.
+ *
+ * @param other object to be compared for equality with this message
+ * @return <tt>true</tt> if the specified object is equal to this message
+ */
+ @Override
+ boolean equals(Object other);
+
+ /**
+ * Returns the hash code value for this message. The hash code of a message
+ * should mix the message's type (object identity of the decsriptor) with its
+ * contents (known and unknown field values). Subclasses must implement this;
+ * inheriting {@code Object.hashCode()} is incorrect.
+ *
+ * @return the hash code value for this message
+ * @see Map#hashCode()
+ */
+ @Override
+ int hashCode();
+
+ // -----------------------------------------------------------------
+ // Convenience methods.
+
+ /**
+ * Converts the message to a string in protocol buffer text format. This is
+ * just a trivial wrapper around {@link TextFormat#printToString(Message)}.
+ */
+ @Override
+ String toString();
+
+ // =================================================================
+ // Builders
+
+ // (From MessageLite, re-declared here only for return type covariance.)
+ Builder newBuilderForType();
+ Builder toBuilder();
+
+ /**
+ * Abstract interface implemented by Protocol Message builders.
+ */
+ interface Builder extends MessageLite.Builder, MessageOrBuilder {
+ // (From MessageLite.Builder, re-declared here only for return type
+ // covariance.)
+ Builder clear();
+
+ /**
+ * Merge {@code other} into the message being built. {@code other} must
+ * have the exact same type as {@code this} (i.e.
+ * {@code getDescriptorForType() == other.getDescriptorForType()}).
+ *
+ * Merging occurs as follows. For each field:<br>
+ * * For singular primitive fields, if the field is set in {@code other},
+ * then {@code other}'s value overwrites the value in this message.<br>
+ * * For singular message fields, if the field is set in {@code other},
+ * it is merged into the corresponding sub-message of this message
+ * using the same merging rules.<br>
+ * * For repeated fields, the elements in {@code other} are concatenated
+ * with the elements in this message.
+ *
+ * This is equivalent to the {@code Message::MergeFrom} method in C++.
+ */
+ Builder mergeFrom(Message other);
+
+ // (From MessageLite.Builder, re-declared here only for return type
+ // covariance.)
+ Message build();
+ Message buildPartial();
+ Builder clone();
+ Builder mergeFrom(CodedInputStream input) throws IOException;
+ Builder mergeFrom(CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws IOException;
+
+ /**
+ * Get the message's type's descriptor.
+ * See {@link Message#getDescriptorForType()}.
+ */
+ Descriptors.Descriptor getDescriptorForType();
+
+ /**
+ * Create a Builder for messages of the appropriate type for the given
+ * field. Messages built with this can then be passed to setField(),
+ * setRepeatedField(), or addRepeatedField().
+ */
+ Builder newBuilderForField(Descriptors.FieldDescriptor field);
+
+ /**
+ * Sets a field to the given value. The value must be of the correct type
+ * for this field, i.e. the same type that
+ * {@link Message#getField(Descriptors.FieldDescriptor)} would return.
+ */
+ Builder setField(Descriptors.FieldDescriptor field, Object value);
+
+ /**
+ * Clears the field. This is exactly equivalent to calling the generated
+ * "clear" accessor method corresponding to the field.
+ */
+ Builder clearField(Descriptors.FieldDescriptor field);
+
+ /**
+ * Sets an element of a repeated field to the given value. The value must
+ * be of the correct type for this field, i.e. the same type that
+ * {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)} would
+ * return.
+ * @throws IllegalArgumentException The field is not a repeated field, or
+ * {@code field.getContainingType() != getDescriptorForType()}.
+ */
+ Builder setRepeatedField(Descriptors.FieldDescriptor field,
+ int index, Object value);
+
+ /**
+ * Like {@code setRepeatedField}, but appends the value as a new element.
+ * @throws IllegalArgumentException The field is not a repeated field, or
+ * {@code field.getContainingType() != getDescriptorForType()}.
+ */
+ Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value);
+
+ /** Set the {@link UnknownFieldSet} for this message. */
+ Builder setUnknownFields(UnknownFieldSet unknownFields);
+
+ /**
+ * Merge some unknown fields into the {@link UnknownFieldSet} for this
+ * message.
+ */
+ Builder mergeUnknownFields(UnknownFieldSet unknownFields);
+
+ // ---------------------------------------------------------------
+ // Convenience methods.
+
+ // (From MessageLite.Builder, re-declared here only for return type
+ // covariance.)
+ Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
+ Builder mergeFrom(ByteString data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+ Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
+ Builder mergeFrom(byte[] data, int off, int len)
+ throws InvalidProtocolBufferException;
+ Builder mergeFrom(byte[] data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+ Builder mergeFrom(byte[] data, int off, int len,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+ Builder mergeFrom(InputStream input) throws IOException;
+ Builder mergeFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws IOException;
+ boolean mergeDelimitedFrom(InputStream input)
+ throws IOException;
+ boolean mergeDelimitedFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws IOException;
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageLite.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageLite.java
new file mode 100644
index 0000000..31b8256
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageLite.java
@@ -0,0 +1,325 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// TODO(kenton): Use generics? E.g. Builder<BuilderType extends Builder>, then
+// mergeFrom*() could return BuilderType for better type-safety.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Abstract interface implemented by Protocol Message objects.
+ *
+ * <p>This interface is implemented by all protocol message objects. Non-lite
+ * messages additionally implement the Message interface, which is a subclass
+ * of MessageLite. Use MessageLite instead when you only need the subset of
+ * features which it supports -- namely, nothing that uses descriptors or
+ * reflection. You can instruct the protocol compiler to generate classes
+ * which implement only MessageLite, not the full Message interface, by adding
+ * the follow line to the .proto file:
+ * <pre>
+ * option optimize_for = LITE_RUNTIME;
+ * </pre>
+ *
+ * <p>This is particularly useful on resource-constrained systems where the
+ * full protocol buffers runtime library is too big.
+ *
+ * <p>Note that on non-constrained systems (e.g. servers) when you need to link
+ * in lots of protocol definitions, a better way to reduce total code footprint
+ * is to use {@code optimize_for = CODE_SIZE}. This will make the generated
+ * code smaller while still supporting all the same features (at the expense of
+ * speed). {@code optimize_for = LITE_RUNTIME} is best when you only have a
+ * small number of message types linked into your binary, in which case the
+ * size of the protocol buffers runtime itself is the biggest problem.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface MessageLite extends MessageLiteOrBuilder {
+
+
+ /**
+ * Serializes the message and writes it to {@code output}. This does not
+ * flush or close the stream.
+ */
+ void writeTo(CodedOutputStream output) throws IOException;
+
+ /**
+ * Get the number of bytes required to encode this message. The result
+ * is only computed on the first call and memoized after that.
+ */
+ int getSerializedSize();
+
+ // -----------------------------------------------------------------
+ // Convenience methods.
+
+ /**
+ * Serializes the message to a {@code ByteString} and returns it. This is
+ * just a trivial wrapper around
+ * {@link #writeTo(CodedOutputStream)}.
+ */
+ ByteString toByteString();
+
+ /**
+ * Serializes the message to a {@code byte} array and returns it. This is
+ * just a trivial wrapper around
+ * {@link #writeTo(CodedOutputStream)}.
+ */
+ byte[] toByteArray();
+
+ /**
+ * Serializes the message and writes it to {@code output}. This is just a
+ * trivial wrapper around {@link #writeTo(CodedOutputStream)}. This does
+ * not flush or close the stream.
+ * <p>
+ * NOTE: Protocol Buffers are not self-delimiting. Therefore, if you write
+ * any more data to the stream after the message, you must somehow ensure
+ * that the parser on the receiving end does not interpret this as being
+ * part of the protocol message. This can be done e.g. by writing the size
+ * of the message before the data, then making sure to limit the input to
+ * that size on the receiving end (e.g. by wrapping the InputStream in one
+ * which limits the input). Alternatively, just use
+ * {@link #writeDelimitedTo(OutputStream)}.
+ */
+ void writeTo(OutputStream output) throws IOException;
+
+ /**
+ * Like {@link #writeTo(OutputStream)}, but writes the size of the message
+ * as a varint before writing the data. This allows more data to be written
+ * to the stream after the message without the need to delimit the message
+ * data yourself. Use {@link Builder#mergeDelimitedFrom(InputStream)} (or
+ * the static method {@code YourMessageType.parseDelimitedFrom(InputStream)})
+ * to parse messages written by this method.
+ */
+ void writeDelimitedTo(OutputStream output) throws IOException;
+
+ // =================================================================
+ // Builders
+
+ /**
+ * Constructs a new builder for a message of the same type as this message.
+ */
+ Builder newBuilderForType();
+
+ /**
+ * Constructs a builder initialized with the current message. Use this to
+ * derive a new message from the current one.
+ */
+ Builder toBuilder();
+
+ /**
+ * Abstract interface implemented by Protocol Message builders.
+ */
+ interface Builder extends MessageLiteOrBuilder, Cloneable {
+ /** Resets all fields to their default values. */
+ Builder clear();
+
+ /**
+ * Construct the final message. Once this is called, the Builder is no
+ * longer valid, and calling any other method will result in undefined
+ * behavior and may throw a NullPointerException. If you need to continue
+ * working with the builder after calling {@code build()}, {@code clone()}
+ * it first.
+ * @throws UninitializedMessageException The message is missing one or more
+ * required fields (i.e. {@link #isInitialized()} returns false).
+ * Use {@link #buildPartial()} to bypass this check.
+ */
+ MessageLite build();
+
+ /**
+ * Like {@link #build()}, but does not throw an exception if the message
+ * is missing required fields. Instead, a partial message is returned.
+ * Once this is called, the Builder is no longer valid, and calling any
+ * will result in undefined behavior and may throw a NullPointerException.
+ *
+ * If you need to continue working with the builder after calling
+ * {@code buildPartial()}, {@code clone()} it first.
+ */
+ MessageLite buildPartial();
+
+ /**
+ * Clones the Builder.
+ * @see Object#clone()
+ */
+ Builder clone();
+
+ /**
+ * Parses a message of this type from the input and merges it with this
+ * message, as if using {@link Builder#mergeFrom(MessageLite)}.
+ *
+ * <p>Warning: This does not verify that all required fields are present in
+ * the input message. If you call {@link #build()} without setting all
+ * required fields, it will throw an {@link UninitializedMessageException},
+ * which is a {@code RuntimeException} and thus might not be caught. There
+ * are a few good ways to deal with this:
+ * <ul>
+ * <li>Call {@link #isInitialized()} to verify that all required fields
+ * are set before building.
+ * <li>Parse the message separately using one of the static
+ * {@code parseFrom} methods, then use {@link #mergeFrom(MessageLite)}
+ * to merge it with this one. {@code parseFrom} will throw an
+ * {@link InvalidProtocolBufferException} (an {@code IOException})
+ * if some required fields are missing.
+ * <li>Use {@code buildPartial()} to build, which ignores missing
+ * required fields.
+ * </ul>
+ *
+ * <p>Note: The caller should call
+ * {@link CodedInputStream#checkLastTagWas(int)} after calling this to
+ * verify that the last tag seen was the appropriate end-group tag,
+ * or zero for EOF.
+ */
+ Builder mergeFrom(CodedInputStream input) throws IOException;
+
+ /**
+ * Like {@link Builder#mergeFrom(CodedInputStream)}, but also
+ * parses extensions. The extensions that you want to be able to parse
+ * must be registered in {@code extensionRegistry}. Extensions not in
+ * the registry will be treated as unknown fields.
+ */
+ Builder mergeFrom(CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws IOException;
+
+ // ---------------------------------------------------------------
+ // Convenience methods.
+
+ /**
+ * Parse {@code data} as a message of this type and merge it with the
+ * message being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream)}.
+ *
+ * @return this
+ */
+ Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
+
+ /**
+ * Parse {@code data} as a message of this type and merge it with the
+ * message being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
+ *
+ * @return this
+ */
+ Builder mergeFrom(ByteString data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parse {@code data} as a message of this type and merge it with the
+ * message being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream)}.
+ *
+ * @return this
+ */
+ Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
+
+ /**
+ * Parse {@code data} as a message of this type and merge it with the
+ * message being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream)}.
+ *
+ * @return this
+ */
+ Builder mergeFrom(byte[] data, int off, int len)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parse {@code data} as a message of this type and merge it with the
+ * message being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
+ *
+ * @return this
+ */
+ Builder mergeFrom(byte[] data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parse {@code data} as a message of this type and merge it with the
+ * message being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
+ *
+ * @return this
+ */
+ Builder mergeFrom(byte[] data, int off, int len,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException;
+
+ /**
+ * Parse a message of this type from {@code input} and merge it with the
+ * message being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream)}. Note that this method always
+ * reads the <i>entire</i> input (unless it throws an exception). If you
+ * want it to stop earlier, you will need to wrap your input in some
+ * wrapper stream that limits reading. Or, use
+ * {@link MessageLite#writeDelimitedTo(OutputStream)} to write your message
+ * and {@link #mergeDelimitedFrom(InputStream)} to read it.
+ * <p>
+ * Despite usually reading the entire input, this does not close the stream.
+ *
+ * @return this
+ */
+ Builder mergeFrom(InputStream input) throws IOException;
+
+ /**
+ * Parse a message of this type from {@code input} and merge it with the
+ * message being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream,ExtensionRegistry)}.
+ *
+ * @return this
+ */
+ Builder mergeFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws IOException;
+
+ /**
+ * Like {@link #mergeFrom(InputStream)}, but does not read until EOF.
+ * Instead, the size of the message (encoded as a varint) is read first,
+ * then the message data. Use
+ * {@link MessageLite#writeDelimitedTo(OutputStream)} to write messages in
+ * this format.
+ *
+ * @returns True if successful, or false if the stream is at EOF when the
+ * method starts. Any other error (including reaching EOF during
+ * parsing) will cause an exception to be thrown.
+ */
+ boolean mergeDelimitedFrom(InputStream input)
+ throws IOException;
+
+ /**
+ * Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions.
+ */
+ boolean mergeDelimitedFrom(InputStream input,
+ ExtensionRegistryLite extensionRegistry)
+ throws IOException;
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
new file mode 100644
index 0000000..7cc72e9
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Base interface for methods common to {@link MessageLite}
+ * and {@link MessageLite.Builder} to provide type equivalency.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public interface MessageLiteOrBuilder {
+ /**
+ * Get an instance of the type with no fields set. Because no fields are set,
+ * all getters for singular fields will return default values and repeated
+ * fields will appear empty.
+ * This may or may not be a singleton. This differs from the
+ * {@code getDefaultInstance()} method of generated message classes in that
+ * this method is an abstract method of the {@code MessageLite} interface
+ * whereas {@code getDefaultInstance()} is a static method of a specific
+ * class. They return the same thing.
+ */
+ MessageLite getDefaultInstanceForType();
+
+ /**
+ * Returns true if all required fields in the message and all embedded
+ * messages are set, false otherwise.
+ */
+ boolean isInitialized();
+
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageOrBuilder.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageOrBuilder.java
new file mode 100644
index 0000000..0132e7c
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageOrBuilder.java
@@ -0,0 +1,110 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.Map;
+
+/**
+ * Base interface for methods common to {@link Message} and
+ * {@link Message.Builder} to provide type equivalency.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public interface MessageOrBuilder extends MessageLiteOrBuilder {
+
+ // (From MessageLite, re-declared here only for return type covariance.)
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ Message getDefaultInstanceForType();
+
+ /**
+ * Get the message's type's descriptor. This differs from the
+ * {@code getDescriptor()} method of generated message classes in that
+ * this method is an abstract method of the {@code Message} interface
+ * whereas {@code getDescriptor()} is a static method of a specific class.
+ * They return the same thing.
+ */
+ Descriptors.Descriptor getDescriptorForType();
+
+ /**
+ * Returns a collection of all the fields in this message which are set
+ * and their corresponding values. A singular ("required" or "optional")
+ * field is set iff hasField() returns true for that field. A "repeated"
+ * field is set iff getRepeatedFieldSize() is greater than zero. The
+ * values are exactly what would be returned by calling
+ * {@link #getField(Descriptors.FieldDescriptor)} for each field. The map
+ * is guaranteed to be a sorted map, so iterating over it will return fields
+ * in order by field number.
+ * <br>
+ * If this is for a builder, the returned map may or may not reflect future
+ * changes to the builder. Either way, the returned map is itself
+ * unmodifiable.
+ */
+ Map<Descriptors.FieldDescriptor, Object> getAllFields();
+
+ /**
+ * Returns true if the given field is set. This is exactly equivalent to
+ * calling the generated "has" accessor method corresponding to the field.
+ * @throws IllegalArgumentException The field is a repeated field, or
+ * {@code field.getContainingType() != getDescriptorForType()}.
+ */
+ boolean hasField(Descriptors.FieldDescriptor field);
+
+ /**
+ * Obtains the value of the given field, or the default value if it is
+ * not set. For primitive fields, the boxed primitive value is returned.
+ * For enum fields, the EnumValueDescriptor for the value is returend. For
+ * embedded message fields, the sub-message is returned. For repeated
+ * fields, a java.util.List is returned.
+ */
+ Object getField(Descriptors.FieldDescriptor field);
+
+ /**
+ * Gets the number of elements of a repeated field. This is exactly
+ * equivalent to calling the generated "Count" accessor method corresponding
+ * to the field.
+ * @throws IllegalArgumentException The field is not a repeated field, or
+ * {@code field.getContainingType() != getDescriptorForType()}.
+ */
+ int getRepeatedFieldCount(Descriptors.FieldDescriptor field);
+
+ /**
+ * Gets an element of a repeated field. For primitive fields, the boxed
+ * primitive value is returned. For enum fields, the EnumValueDescriptor
+ * for the value is returend. For embedded message fields, the sub-message
+ * is returned.
+ * @throws IllegalArgumentException The field is not a repeated field, or
+ * {@code field.getContainingType() != getDescriptorForType()}.
+ */
+ Object getRepeatedField(Descriptors.FieldDescriptor field, int index);
+
+ /** Get the {@link UnknownFieldSet} for this message. */
+ UnknownFieldSet getUnknownFields();
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
new file mode 100644
index 0000000..112400f
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+
+/**
+ * Interface of useful methods added to all enums generated by the protocol
+ * compiler.
+ */
+public interface ProtocolMessageEnum extends Internal.EnumLite {
+
+ /**
+ * Return the value's numeric value as defined in the .proto file.
+ */
+ int getNumber();
+
+ /**
+ * Return the value's descriptor, which contains information such as
+ * value name, number, and type.
+ */
+ EnumValueDescriptor getValueDescriptor();
+
+ /**
+ * Return the enum type's descriptor, which contains information
+ * about each defined value, etc.
+ */
+ EnumDescriptor getDescriptorForType();
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
new file mode 100644
index 0000000..0024f79
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
@@ -0,0 +1,696 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <code>RepeatedFieldBuilder</code> implements a structure that a protocol
+ * message uses to hold a repeated field of other protocol messages. It supports
+ * the classical use case of adding immutable {@link Message}'s to the
+ * repeated field and is highly optimized around this (no extra memory
+ * allocations and sharing of immutable arrays).
+ * <br>
+ * It also supports the additional use case of adding a {@link Message.Builder}
+ * to the repeated field and deferring conversion of that <code>Builder</code>
+ * to an immutable <code>Message</code>. In this way, it's possible to maintain
+ * a tree of <code>Builder</code>'s that acts as a fully read/write data
+ * structure.
+ * <br>
+ * Logically, one can think of a tree of builders as converting the entire tree
+ * to messages when build is called on the root or when any method is called
+ * that desires a Message instead of a Builder. In terms of the implementation,
+ * the <code>SingleFieldBuilder</code> and <code>RepeatedFieldBuilder</code>
+ * classes cache messages that were created so that messages only need to be
+ * created when some change occured in its builder or a builder for one of its
+ * descendants.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class RepeatedFieldBuilder
+ <MType extends GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ implements GeneratedMessage.BuilderParent {
+
+ // Parent to send changes to.
+ private GeneratedMessage.BuilderParent parent;
+
+ // List of messages. Never null. It may be immutable, in which case
+ // isMessagesListImmutable will be true. See note below.
+ private List<MType> messages;
+
+ // Whether messages is an mutable array that can be modified.
+ private boolean isMessagesListMutable;
+
+ // List of builders. May be null, in which case, no nested builders were
+ // created. If not null, entries represent the builder for that index.
+ private List<SingleFieldBuilder<MType, BType, IType>> builders;
+
+ // Here are the invariants for messages and builders:
+ // 1. messages is never null and its count corresponds to the number of items
+ // in the repeated field.
+ // 2. If builders is non-null, messages and builders MUST always
+ // contain the same number of items.
+ // 3. Entries in either array can be null, but for any index, there MUST be
+ // either a Message in messages or a builder in builders.
+ // 4. If the builder at an index is non-null, the builder is
+ // authoritative. This is the case where a Builder was set on the index.
+ // Any message in the messages array MUST be ignored.
+ // t. If the builder at an index is null, the message in the messages
+ // list is authoritative. This is the case where a Message (not a Builder)
+ // was set directly for an index.
+
+ // Indicates that we've built a message and so we are now obligated
+ // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
+ private boolean isClean;
+
+ // A view of this builder that exposes a List interface of messages. This is
+ // initialized on demand. This is fully backed by this object and all changes
+ // are reflected in it. Access to any item converts it to a message if it
+ // was a builder.
+ private MessageExternalList<MType, BType, IType> externalMessageList;
+
+ // A view of this builder that exposes a List interface of builders. This is
+ // initialized on demand. This is fully backed by this object and all changes
+ // are reflected in it. Access to any item converts it to a builder if it
+ // was a message.
+ private BuilderExternalList<MType, BType, IType> externalBuilderList;
+
+ // A view of this builder that exposes a List interface of the interface
+ // implemented by messages and builders. This is initialized on demand. This
+ // is fully backed by this object and all changes are reflected in it.
+ // Access to any item returns either a builder or message depending on
+ // what is most efficient.
+ private MessageOrBuilderExternalList<MType, BType, IType>
+ externalMessageOrBuilderList;
+
+ /**
+ * Constructs a new builder with an empty list of messages.
+ *
+ * @param messages the current list of messages
+ * @param isMessagesListMutable Whether the messages list is mutable
+ * @param parent a listener to notify of changes
+ * @param isClean whether the builder is initially marked clean
+ */
+ public RepeatedFieldBuilder(
+ List<MType> messages,
+ boolean isMessagesListMutable,
+ GeneratedMessage.BuilderParent parent,
+ boolean isClean) {
+ this.messages = messages;
+ this.isMessagesListMutable = isMessagesListMutable;
+ this.parent = parent;
+ this.isClean = isClean;
+ }
+
+ public void dispose() {
+ // Null out parent so we stop sending it invalidations.
+ parent = null;
+ }
+
+ /**
+ * Ensures that the list of messages is mutable so it can be updated. If it's
+ * immutable, a copy is made.
+ */
+ private void ensureMutableMessageList() {
+ if (!isMessagesListMutable) {
+ messages = new ArrayList<MType>(messages);
+ isMessagesListMutable = true;
+ }
+ }
+
+ /**
+ * Ensures that the list of builders is not null. If it's null, the list is
+ * created and initialized to be the same size as the messages list with
+ * null entries.
+ */
+ private void ensureBuilders() {
+ if (this.builders == null) {
+ this.builders =
+ new ArrayList<SingleFieldBuilder<MType, BType, IType>>(
+ messages.size());
+ for (int i = 0; i < messages.size(); i++) {
+ builders.add(null);
+ }
+ }
+ }
+
+ /**
+ * Gets the count of items in the list.
+ *
+ * @return the count of items in the list.
+ */
+ public int getCount() {
+ return messages.size();
+ }
+
+ /**
+ * Gets whether the list is empty.
+ *
+ * @return whether the list is empty
+ */
+ public boolean isEmpty() {
+ return messages.isEmpty();
+ }
+
+ /**
+ * Get the message at the specified index. If the message is currently stored
+ * as a <code>Builder</code>, it is converted to a <code>Message</code> by
+ * calling {@link Message.Builder#buildPartial} on it.
+ *
+ * @param index the index of the message to get
+ * @return the message for the specified index
+ */
+ public MType getMessage(int index) {
+ return getMessage(index, false);
+ }
+
+ /**
+ * Get the message at the specified index. If the message is currently stored
+ * as a <code>Builder</code>, it is converted to a <code>Message</code> by
+ * calling {@link Message.Builder#buildPartial} on it.
+ *
+ * @param index the index of the message to get
+ * @param forBuild this is being called for build so we want to make sure
+ * we SingleFieldBuilder.build to send dirty invalidations
+ * @return the message for the specified index
+ */
+ private MType getMessage(int index, boolean forBuild) {
+ if (this.builders == null) {
+ // We don't have any builders -- return the current Message.
+ // This is the case where no builder was created, so we MUST have a
+ // Message.
+ return messages.get(index);
+ }
+
+ SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
+ if (builder == null) {
+ // We don't have a builder -- return the current message.
+ // This is the case where no builder was created for the entry at index,
+ // so we MUST have a message.
+ return messages.get(index);
+
+ } else {
+ return forBuild ? builder.build() : builder.getMessage();
+ }
+ }
+
+ /**
+ * Gets a builder for the specified index. If no builder has been created for
+ * that index, a builder is created on demand by calling
+ * {@link Message#toBuilder}.
+ *
+ * @param index the index of the message to get
+ * @return The builder for that index
+ */
+ public BType getBuilder(int index) {
+ ensureBuilders();
+ SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
+ if (builder == null) {
+ MType message = messages.get(index);
+ builder = new SingleFieldBuilder<MType, BType, IType>(
+ message, this, isClean);
+ builders.set(index, builder);
+ }
+ return builder.getBuilder();
+ }
+
+ /**
+ * Gets the base class interface for the specified index. This may either be
+ * a builder or a message. It will return whatever is more efficient.
+ *
+ * @param index the index of the message to get
+ * @return the message or builder for the index as the base class interface
+ */
+ @SuppressWarnings("unchecked")
+ public IType getMessageOrBuilder(int index) {
+ if (this.builders == null) {
+ // We don't have any builders -- return the current Message.
+ // This is the case where no builder was created, so we MUST have a
+ // Message.
+ return (IType) messages.get(index);
+ }
+
+ SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
+ if (builder == null) {
+ // We don't have a builder -- return the current message.
+ // This is the case where no builder was created for the entry at index,
+ // so we MUST have a message.
+ return (IType) messages.get(index);
+
+ } else {
+ return builder.getMessageOrBuilder();
+ }
+ }
+
+ /**
+ * Sets a message at the specified index replacing the existing item at
+ * that index.
+ *
+ * @param index the index to set.
+ * @param message the message to set
+ * @return the builder
+ */
+ public RepeatedFieldBuilder<MType, BType, IType> setMessage(
+ int index, MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ ensureMutableMessageList();
+ messages.set(index, message);
+ if (builders != null) {
+ SingleFieldBuilder<MType, BType, IType> entry =
+ builders.set(index, null);
+ if (entry != null) {
+ entry.dispose();
+ }
+ }
+ onChanged();
+ incrementModCounts();
+ return this;
+ }
+
+ /**
+ * Appends the specified element to the end of this list.
+ *
+ * @param message the message to add
+ * @return the builder
+ */
+ public RepeatedFieldBuilder<MType, BType, IType> addMessage(
+ MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ ensureMutableMessageList();
+ messages.add(message);
+ if (builders != null) {
+ builders.add(null);
+ }
+ onChanged();
+ incrementModCounts();
+ return this;
+ }
+
+ /**
+ * Inserts the specified message at the specified position in this list.
+ * Shifts the element currently at that position (if any) and any subsequent
+ * elements to the right (adds one to their indices).
+ *
+ * @param index the index at which to insert the message
+ * @param message the message to add
+ * @return the builder
+ */
+ public RepeatedFieldBuilder<MType, BType, IType> addMessage(
+ int index, MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ ensureMutableMessageList();
+ messages.add(index, message);
+ if (builders != null) {
+ builders.add(index, null);
+ }
+ onChanged();
+ incrementModCounts();
+ return this;
+ }
+
+ /**
+ * Appends all of the messages in the specified collection to the end of
+ * this list, in the order that they are returned by the specified
+ * collection's iterator.
+ *
+ * @param values the messages to add
+ * @return the builder
+ */
+ public RepeatedFieldBuilder<MType, BType, IType> addAllMessages(
+ Iterable<? extends MType> values) {
+ for (final MType value : values) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ }
+ if (values instanceof Collection) {
+ @SuppressWarnings("unchecked") final
+ Collection<MType> collection = (Collection<MType>) values;
+ if (collection.size() == 0) {
+ return this;
+ }
+ ensureMutableMessageList();
+ for (MType value : values) {
+ addMessage(value);
+ }
+ } else {
+ ensureMutableMessageList();
+ for (MType value : values) {
+ addMessage(value);
+ }
+ }
+ onChanged();
+ incrementModCounts();
+ return this;
+ }
+
+ /**
+ * Appends a new builder to the end of this list and returns the builder.
+ *
+ * @param message the message to add which is the basis of the builder
+ * @return the new builder
+ */
+ public BType addBuilder(MType message) {
+ ensureMutableMessageList();
+ ensureBuilders();
+ SingleFieldBuilder<MType, BType, IType> builder =
+ new SingleFieldBuilder<MType, BType, IType>(
+ message, this, isClean);
+ messages.add(null);
+ builders.add(builder);
+ onChanged();
+ incrementModCounts();
+ return builder.getBuilder();
+ }
+
+ /**
+ * Inserts a new builder at the specified position in this list.
+ * Shifts the element currently at that position (if any) and any subsequent
+ * elements to the right (adds one to their indices).
+ *
+ * @param index the index at which to insert the builder
+ * @param message the message to add which is the basis of the builder
+ * @return the builder
+ */
+ public BType addBuilder(int index, MType message) {
+ ensureMutableMessageList();
+ ensureBuilders();
+ SingleFieldBuilder<MType, BType, IType> builder =
+ new SingleFieldBuilder<MType, BType, IType>(
+ message, this, isClean);
+ messages.add(index, null);
+ builders.add(index, builder);
+ onChanged();
+ incrementModCounts();
+ return builder.getBuilder();
+ }
+
+ /**
+ * Removes the element at the specified position in this list. Shifts any
+ * subsequent elements to the left (subtracts one from their indices).
+ * Returns the element that was removed from the list.
+ *
+ * @param index the index at which to remove the message
+ */
+ public void remove(int index) {
+ ensureMutableMessageList();
+ messages.remove(index);
+ if (builders != null) {
+ SingleFieldBuilder<MType, BType, IType> entry =
+ builders.remove(index);
+ if (entry != null) {
+ entry.dispose();
+ }
+ }
+ onChanged();
+ incrementModCounts();
+ }
+
+ /**
+ * Removes all of the elements from this list.
+ * The list will be empty after this call returns.
+ */
+ public void clear() {
+ messages = Collections.emptyList();
+ isMessagesListMutable = false;
+ if (builders != null) {
+ for (SingleFieldBuilder<MType, BType, IType> entry :
+ builders) {
+ if (entry != null) {
+ entry.dispose();
+ }
+ }
+ builders = null;
+ }
+ onChanged();
+ incrementModCounts();
+ }
+
+ /**
+ * Builds the list of messages from the builder and returns them.
+ *
+ * @return an immutable list of messages
+ */
+ public List<MType> build() {
+ // Now that build has been called, we are required to dispatch
+ // invalidations.
+ isClean = true;
+
+ if (!isMessagesListMutable && builders == null) {
+ // We still have an immutable list and we never created a builder.
+ return messages;
+ }
+
+ boolean allMessagesInSync = true;
+ if (!isMessagesListMutable) {
+ // We still have an immutable list. Let's see if any of them are out
+ // of sync with their builders.
+ for (int i = 0; i < messages.size(); i++) {
+ Message message = messages.get(i);
+ SingleFieldBuilder<MType, BType, IType> builder = builders.get(i);
+ if (builder != null) {
+ if (builder.build() != message) {
+ allMessagesInSync = false;
+ break;
+ }
+ }
+ }
+ if (allMessagesInSync) {
+ // Immutable list is still in sync.
+ return messages;
+ }
+ }
+
+ // Need to make sure messages is up to date
+ ensureMutableMessageList();
+ for (int i = 0; i < messages.size(); i++) {
+ messages.set(i, getMessage(i, true));
+ }
+
+ // We're going to return our list as immutable so we mark that we can
+ // no longer update it.
+ messages = Collections.unmodifiableList(messages);
+ isMessagesListMutable = false;
+ return messages;
+ }
+
+ /**
+ * Gets a view of the builder as a list of messages. The returned list is live
+ * and will reflect any changes to the underlying builder.
+ *
+ * @return the messages in the list
+ */
+ public List<MType> getMessageList() {
+ if (externalMessageList == null) {
+ externalMessageList =
+ new MessageExternalList<MType, BType, IType>(this);
+ }
+ return externalMessageList;
+ }
+
+ /**
+ * Gets a view of the builder as a list of builders. This returned list is
+ * live and will reflect any changes to the underlying builder.
+ *
+ * @return the builders in the list
+ */
+ public List<BType> getBuilderList() {
+ if (externalBuilderList == null) {
+ externalBuilderList =
+ new BuilderExternalList<MType, BType, IType>(this);
+ }
+ return externalBuilderList;
+ }
+
+ /**
+ * Gets a view of the builder as a list of MessageOrBuilders. This returned
+ * list is live and will reflect any changes to the underlying builder.
+ *
+ * @return the builders in the list
+ */
+ public List<IType> getMessageOrBuilderList() {
+ if (externalMessageOrBuilderList == null) {
+ externalMessageOrBuilderList =
+ new MessageOrBuilderExternalList<MType, BType, IType>(this);
+ }
+ return externalMessageOrBuilderList;
+ }
+
+ /**
+ * Called when a the builder or one of its nested children has changed
+ * and any parent should be notified of its invalidation.
+ */
+ private void onChanged() {
+ if (isClean && parent != null) {
+ parent.markDirty();
+
+ // Don't keep dispatching invalidations until build is called again.
+ isClean = false;
+ }
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void markDirty() {
+ onChanged();
+ }
+
+ /**
+ * Increments the mod counts so that an ConcurrentModificationException can
+ * be thrown if calling code tries to modify the builder while its iterating
+ * the list.
+ */
+ private void incrementModCounts() {
+ if (externalMessageList != null) {
+ externalMessageList.incrementModCount();
+ }
+ if (externalBuilderList != null) {
+ externalBuilderList.incrementModCount();
+ }
+ if (externalMessageOrBuilderList != null) {
+ externalMessageOrBuilderList.incrementModCount();
+ }
+ }
+
+ /**
+ * Provides a live view of the builder as a list of messages.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ */
+ private static class MessageExternalList<
+ MType extends GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<MType> implements List<MType> {
+
+ RepeatedFieldBuilder<MType, BType, IType> builder;
+
+ MessageExternalList(
+ RepeatedFieldBuilder<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ public MType get(int index) {
+ return builder.getMessage(index);
+ }
+
+ void incrementModCount() {
+ modCount++;
+ }
+ }
+
+ /**
+ * Provides a live view of the builder as a list of builders.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ */
+ private static class BuilderExternalList<
+ MType extends GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<BType> implements List<BType> {
+
+ RepeatedFieldBuilder<MType, BType, IType> builder;
+
+ BuilderExternalList(
+ RepeatedFieldBuilder<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ public BType get(int index) {
+ return builder.getBuilder(index);
+ }
+
+ void incrementModCount() {
+ modCount++;
+ }
+ }
+
+ /**
+ * Provides a live view of the builder as a list of builders.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ */
+ private static class MessageOrBuilderExternalList<
+ MType extends GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ extends AbstractList<IType> implements List<IType> {
+
+ RepeatedFieldBuilder<MType, BType, IType> builder;
+
+ MessageOrBuilderExternalList(
+ RepeatedFieldBuilder<MType, BType, IType> builder) {
+ this.builder = builder;
+ }
+
+ public int size() {
+ return this.builder.getCount();
+ }
+
+ public IType get(int index) {
+ return builder.getMessageOrBuilder(index);
+ }
+
+ void incrementModCount() {
+ modCount++;
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcCallback.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcCallback.java
new file mode 100644
index 0000000..1fd35ed
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcCallback.java
@@ -0,0 +1,47 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Interface for an RPC callback, normally called when an RPC completes.
+ * {@code ParameterType} is normally the method's response message type.
+ *
+ * <p>Starting with version 2.3.0, RPC implementations should not try to build
+ * on this, but should instead provide code generator plugins which generate
+ * code specific to the particular RPC implementation. This way the generated
+ * code can be more appropriate for the implementation in use and can avoid
+ * unnecessary layers of indirection.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface RpcCallback<ParameterType> {
+ void run(ParameterType parameter);
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcChannel.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcChannel.java
new file mode 100644
index 0000000..c6ec54f
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcChannel.java
@@ -0,0 +1,71 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * <p>Abstract interface for an RPC channel. An {@code RpcChannel} represents a
+ * communication line to a {@link Service} which can be used to call that
+ * {@link Service}'s methods. The {@link Service} may be running on another
+ * machine. Normally, you should not call an {@code RpcChannel} directly, but
+ * instead construct a stub {@link Service} wrapping it. Example:
+ *
+ * <pre>
+ * RpcChannel channel = rpcImpl.newChannel("remotehost.example.com:1234");
+ * RpcController controller = rpcImpl.newController();
+ * MyService service = MyService.newStub(channel);
+ * service.myMethod(controller, request, callback);
+ * </pre>
+ *
+ * <p>Starting with version 2.3.0, RPC implementations should not try to build
+ * on this, but should instead provide code generator plugins which generate
+ * code specific to the particular RPC implementation. This way the generated
+ * code can be more appropriate for the implementation in use and can avoid
+ * unnecessary layers of indirection.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface RpcChannel {
+ /**
+ * Call the given method of the remote service. This method is similar to
+ * {@code Service.callMethod()} with one important difference: the caller
+ * decides the types of the {@code Message} objects, not the callee. The
+ * request may be of any type as long as
+ * {@code request.getDescriptor() == method.getInputType()}.
+ * The response passed to the callback will be of the same type as
+ * {@code responsePrototype} (which must have
+ * {@code getDescriptor() == method.getOutputType()}).
+ */
+ void callMethod(Descriptors.MethodDescriptor method,
+ RpcController controller,
+ Message request,
+ Message responsePrototype,
+ RpcCallback<Message> done);
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcController.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcController.java
new file mode 100644
index 0000000..aaa5446
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcController.java
@@ -0,0 +1,118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * <p>An {@code RpcController} mediates a single method call. The primary
+ * purpose of the controller is to provide a way to manipulate settings
+ * specific to the RPC implementation and to find out about RPC-level errors.
+ *
+ * <p>Starting with version 2.3.0, RPC implementations should not try to build
+ * on this, but should instead provide code generator plugins which generate
+ * code specific to the particular RPC implementation. This way the generated
+ * code can be more appropriate for the implementation in use and can avoid
+ * unnecessary layers of indirection.
+ *
+ * <p>The methods provided by the {@code RpcController} interface are intended
+ * to be a "least common denominator" set of features which we expect all
+ * implementations to support. Specific implementations may provide more
+ * advanced features (e.g. deadline propagation).
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface RpcController {
+ // -----------------------------------------------------------------
+ // These calls may be made from the client side only. Their results
+ // are undefined on the server side (may throw RuntimeExceptions).
+
+ /**
+ * Resets the RpcController to its initial state so that it may be reused in
+ * a new call. This can be called from the client side only. It must not
+ * be called while an RPC is in progress.
+ */
+ void reset();
+
+ /**
+ * After a call has finished, returns true if the call failed. The possible
+ * reasons for failure depend on the RPC implementation. {@code failed()}
+ * most only be called on the client side, and must not be called before a
+ * call has finished.
+ */
+ boolean failed();
+
+ /**
+ * If {@code failed()} is {@code true}, returns a human-readable description
+ * of the error.
+ */
+ String errorText();
+
+ /**
+ * Advises the RPC system that the caller desires that the RPC call be
+ * canceled. The RPC system may cancel it immediately, may wait awhile and
+ * then cancel it, or may not even cancel the call at all. If the call is
+ * canceled, the "done" callback will still be called and the RpcController
+ * will indicate that the call failed at that time.
+ */
+ void startCancel();
+
+ // -----------------------------------------------------------------
+ // These calls may be made from the server side only. Their results
+ // are undefined on the client side (may throw RuntimeExceptions).
+
+ /**
+ * Causes {@code failed()} to return true on the client side. {@code reason}
+ * will be incorporated into the message returned by {@code errorText()}.
+ * If you find you need to return machine-readable information about
+ * failures, you should incorporate it into your response protocol buffer
+ * and should NOT call {@code setFailed()}.
+ */
+ void setFailed(String reason);
+
+ /**
+ * If {@code true}, indicates that the client canceled the RPC, so the server
+ * may as well give up on replying to it. This method must be called on the
+ * server side only. The server should still call the final "done" callback.
+ */
+ boolean isCanceled();
+
+ /**
+ * Asks that the given callback be called when the RPC is canceled. The
+ * parameter passed to the callback will always be {@code null}. The
+ * callback will always be called exactly once. If the RPC completes without
+ * being canceled, the callback will be called after completion. If the RPC
+ * has already been canceled when NotifyOnCancel() is called, the callback
+ * will be called immediately.
+ *
+ * <p>{@code notifyOnCancel()} must be called no more than once per request.
+ * It must be called on the server side only.
+ */
+ void notifyOnCancel(RpcCallback<Object> callback);
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcUtil.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcUtil.java
new file mode 100644
index 0000000..b1b959a
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/RpcUtil.java
@@ -0,0 +1,135 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Grab-bag of utility functions useful when dealing with RPCs.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class RpcUtil {
+ private RpcUtil() {}
+
+ /**
+ * Take an {@code RpcCallback<Message>} and convert it to an
+ * {@code RpcCallback} accepting a specific message type. This is always
+ * type-safe (parameter type contravariance).
+ */
+ @SuppressWarnings("unchecked")
+ public static <Type extends Message> RpcCallback<Type>
+ specializeCallback(final RpcCallback<Message> originalCallback) {
+ return (RpcCallback<Type>)originalCallback;
+ // The above cast works, but only due to technical details of the Java
+ // implementation. A more theoretically correct -- but less efficient --
+ // implementation would be as follows:
+ // return new RpcCallback<Type>() {
+ // public void run(Type parameter) {
+ // originalCallback.run(parameter);
+ // }
+ // };
+ }
+
+ /**
+ * Take an {@code RpcCallback} accepting a specific message type and convert
+ * it to an {@code RpcCallback<Message>}. The generalized callback will
+ * accept any message object which has the same descriptor, and will convert
+ * it to the correct class before calling the original callback. However,
+ * if the generalized callback is given a message with a different descriptor,
+ * an exception will be thrown.
+ */
+ public static <Type extends Message>
+ RpcCallback<Message> generalizeCallback(
+ final RpcCallback<Type> originalCallback,
+ final Class<Type> originalClass,
+ final Type defaultInstance) {
+ return new RpcCallback<Message>() {
+ public void run(final Message parameter) {
+ Type typedParameter;
+ try {
+ typedParameter = originalClass.cast(parameter);
+ } catch (ClassCastException ignored) {
+ typedParameter = copyAsType(defaultInstance, parameter);
+ }
+ originalCallback.run(typedParameter);
+ }
+ };
+ }
+
+ /**
+ * Creates a new message of type "Type" which is a copy of "source". "source"
+ * must have the same descriptor but may be a different class (e.g.
+ * DynamicMessage).
+ */
+ @SuppressWarnings("unchecked")
+ private static <Type extends Message> Type copyAsType(
+ final Type typeDefaultInstance, final Message source) {
+ return (Type)typeDefaultInstance.newBuilderForType()
+ .mergeFrom(source)
+ .build();
+ }
+
+ /**
+ * Creates a callback which can only be called once. This may be useful for
+ * security, when passing a callback to untrusted code: most callbacks do
+ * not expect to be called more than once, so doing so may expose bugs if it
+ * is not prevented.
+ */
+ public static <ParameterType>
+ RpcCallback<ParameterType> newOneTimeCallback(
+ final RpcCallback<ParameterType> originalCallback) {
+ return new RpcCallback<ParameterType>() {
+ private boolean alreadyCalled = false;
+
+ public void run(final ParameterType parameter) {
+ synchronized(this) {
+ if (alreadyCalled) {
+ throw new AlreadyCalledException();
+ }
+ alreadyCalled = true;
+ }
+
+ originalCallback.run(parameter);
+ }
+ };
+ }
+
+ /**
+ * Exception thrown when a one-time callback is called more than once.
+ */
+ public static final class AlreadyCalledException extends RuntimeException {
+ private static final long serialVersionUID = 5469741279507848266L;
+
+ public AlreadyCalledException() {
+ super("This RpcCallback was already called and cannot be called " +
+ "multiple times.");
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Service.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Service.java
new file mode 100644
index 0000000..541585f
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/Service.java
@@ -0,0 +1,117 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Abstract base interface for protocol-buffer-based RPC services. Services
+ * themselves are abstract classes (implemented either by servers or as
+ * stubs), but they subclass this base interface. The methods of this
+ * interface can be used to call the methods of the service without knowing
+ * its exact type at compile time (analogous to the Message interface).
+ *
+ * <p>Starting with version 2.3.0, RPC implementations should not try to build
+ * on this, but should instead provide code generator plugins which generate
+ * code specific to the particular RPC implementation. This way the generated
+ * code can be more appropriate for the implementation in use and can avoid
+ * unnecessary layers of indirection.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface Service {
+ /**
+ * Get the {@code ServiceDescriptor} describing this service and its methods.
+ */
+ Descriptors.ServiceDescriptor getDescriptorForType();
+
+ /**
+ * <p>Call a method of the service specified by MethodDescriptor. This is
+ * normally implemented as a simple {@code switch()} that calls the standard
+ * definitions of the service's methods.
+ *
+ * <p>Preconditions:
+ * <ul>
+ * <li>{@code method.getService() == getDescriptorForType()}
+ * <li>{@code request} is of the exact same class as the object returned by
+ * {@code getRequestPrototype(method)}.
+ * <li>{@code controller} is of the correct type for the RPC implementation
+ * being used by this Service. For stubs, the "correct type" depends
+ * on the RpcChannel which the stub is using. Server-side Service
+ * implementations are expected to accept whatever type of
+ * {@code RpcController} the server-side RPC implementation uses.
+ * </ul>
+ *
+ * <p>Postconditions:
+ * <ul>
+ * <li>{@code done} will be called when the method is complete. This may be
+ * before {@code callMethod()} returns or it may be at some point in
+ * the future.
+ * <li>The parameter to {@code done} is the response. It must be of the
+ * exact same type as would be returned by
+ * {@code getResponsePrototype(method)}.
+ * <li>If the RPC failed, the parameter to {@code done} will be
+ * {@code null}. Further details about the failure can be found by
+ * querying {@code controller}.
+ * </ul>
+ */
+ void callMethod(Descriptors.MethodDescriptor method,
+ RpcController controller,
+ Message request,
+ RpcCallback<Message> done);
+
+ /**
+ * <p>{@code callMethod()} requires that the request passed in is of a
+ * particular subclass of {@code Message}. {@code getRequestPrototype()}
+ * gets the default instances of this type for a given method. You can then
+ * call {@code Message.newBuilderForType()} on this instance to
+ * construct a builder to build an object which you can then pass to
+ * {@code callMethod()}.
+ *
+ * <p>Example:
+ * <pre>
+ * MethodDescriptor method =
+ * service.getDescriptorForType().findMethodByName("Foo");
+ * Message request =
+ * stub.getRequestPrototype(method).newBuilderForType()
+ * .mergeFrom(input).build();
+ * service.callMethod(method, request, callback);
+ * </pre>
+ */
+ Message getRequestPrototype(Descriptors.MethodDescriptor method);
+
+ /**
+ * Like {@code getRequestPrototype()}, but gets a prototype of the response
+ * message. {@code getResponsePrototype()} is generally not needed because
+ * the {@code Service} implementation constructs the response message itself,
+ * but it may be useful in some cases to know ahead of time what type of
+ * object will be returned.
+ */
+ Message getResponsePrototype(Descriptors.MethodDescriptor method);
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ServiceException.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ServiceException.java
new file mode 100644
index 0000000..cde669d
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/ServiceException.java
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Thrown by blocking RPC methods when a failure occurs.
+ *
+ * @author cpovirk@google.com (Chris Povirk)
+ */
+public class ServiceException extends Exception {
+ private static final long serialVersionUID = -1219262335729891920L;
+
+ public ServiceException(final String message) {
+ super(message);
+ }
+
+ public ServiceException(final Throwable cause) {
+ super(cause);
+ }
+
+ public ServiceException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java
new file mode 100644
index 0000000..d4475f6
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java
@@ -0,0 +1,241 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * <code>SingleFieldBuilder</code> implements a structure that a protocol
+ * message uses to hold a single field of another protocol message. It supports
+ * the classical use case of setting an immutable {@link Message} as the value
+ * of the field and is highly optimized around this.
+ * <br>
+ * It also supports the additional use case of setting a {@link Message.Builder}
+ * as the field and deferring conversion of that <code>Builder</code>
+ * to an immutable <code>Message</code>. In this way, it's possible to maintain
+ * a tree of <code>Builder</code>'s that acts as a fully read/write data
+ * structure.
+ * <br>
+ * Logically, one can think of a tree of builders as converting the entire tree
+ * to messages when build is called on the root or when any method is called
+ * that desires a Message instead of a Builder. In terms of the implementation,
+ * the <code>SingleFieldBuilder</code> and <code>RepeatedFieldBuilder</code>
+ * classes cache messages that were created so that messages only need to be
+ * created when some change occured in its builder or a builder for one of its
+ * descendants.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class SingleFieldBuilder
+ <MType extends GeneratedMessage,
+ BType extends GeneratedMessage.Builder,
+ IType extends MessageOrBuilder>
+ implements GeneratedMessage.BuilderParent {
+
+ // Parent to send changes to.
+ private GeneratedMessage.BuilderParent parent;
+
+ // Invariant: one of builder or message fields must be non-null.
+
+ // If set, this is the case where we are backed by a builder. In this case,
+ // message field represents a cached message for the builder (or null if
+ // there is no cached message).
+ private BType builder;
+
+ // If builder is non-null, this represents a cached message from the builder.
+ // If builder is null, this is the authoritative message for the field.
+ private MType message;
+
+ // Indicates that we've built a message and so we are now obligated
+ // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
+ private boolean isClean;
+
+ public SingleFieldBuilder(
+ MType message,
+ GeneratedMessage.BuilderParent parent,
+ boolean isClean) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ this.message = message;
+ this.parent = parent;
+ this.isClean = isClean;
+ }
+
+ public void dispose() {
+ // Null out parent so we stop sending it invalidations.
+ parent = null;
+ }
+
+ /**
+ * Get the message for the field. If the message is currently stored
+ * as a <code>Builder</code>, it is converted to a <code>Message</code> by
+ * calling {@link Message.Builder#buildPartial} on it. If no message has
+ * been set, returns the default instance of the message.
+ *
+ * @return the message for the field
+ */
+ @SuppressWarnings("unchecked")
+ public MType getMessage() {
+ if (message == null) {
+ // If message is null, the invariant is that we must be have a builder.
+ message = (MType) builder.buildPartial();
+ }
+ return message;
+ }
+
+ /**
+ * Builds the message and returns it.
+ *
+ * @return the message
+ */
+ public MType build() {
+ // Now that build has been called, we are required to dispatch
+ // invalidations.
+ isClean = true;
+ return getMessage();
+ }
+
+ /**
+ * Gets a builder for the field. If no builder has been created yet, a
+ * builder is created on demand by calling {@link Message#toBuilder}.
+ *
+ * @return The builder for the field
+ */
+ @SuppressWarnings("unchecked")
+ public BType getBuilder() {
+ if (builder == null) {
+ // builder.mergeFrom() on a fresh builder
+ // does not create any sub-objects with independent clean/dirty states,
+ // therefore setting the builder itself to clean without actually calling
+ // build() cannot break any invariants.
+ builder = (BType) message.newBuilderForType(this);
+ builder.mergeFrom(message); // no-op if message is the default message
+ builder.markClean();
+ }
+ return builder;
+ }
+
+ /**
+ * Gets the base class interface for the field. This may either be a builder
+ * or a message. It will return whatever is more efficient.
+ *
+ * @return the message or builder for the field as the base class interface
+ */
+ @SuppressWarnings("unchecked")
+ public IType getMessageOrBuilder() {
+ if (builder != null) {
+ return (IType) builder;
+ } else {
+ return (IType) message;
+ }
+ }
+
+ /**
+ * Sets a message for the field replacing any existing value.
+ *
+ * @param message the message to set
+ * @return the builder
+ */
+ public SingleFieldBuilder<MType, BType, IType> setMessage(
+ MType message) {
+ if (message == null) {
+ throw new NullPointerException();
+ }
+ this.message = message;
+ if (builder != null) {
+ builder.dispose();
+ builder = null;
+ }
+ onChanged();
+ return this;
+ }
+
+ /**
+ * Merges the field from another field.
+ *
+ * @param value the value to merge from
+ * @return the builder
+ */
+ public SingleFieldBuilder<MType, BType, IType> mergeFrom(
+ MType value) {
+ if (builder == null && message == message.getDefaultInstanceForType()) {
+ message = value;
+ } else {
+ getBuilder().mergeFrom(value);
+ }
+ onChanged();
+ return this;
+ }
+
+ /**
+ * Clears the value of the field.
+ *
+ * @return the builder
+ */
+ @SuppressWarnings("unchecked")
+ public SingleFieldBuilder<MType, BType, IType> clear() {
+ message = (MType) (message != null ?
+ message.getDefaultInstanceForType() :
+ builder.getDefaultInstanceForType());
+ if (builder != null) {
+ builder.dispose();
+ builder = null;
+ }
+ onChanged();
+ return this;
+ }
+
+ /**
+ * Called when a the builder or one of its nested children has changed
+ * and any parent should be notified of its invalidation.
+ */
+ private void onChanged() {
+ // If builder is null, this is the case where onChanged is being called
+ // from setMessage or clear.
+ if (builder != null) {
+ message = null;
+ }
+ if (isClean && parent != null) {
+ parent.markDirty();
+
+ // Don't keep dispatching invalidations until build is called again.
+ isClean = false;
+ }
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void markDirty() {
+ onChanged();
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java
new file mode 100644
index 0000000..1cf270f
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java
@@ -0,0 +1,618 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.TreeMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+
+/**
+ * A custom map implementation from FieldDescriptor to Object optimized to
+ * minimize the number of memory allocations for instances with a small number
+ * of mappings. The implementation stores the first {@code k} mappings in an
+ * array for a configurable value of {@code k}, allowing direct access to the
+ * corresponding {@code Entry}s without the need to create an Iterator. The
+ * remaining entries are stored in an overflow map. Iteration over the entries
+ * in the map should be done as follows:
+ *
+ * <pre>
+ * for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
+ * process(fieldMap.getArrayEntryAt(i));
+ * }
+ * for (Map.Entry<K, V> entry : fieldMap.getOverflowEntries()) {
+ * process(entry);
+ * }
+ * </pre>
+ *
+ * The resulting iteration is in order of ascending field tag number. The
+ * object returned by {@link #entrySet()} adheres to the same contract but is
+ * less efficient as it necessarily involves creating an object for iteration.
+ * <p>
+ * The tradeoff for this memory efficiency is that the worst case running time
+ * of the {@code put()} operation is {@code O(k + lg n)}, which happens when
+ * entries are added in descending order. {@code k} should be chosen such that
+ * it covers enough common cases without adversely affecting larger maps. In
+ * practice, the worst case scenario does not happen for extensions because
+ * extension fields are serialized and deserialized in order of ascending tag
+ * number, but the worst case scenario can happen for DynamicMessages.
+ * <p>
+ * The running time for all other operations is similar to that of
+ * {@code TreeMap}.
+ * <p>
+ * Instances are not thread-safe until {@link #makeImmutable()} is called,
+ * after which any modifying operation will result in an
+ * {@link UnsupportedOperationException}.
+ *
+ * @author darick@google.com Darick Tong
+ */
+// This class is final for all intents and purposes because the constructor is
+// private. However, the FieldDescriptor-specific logic is encapsulated in
+// a subclass to aid testability of the core logic.
+class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
+
+ /**
+ * Creates a new instance for mapping FieldDescriptors to their values.
+ * The {@link #makeImmutable()} implementation will convert the List values
+ * of any repeated fields to unmodifiable lists.
+ *
+ * @param arraySize The size of the entry array containing the
+ * lexicographically smallest mappings.
+ */
+ static <FieldDescriptorType extends
+ FieldSet.FieldDescriptorLite<FieldDescriptorType>>
+ SmallSortedMap<FieldDescriptorType, Object> newFieldMap(int arraySize) {
+ return new SmallSortedMap<FieldDescriptorType, Object>(arraySize) {
+ @Override
+ @SuppressWarnings("unchecked")
+ public void makeImmutable() {
+ if (!isImmutable()) {
+ for (int i = 0; i < getNumArrayEntries(); i++) {
+ final Map.Entry<FieldDescriptorType, Object> entry =
+ getArrayEntryAt(i);
+ if (entry.getKey().isRepeated()) {
+ final List value = (List) entry.getValue();
+ entry.setValue(Collections.unmodifiableList(value));
+ }
+ }
+ for (Map.Entry<FieldDescriptorType, Object> entry :
+ getOverflowEntries()) {
+ if (entry.getKey().isRepeated()) {
+ final List value = (List) entry.getValue();
+ entry.setValue(Collections.unmodifiableList(value));
+ }
+ }
+ }
+ super.makeImmutable();
+ }
+ };
+ }
+
+ /**
+ * Creates a new instance for testing.
+ *
+ * @param arraySize The size of the entry array containing the
+ * lexicographically smallest mappings.
+ */
+ static <K extends Comparable<K>, V> SmallSortedMap<K, V> newInstanceForTest(
+ int arraySize) {
+ return new SmallSortedMap<K, V>(arraySize);
+ }
+
+ private final int maxArraySize;
+ // The "entry array" is actually a List because generic arrays are not
+ // allowed. ArrayList also nicely handles the entry shifting on inserts and
+ // removes.
+ private List<Entry> entryList;
+ private Map<K, V> overflowEntries;
+ private boolean isImmutable;
+ // The EntrySet is a stateless view of the Map. It's initialized the first
+ // time it is requested and reused henceforth.
+ private volatile EntrySet lazyEntrySet;
+
+ /**
+ * @code arraySize Size of the array in which the lexicographically smallest
+ * mappings are stored. (i.e. the {@code k} referred to in the class
+ * documentation).
+ */
+ private SmallSortedMap(int arraySize) {
+ this.maxArraySize = arraySize;
+ this.entryList = Collections.emptyList();
+ this.overflowEntries = Collections.emptyMap();
+ }
+
+ /** Make this map immutable from this point forward. */
+ public void makeImmutable() {
+ if (!isImmutable) {
+ // Note: There's no need to wrap the entryList in an unmodifiableList
+ // because none of the list's accessors are exposed. The iterator() of
+ // overflowEntries, on the other hand, is exposed so it must be made
+ // unmodifiable.
+ overflowEntries = overflowEntries.isEmpty() ?
+ Collections.<K, V>emptyMap() :
+ Collections.unmodifiableMap(overflowEntries);
+ isImmutable = true;
+ }
+ }
+
+ /** @return Whether {@link #makeImmutable()} has been called. */
+ public boolean isImmutable() {
+ return isImmutable;
+ }
+
+ /** @return The number of entries in the entry array. */
+ public int getNumArrayEntries() {
+ return entryList.size();
+ }
+
+ /** @return The array entry at the given {@code index}. */
+ public Map.Entry<K, V> getArrayEntryAt(int index) {
+ return entryList.get(index);
+ }
+
+ /** @return There number of overflow entries. */
+ public int getNumOverflowEntries() {
+ return overflowEntries.size();
+ }
+
+ /** @return An iterable over the overflow entries. */
+ public Iterable<Map.Entry<K, V>> getOverflowEntries() {
+ return overflowEntries.isEmpty() ?
+ EmptySet.<Map.Entry<K, V>>iterable() :
+ overflowEntries.entrySet();
+ }
+
+ @Override
+ public int size() {
+ return entryList.size() + overflowEntries.size();
+ }
+
+ /**
+ * The implementation throws a {@code ClassCastException} if o is not an
+ * object of type {@code K}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean containsKey(Object o) {
+ @SuppressWarnings("unchecked")
+ final K key = (K) o;
+ return binarySearchInArray(key) >= 0 || overflowEntries.containsKey(key);
+ }
+
+ /**
+ * The implementation throws a {@code ClassCastException} if o is not an
+ * object of type {@code K}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public V get(Object o) {
+ @SuppressWarnings("unchecked")
+ final K key = (K) o;
+ final int index = binarySearchInArray(key);
+ if (index >= 0) {
+ return entryList.get(index).getValue();
+ }
+ return overflowEntries.get(key);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ checkMutable();
+ final int index = binarySearchInArray(key);
+ if (index >= 0) {
+ // Replace existing array entry.
+ return entryList.get(index).setValue(value);
+ }
+ ensureEntryArrayMutable();
+ final int insertionPoint = -(index + 1);
+ if (insertionPoint >= maxArraySize) {
+ // Put directly in overflow.
+ return getOverflowEntriesMutable().put(key, value);
+ }
+ // Insert new Entry in array.
+ if (entryList.size() == maxArraySize) {
+ // Shift the last array entry into overflow.
+ final Entry lastEntryInArray = entryList.remove(maxArraySize - 1);
+ getOverflowEntriesMutable().put(lastEntryInArray.getKey(),
+ lastEntryInArray.getValue());
+ }
+ entryList.add(insertionPoint, new Entry(key, value));
+ return null;
+ }
+
+ @Override
+ public void clear() {
+ checkMutable();
+ if (!entryList.isEmpty()) {
+ entryList.clear();
+ }
+ if (!overflowEntries.isEmpty()) {
+ overflowEntries.clear();
+ }
+ }
+
+ /**
+ * The implementation throws a {@code ClassCastException} if o is not an
+ * object of type {@code K}.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public V remove(Object o) {
+ checkMutable();
+ @SuppressWarnings("unchecked")
+ final K key = (K) o;
+ final int index = binarySearchInArray(key);
+ if (index >= 0) {
+ return removeArrayEntryAt(index);
+ }
+ // overflowEntries might be Collections.unmodifiableMap(), so only
+ // call remove() if it is non-empty.
+ if (overflowEntries.isEmpty()) {
+ return null;
+ } else {
+ return overflowEntries.remove(key);
+ }
+ }
+
+ private V removeArrayEntryAt(int index) {
+ checkMutable();
+ final V removed = entryList.remove(index).getValue();
+ if (!overflowEntries.isEmpty()) {
+ // Shift the first entry in the overflow to be the last entry in the
+ // array.
+ final Iterator<Map.Entry<K, V>> iterator =
+ getOverflowEntriesMutable().entrySet().iterator();
+ entryList.add(new Entry(iterator.next()));
+ iterator.remove();
+ }
+ return removed;
+ }
+
+ /**
+ * @param key The key to find in the entry array.
+ * @return The returned integer position follows the same semantics as the
+ * value returned by {@link java.util.Arrays#binarySearch()}.
+ */
+ private int binarySearchInArray(K key) {
+ int left = 0;
+ int right = entryList.size() - 1;
+
+ // Optimization: For the common case in which entries are added in
+ // ascending tag order, check the largest element in the array before
+ // doing a full binary search.
+ if (right >= 0) {
+ int cmp = key.compareTo(entryList.get(right).getKey());
+ if (cmp > 0) {
+ return -(right + 2); // Insert point is after "right".
+ } else if (cmp == 0) {
+ return right;
+ }
+ }
+
+ while (left <= right) {
+ int mid = (left + right) / 2;
+ int cmp = key.compareTo(entryList.get(mid).getKey());
+ if (cmp < 0) {
+ right = mid - 1;
+ } else if (cmp > 0) {
+ left = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ return -(left + 1);
+ }
+
+ /**
+ * Similar to the AbstractMap implementation of {@code keySet()} and
+ * {@code values()}, the entry set is created the first time this method is
+ * called, and returned in response to all subsequent calls.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<Map.Entry<K, V>> entrySet() {
+ if (lazyEntrySet == null) {
+ lazyEntrySet = new EntrySet();
+ }
+ return lazyEntrySet;
+ }
+
+ /**
+ * @throws UnsupportedOperationException if {@link #makeImmutable()} has
+ * has been called.
+ */
+ private void checkMutable() {
+ if (isImmutable) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * @return a {@link SortedMap} to which overflow entries mappings can be
+ * added or removed.
+ * @throws UnsupportedOperationException if {@link #makeImmutable()} has been
+ * called.
+ */
+ @SuppressWarnings("unchecked")
+ private SortedMap<K, V> getOverflowEntriesMutable() {
+ checkMutable();
+ if (overflowEntries.isEmpty() && !(overflowEntries instanceof TreeMap)) {
+ overflowEntries = new TreeMap<K, V>();
+ }
+ return (SortedMap<K, V>) overflowEntries;
+ }
+
+ /**
+ * Lazily creates the entry list. Any code that adds to the list must first
+ * call this method.
+ */
+ private void ensureEntryArrayMutable() {
+ checkMutable();
+ if (entryList.isEmpty() && !(entryList instanceof ArrayList)) {
+ entryList = new ArrayList<Entry>(maxArraySize);
+ }
+ }
+
+ /**
+ * Entry implementation that implements Comparable in order to support
+ * binary search witin the entry array. Also checks mutability in
+ * {@link #setValue()}.
+ */
+ private class Entry implements Map.Entry<K, V>, Comparable<Entry> {
+
+ private final K key;
+ private V value;
+
+ Entry(Map.Entry<K, V> copy) {
+ this(copy.getKey(), copy.getValue());
+ }
+
+ Entry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public K getKey() {
+ return key;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public V getValue() {
+ return value;
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public int compareTo(Entry other) {
+ return getKey().compareTo(other.getKey());
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public V setValue(V newValue) {
+ checkMutable();
+ final V oldValue = this.value;
+ this.value = newValue;
+ return oldValue;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof Map.Entry)) {
+ return false;
+ }
+ @SuppressWarnings("unchecked")
+ Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
+ return equals(key, other.getKey()) && equals(value, other.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+ return (key == null ? 0 : key.hashCode()) ^
+ (value == null ? 0 : value.hashCode());
+ }
+
+ @Override
+ public String toString() {
+ return key + "=" + value;
+ }
+
+ /** equals() that handles null values. */
+ private boolean equals(Object o1, Object o2) {
+ return o1 == null ? o2 == null : o1.equals(o2);
+ }
+ }
+
+ /**
+ * Stateless view of the entries in the field map.
+ */
+ private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
+
+ @Override
+ public Iterator<Map.Entry<K, V>> iterator() {
+ return new EntryIterator();
+ }
+
+ @Override
+ public int size() {
+ return SmallSortedMap.this.size();
+ }
+
+ /**
+ * Throws a {@link ClassCastException} if o is not of the expected type.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean contains(Object o) {
+ @SuppressWarnings("unchecked")
+ final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
+ final V existing = get(entry.getKey());
+ final V value = entry.getValue();
+ return existing == value ||
+ (existing != null && existing.equals(value));
+ }
+
+ @Override
+ public boolean add(Map.Entry<K, V> entry) {
+ if (!contains(entry)) {
+ put(entry.getKey(), entry.getValue());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Throws a {@link ClassCastException} if o is not of the expected type.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean remove(Object o) {
+ @SuppressWarnings("unchecked")
+ final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
+ if (contains(entry)) {
+ SmallSortedMap.this.remove(entry.getKey());
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void clear() {
+ SmallSortedMap.this.clear();
+ }
+ }
+
+ /**
+ * Iterator implementation that switches from the entry array to the overflow
+ * entries appropriately.
+ */
+ private class EntryIterator implements Iterator<Map.Entry<K, V>> {
+
+ private int pos = -1;
+ private boolean nextCalledBeforeRemove;
+ private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasNext() {
+ return (pos + 1) < entryList.size() ||
+ getOverflowIterator().hasNext();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Map.Entry<K, V> next() {
+ nextCalledBeforeRemove = true;
+ // Always increment pos so that we know whether the last returned value
+ // was from the array or from overflow.
+ if (++pos < entryList.size()) {
+ return entryList.get(pos);
+ }
+ return getOverflowIterator().next();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void remove() {
+ if (!nextCalledBeforeRemove) {
+ throw new IllegalStateException("remove() was called before next()");
+ }
+ nextCalledBeforeRemove = false;
+ checkMutable();
+
+ if (pos < entryList.size()) {
+ removeArrayEntryAt(pos--);
+ } else {
+ getOverflowIterator().remove();
+ }
+ }
+
+ /**
+ * It is important to create the overflow iterator only after the array
+ * entries have been iterated over because the overflow entry set changes
+ * when the client calls remove() on the array entries, which invalidates
+ * any existing iterators.
+ */
+ private Iterator<Map.Entry<K, V>> getOverflowIterator() {
+ if (lazyOverflowIterator == null) {
+ lazyOverflowIterator = overflowEntries.entrySet().iterator();
+ }
+ return lazyOverflowIterator;
+ }
+ }
+
+ /**
+ * Helper class that holds immutable instances of an Iterable/Iterator that
+ * we return when the overflow entries is empty. This eliminates the creation
+ * of an Iterator object when there is nothing to iterate over.
+ */
+ private static class EmptySet {
+
+ private static final Iterator<Object> ITERATOR = new Iterator<Object>() {
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasNext() {
+ return false;
+ }
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Object next() {
+ throw new NoSuchElementException();
+ }
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ private static final Iterable<Object> ITERABLE = new Iterable<Object>() {
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public Iterator<Object> iterator() {
+ return ITERATOR;
+ }
+ };
+
+ @SuppressWarnings("unchecked")
+ static <T> Iterable<T> iterable() {
+ return (Iterable<T>) ITERABLE;
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/TextFormat.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/TextFormat.java
new file mode 100644
index 0000000..d5fbdab
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/TextFormat.java
@@ -0,0 +1,1476 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+
+import java.io.IOException;
+import java.nio.CharBuffer;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Provide text parsing and formatting support for proto2 instances.
+ * The implementation largely follows google/protobuf/text_format.cc.
+ *
+ * @author wenboz@google.com Wenbo Zhu
+ * @author kenton@google.com Kenton Varda
+ */
+public final class TextFormat {
+ private TextFormat() {}
+
+ private static final Printer DEFAULT_PRINTER = new Printer(false);
+ private static final Printer SINGLE_LINE_PRINTER = new Printer(true);
+
+ /**
+ * Outputs a textual representation of the Protocol Message supplied into
+ * the parameter output. (This representation is the new version of the
+ * classic "ProtocolPrinter" output from the original Protocol Buffer system)
+ */
+ public static void print(final Message message, final Appendable output)
+ throws IOException {
+ DEFAULT_PRINTER.print(message, new TextGenerator(output));
+ }
+
+ /** Outputs a textual representation of {@code fields} to {@code output}. */
+ public static void print(final UnknownFieldSet fields,
+ final Appendable output)
+ throws IOException {
+ DEFAULT_PRINTER.printUnknownFields(fields, new TextGenerator(output));
+ }
+
+ /**
+ * Generates a human readable form of this message, useful for debugging and
+ * other purposes, with no newline characters.
+ */
+ public static String shortDebugString(final Message message) {
+ try {
+ final StringBuilder sb = new StringBuilder();
+ SINGLE_LINE_PRINTER.print(message, new TextGenerator(sb));
+ // Single line mode currently might have an extra space at the end.
+ return sb.toString().trim();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Generates a human readable form of the unknown fields, useful for debugging
+ * and other purposes, with no newline characters.
+ */
+ public static String shortDebugString(final UnknownFieldSet fields) {
+ try {
+ final StringBuilder sb = new StringBuilder();
+ SINGLE_LINE_PRINTER.printUnknownFields(fields, new TextGenerator(sb));
+ // Single line mode currently might have an extra space at the end.
+ return sb.toString().trim();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Like {@code print()}, but writes directly to a {@code String} and
+ * returns it.
+ */
+ public static String printToString(final Message message) {
+ try {
+ final StringBuilder text = new StringBuilder();
+ print(message, text);
+ return text.toString();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Like {@code print()}, but writes directly to a {@code String} and
+ * returns it.
+ */
+ public static String printToString(final UnknownFieldSet fields) {
+ try {
+ final StringBuilder text = new StringBuilder();
+ print(fields, text);
+ return text.toString();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public static void printField(final FieldDescriptor field,
+ final Object value,
+ final Appendable output)
+ throws IOException {
+ DEFAULT_PRINTER.printField(field, value, new TextGenerator(output));
+ }
+
+ public static String printFieldToString(final FieldDescriptor field,
+ final Object value) {
+ try {
+ final StringBuilder text = new StringBuilder();
+ printField(field, value, text);
+ return text.toString();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Outputs a textual representation of the value of given field value.
+ *
+ * @param field the descriptor of the field
+ * @param value the value of the field
+ * @param output the output to which to append the formatted value
+ * @throws ClassCastException if the value is not appropriate for the
+ * given field descriptor
+ * @throws IOException if there is an exception writing to the output
+ */
+ public static void printFieldValue(final FieldDescriptor field,
+ final Object value,
+ final Appendable output)
+ throws IOException {
+ DEFAULT_PRINTER.printFieldValue(field, value, new TextGenerator(output));
+ }
+
+ /**
+ * Outputs a textual representation of the value of an unknown field.
+ *
+ * @param tag the field's tag number
+ * @param value the value of the field
+ * @param output the output to which to append the formatted value
+ * @throws ClassCastException if the value is not appropriate for the
+ * given field descriptor
+ * @throws IOException if there is an exception writing to the output
+ */
+ public static void printUnknownFieldValue(final int tag,
+ final Object value,
+ final Appendable output)
+ throws IOException {
+ printUnknownFieldValue(tag, value, new TextGenerator(output));
+ }
+
+ private static void printUnknownFieldValue(final int tag,
+ final Object value,
+ final TextGenerator generator)
+ throws IOException {
+ switch (WireFormat.getTagWireType(tag)) {
+ case WireFormat.WIRETYPE_VARINT:
+ generator.print(unsignedToString((Long) value));
+ break;
+ case WireFormat.WIRETYPE_FIXED32:
+ generator.print(
+ String.format((Locale) null, "0x%08x", (Integer) value));
+ break;
+ case WireFormat.WIRETYPE_FIXED64:
+ generator.print(String.format((Locale) null, "0x%016x", (Long) value));
+ break;
+ case WireFormat.WIRETYPE_LENGTH_DELIMITED:
+ generator.print("\"");
+ generator.print(escapeBytes((ByteString) value));
+ generator.print("\"");
+ break;
+ case WireFormat.WIRETYPE_START_GROUP:
+ DEFAULT_PRINTER.printUnknownFields((UnknownFieldSet) value, generator);
+ break;
+ default:
+ throw new IllegalArgumentException("Bad tag: " + tag);
+ }
+ }
+
+ /** Helper class for converting protobufs to text. */
+ private static final class Printer {
+ /** Whether to omit newlines from the output. */
+ final boolean singleLineMode;
+
+ private Printer(final boolean singleLineMode) {
+ this.singleLineMode = singleLineMode;
+ }
+
+ private void print(final Message message, final TextGenerator generator)
+ throws IOException {
+ for (Map.Entry<FieldDescriptor, Object> field
+ : message.getAllFields().entrySet()) {
+ printField(field.getKey(), field.getValue(), generator);
+ }
+ printUnknownFields(message.getUnknownFields(), generator);
+ }
+
+ private void printField(final FieldDescriptor field, final Object value,
+ final TextGenerator generator) throws IOException {
+ if (field.isRepeated()) {
+ // Repeated field. Print each element.
+ for (Object element : (List<?>) value) {
+ printSingleField(field, element, generator);
+ }
+ } else {
+ printSingleField(field, value, generator);
+ }
+ }
+
+ private void printSingleField(final FieldDescriptor field,
+ final Object value,
+ final TextGenerator generator)
+ throws IOException {
+ if (field.isExtension()) {
+ generator.print("[");
+ // We special-case MessageSet elements for compatibility with proto1.
+ if (field.getContainingType().getOptions().getMessageSetWireFormat()
+ && (field.getType() == FieldDescriptor.Type.MESSAGE)
+ && (field.isOptional())
+ // object equality
+ && (field.getExtensionScope() == field.getMessageType())) {
+ generator.print(field.getMessageType().getFullName());
+ } else {
+ generator.print(field.getFullName());
+ }
+ generator.print("]");
+ } else {
+ if (field.getType() == FieldDescriptor.Type.GROUP) {
+ // Groups must be serialized with their original capitalization.
+ generator.print(field.getMessageType().getName());
+ } else {
+ generator.print(field.getName());
+ }
+ }
+
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (singleLineMode) {
+ generator.print(" { ");
+ } else {
+ generator.print(" {\n");
+ generator.indent();
+ }
+ } else {
+ generator.print(": ");
+ }
+
+ printFieldValue(field, value, generator);
+
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ if (singleLineMode) {
+ generator.print("} ");
+ } else {
+ generator.outdent();
+ generator.print("}\n");
+ }
+ } else {
+ if (singleLineMode) {
+ generator.print(" ");
+ } else {
+ generator.print("\n");
+ }
+ }
+ }
+
+ private void printFieldValue(final FieldDescriptor field,
+ final Object value,
+ final TextGenerator generator)
+ throws IOException {
+ switch (field.getType()) {
+ case INT32:
+ case SINT32:
+ case SFIXED32:
+ generator.print(((Integer) value).toString());
+ break;
+
+ case INT64:
+ case SINT64:
+ case SFIXED64:
+ generator.print(((Long) value).toString());
+ break;
+
+ case BOOL:
+ generator.print(((Boolean) value).toString());
+ break;
+
+ case FLOAT:
+ generator.print(((Float) value).toString());
+ break;
+
+ case DOUBLE:
+ generator.print(((Double) value).toString());
+ break;
+
+ case UINT32:
+ case FIXED32:
+ generator.print(unsignedToString((Integer) value));
+ break;
+
+ case UINT64:
+ case FIXED64:
+ generator.print(unsignedToString((Long) value));
+ break;
+
+ case STRING:
+ generator.print("\"");
+ generator.print(escapeText((String) value));
+ generator.print("\"");
+ break;
+
+ case BYTES:
+ generator.print("\"");
+ generator.print(escapeBytes((ByteString) value));
+ generator.print("\"");
+ break;
+
+ case ENUM:
+ generator.print(((EnumValueDescriptor) value).getName());
+ break;
+
+ case MESSAGE:
+ case GROUP:
+ print((Message) value, generator);
+ break;
+ }
+ }
+
+ private void printUnknownFields(final UnknownFieldSet unknownFields,
+ final TextGenerator generator)
+ throws IOException {
+ for (Map.Entry<Integer, UnknownFieldSet.Field> entry :
+ unknownFields.asMap().entrySet()) {
+ final int number = entry.getKey();
+ final UnknownFieldSet.Field field = entry.getValue();
+ printUnknownField(number, WireFormat.WIRETYPE_VARINT,
+ field.getVarintList(), generator);
+ printUnknownField(number, WireFormat.WIRETYPE_FIXED32,
+ field.getFixed32List(), generator);
+ printUnknownField(number, WireFormat.WIRETYPE_FIXED64,
+ field.getFixed64List(), generator);
+ printUnknownField(number, WireFormat.WIRETYPE_LENGTH_DELIMITED,
+ field.getLengthDelimitedList(), generator);
+ for (final UnknownFieldSet value : field.getGroupList()) {
+ generator.print(entry.getKey().toString());
+ if (singleLineMode) {
+ generator.print(" { ");
+ } else {
+ generator.print(" {\n");
+ generator.indent();
+ }
+ printUnknownFields(value, generator);
+ if (singleLineMode) {
+ generator.print("} ");
+ } else {
+ generator.outdent();
+ generator.print("}\n");
+ }
+ }
+ }
+ }
+
+ private void printUnknownField(final int number,
+ final int wireType,
+ final List<?> values,
+ final TextGenerator generator)
+ throws IOException {
+ for (final Object value : values) {
+ generator.print(String.valueOf(number));
+ generator.print(": ");
+ printUnknownFieldValue(wireType, value, generator);
+ generator.print(singleLineMode ? " " : "\n");
+ }
+ }
+ }
+
+ /** Convert an unsigned 32-bit integer to a string. */
+ private static String unsignedToString(final int value) {
+ if (value >= 0) {
+ return Integer.toString(value);
+ } else {
+ return Long.toString(((long) value) & 0x00000000FFFFFFFFL);
+ }
+ }
+
+ /** Convert an unsigned 64-bit integer to a string. */
+ private static String unsignedToString(final long value) {
+ if (value >= 0) {
+ return Long.toString(value);
+ } else {
+ // Pull off the most-significant bit so that BigInteger doesn't think
+ // the number is negative, then set it again using setBit().
+ return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL)
+ .setBit(63).toString();
+ }
+ }
+
+ /**
+ * An inner class for writing text to the output stream.
+ */
+ private static final class TextGenerator {
+ private final Appendable output;
+ private final StringBuilder indent = new StringBuilder();
+ private boolean atStartOfLine = true;
+
+ private TextGenerator(final Appendable output) {
+ this.output = output;
+ }
+
+ /**
+ * Indent text by two spaces. After calling Indent(), two spaces will be
+ * inserted at the beginning of each line of text. Indent() may be called
+ * multiple times to produce deeper indents.
+ */
+ public void indent() {
+ indent.append(" ");
+ }
+
+ /**
+ * Reduces the current indent level by two spaces, or crashes if the indent
+ * level is zero.
+ */
+ public void outdent() {
+ final int length = indent.length();
+ if (length == 0) {
+ throw new IllegalArgumentException(
+ " Outdent() without matching Indent().");
+ }
+ indent.delete(length - 2, length);
+ }
+
+ /**
+ * Print text to the output stream.
+ */
+ public void print(final CharSequence text) throws IOException {
+ final int size = text.length();
+ int pos = 0;
+
+ for (int i = 0; i < size; i++) {
+ if (text.charAt(i) == '\n') {
+ write(text.subSequence(pos, size), i - pos + 1);
+ pos = i + 1;
+ atStartOfLine = true;
+ }
+ }
+ write(text.subSequence(pos, size), size - pos);
+ }
+
+ private void write(final CharSequence data, final int size)
+ throws IOException {
+ if (size == 0) {
+ return;
+ }
+ if (atStartOfLine) {
+ atStartOfLine = false;
+ output.append(indent);
+ }
+ output.append(data);
+ }
+ }
+
+ // =================================================================
+ // Parsing
+
+ /**
+ * Represents a stream of tokens parsed from a {@code String}.
+ *
+ * <p>The Java standard library provides many classes that you might think
+ * would be useful for implementing this, but aren't. For example:
+ *
+ * <ul>
+ * <li>{@code java.io.StreamTokenizer}: This almost does what we want -- or,
+ * at least, something that would get us close to what we want -- except
+ * for one fatal flaw: It automatically un-escapes strings using Java
+ * escape sequences, which do not include all the escape sequences we
+ * need to support (e.g. '\x').
+ * <li>{@code java.util.Scanner}: This seems like a great way at least to
+ * parse regular expressions out of a stream (so we wouldn't have to load
+ * the entire input into a single string before parsing). Sadly,
+ * {@code Scanner} requires that tokens be delimited with some delimiter.
+ * Thus, although the text "foo:" should parse to two tokens ("foo" and
+ * ":"), {@code Scanner} would recognize it only as a single token.
+ * Furthermore, {@code Scanner} provides no way to inspect the contents
+ * of delimiters, making it impossible to keep track of line and column
+ * numbers.
+ * </ul>
+ *
+ * <p>Luckily, Java's regular expression support does manage to be useful to
+ * us. (Barely: We need {@code Matcher.usePattern()}, which is new in
+ * Java 1.5.) So, we can use that, at least. Unfortunately, this implies
+ * that we need to have the entire input in one contiguous string.
+ */
+ private static final class Tokenizer {
+ private final CharSequence text;
+ private final Matcher matcher;
+ private String currentToken;
+
+ // The character index within this.text at which the current token begins.
+ private int pos = 0;
+
+ // The line and column numbers of the current token.
+ private int line = 0;
+ private int column = 0;
+
+ // The line and column numbers of the previous token (allows throwing
+ // errors *after* consuming).
+ private int previousLine = 0;
+ private int previousColumn = 0;
+
+ // We use possesive quantifiers (*+ and ++) because otherwise the Java
+ // regex matcher has stack overflows on large inputs.
+ private static final Pattern WHITESPACE =
+ Pattern.compile("(\\s|(#.*$))++", Pattern.MULTILINE);
+ private static final Pattern TOKEN = Pattern.compile(
+ "[a-zA-Z_][0-9a-zA-Z_+-]*+|" + // an identifier
+ "[.]?[0-9+-][0-9a-zA-Z_.+-]*+|" + // a number
+ "\"([^\"\n\\\\]|\\\\.)*+(\"|\\\\?$)|" + // a double-quoted string
+ "\'([^\'\n\\\\]|\\\\.)*+(\'|\\\\?$)", // a single-quoted string
+ Pattern.MULTILINE);
+
+ private static final Pattern DOUBLE_INFINITY = Pattern.compile(
+ "-?inf(inity)?",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern FLOAT_INFINITY = Pattern.compile(
+ "-?inf(inity)?f?",
+ Pattern.CASE_INSENSITIVE);
+ private static final Pattern FLOAT_NAN = Pattern.compile(
+ "nanf?",
+ Pattern.CASE_INSENSITIVE);
+
+ /** Construct a tokenizer that parses tokens from the given text. */
+ private Tokenizer(final CharSequence text) {
+ this.text = text;
+ this.matcher = WHITESPACE.matcher(text);
+ skipWhitespace();
+ nextToken();
+ }
+
+ /** Are we at the end of the input? */
+ public boolean atEnd() {
+ return currentToken.length() == 0;
+ }
+
+ /** Advance to the next token. */
+ public void nextToken() {
+ previousLine = line;
+ previousColumn = column;
+
+ // Advance the line counter to the current position.
+ while (pos < matcher.regionStart()) {
+ if (text.charAt(pos) == '\n') {
+ ++line;
+ column = 0;
+ } else {
+ ++column;
+ }
+ ++pos;
+ }
+
+ // Match the next token.
+ if (matcher.regionStart() == matcher.regionEnd()) {
+ // EOF
+ currentToken = "";
+ } else {
+ matcher.usePattern(TOKEN);
+ if (matcher.lookingAt()) {
+ currentToken = matcher.group();
+ matcher.region(matcher.end(), matcher.regionEnd());
+ } else {
+ // Take one character.
+ currentToken = String.valueOf(text.charAt(pos));
+ matcher.region(pos + 1, matcher.regionEnd());
+ }
+
+ skipWhitespace();
+ }
+ }
+
+ /**
+ * Skip over any whitespace so that the matcher region starts at the next
+ * token.
+ */
+ private void skipWhitespace() {
+ matcher.usePattern(WHITESPACE);
+ if (matcher.lookingAt()) {
+ matcher.region(matcher.end(), matcher.regionEnd());
+ }
+ }
+
+ /**
+ * If the next token exactly matches {@code token}, consume it and return
+ * {@code true}. Otherwise, return {@code false} without doing anything.
+ */
+ public boolean tryConsume(final String token) {
+ if (currentToken.equals(token)) {
+ nextToken();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * If the next token exactly matches {@code token}, consume it. Otherwise,
+ * throw a {@link ParseException}.
+ */
+ public void consume(final String token) throws ParseException {
+ if (!tryConsume(token)) {
+ throw parseException("Expected \"" + token + "\".");
+ }
+ }
+
+ /**
+ * Returns {@code true} if the next token is an integer, but does
+ * not consume it.
+ */
+ public boolean lookingAtInteger() {
+ if (currentToken.length() == 0) {
+ return false;
+ }
+
+ final char c = currentToken.charAt(0);
+ return ('0' <= c && c <= '9') ||
+ c == '-' || c == '+';
+ }
+
+ /**
+ * If the next token is an identifier, consume it and return its value.
+ * Otherwise, throw a {@link ParseException}.
+ */
+ public String consumeIdentifier() throws ParseException {
+ for (int i = 0; i < currentToken.length(); i++) {
+ final char c = currentToken.charAt(i);
+ if (('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ ('0' <= c && c <= '9') ||
+ (c == '_') || (c == '.')) {
+ // OK
+ } else {
+ throw parseException("Expected identifier.");
+ }
+ }
+
+ final String result = currentToken;
+ nextToken();
+ return result;
+ }
+
+ /**
+ * If the next token is a 32-bit signed integer, consume it and return its
+ * value. Otherwise, throw a {@link ParseException}.
+ */
+ public int consumeInt32() throws ParseException {
+ try {
+ final int result = parseInt32(currentToken);
+ nextToken();
+ return result;
+ } catch (NumberFormatException e) {
+ throw integerParseException(e);
+ }
+ }
+
+ /**
+ * If the next token is a 32-bit unsigned integer, consume it and return its
+ * value. Otherwise, throw a {@link ParseException}.
+ */
+ public int consumeUInt32() throws ParseException {
+ try {
+ final int result = parseUInt32(currentToken);
+ nextToken();
+ return result;
+ } catch (NumberFormatException e) {
+ throw integerParseException(e);
+ }
+ }
+
+ /**
+ * If the next token is a 64-bit signed integer, consume it and return its
+ * value. Otherwise, throw a {@link ParseException}.
+ */
+ public long consumeInt64() throws ParseException {
+ try {
+ final long result = parseInt64(currentToken);
+ nextToken();
+ return result;
+ } catch (NumberFormatException e) {
+ throw integerParseException(e);
+ }
+ }
+
+ /**
+ * If the next token is a 64-bit unsigned integer, consume it and return its
+ * value. Otherwise, throw a {@link ParseException}.
+ */
+ public long consumeUInt64() throws ParseException {
+ try {
+ final long result = parseUInt64(currentToken);
+ nextToken();
+ return result;
+ } catch (NumberFormatException e) {
+ throw integerParseException(e);
+ }
+ }
+
+ /**
+ * If the next token is a double, consume it and return its value.
+ * Otherwise, throw a {@link ParseException}.
+ */
+ public double consumeDouble() throws ParseException {
+ // We need to parse infinity and nan separately because
+ // Double.parseDouble() does not accept "inf", "infinity", or "nan".
+ if (DOUBLE_INFINITY.matcher(currentToken).matches()) {
+ final boolean negative = currentToken.startsWith("-");
+ nextToken();
+ return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
+ }
+ if (currentToken.equalsIgnoreCase("nan")) {
+ nextToken();
+ return Double.NaN;
+ }
+ try {
+ final double result = Double.parseDouble(currentToken);
+ nextToken();
+ return result;
+ } catch (NumberFormatException e) {
+ throw floatParseException(e);
+ }
+ }
+
+ /**
+ * If the next token is a float, consume it and return its value.
+ * Otherwise, throw a {@link ParseException}.
+ */
+ public float consumeFloat() throws ParseException {
+ // We need to parse infinity and nan separately because
+ // Float.parseFloat() does not accept "inf", "infinity", or "nan".
+ if (FLOAT_INFINITY.matcher(currentToken).matches()) {
+ final boolean negative = currentToken.startsWith("-");
+ nextToken();
+ return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
+ }
+ if (FLOAT_NAN.matcher(currentToken).matches()) {
+ nextToken();
+ return Float.NaN;
+ }
+ try {
+ final float result = Float.parseFloat(currentToken);
+ nextToken();
+ return result;
+ } catch (NumberFormatException e) {
+ throw floatParseException(e);
+ }
+ }
+
+ /**
+ * If the next token is a boolean, consume it and return its value.
+ * Otherwise, throw a {@link ParseException}.
+ */
+ public boolean consumeBoolean() throws ParseException {
+ if (currentToken.equals("true") ||
+ currentToken.equals("t") ||
+ currentToken.equals("1")) {
+ nextToken();
+ return true;
+ } else if (currentToken.equals("false") ||
+ currentToken.equals("f") ||
+ currentToken.equals("0")) {
+ nextToken();
+ return false;
+ } else {
+ throw parseException("Expected \"true\" or \"false\".");
+ }
+ }
+
+ /**
+ * If the next token is a string, consume it and return its (unescaped)
+ * value. Otherwise, throw a {@link ParseException}.
+ */
+ public String consumeString() throws ParseException {
+ return consumeByteString().toStringUtf8();
+ }
+
+ /**
+ * If the next token is a string, consume it, unescape it as a
+ * {@link ByteString}, and return it. Otherwise, throw a
+ * {@link ParseException}.
+ */
+ public ByteString consumeByteString() throws ParseException {
+ List<ByteString> list = new ArrayList<ByteString>();
+ consumeByteString(list);
+ while (currentToken.startsWith("'") || currentToken.startsWith("\"")) {
+ consumeByteString(list);
+ }
+ return ByteString.copyFrom(list);
+ }
+
+ /**
+ * Like {@link #consumeByteString()} but adds each token of the string to
+ * the given list. String literals (whether bytes or text) may come in
+ * multiple adjacent tokens which are automatically concatenated, like in
+ * C or Python.
+ */
+ private void consumeByteString(List<ByteString> list) throws ParseException {
+ final char quote = currentToken.length() > 0 ? currentToken.charAt(0)
+ : '\0';
+ if (quote != '\"' && quote != '\'') {
+ throw parseException("Expected string.");
+ }
+
+ if (currentToken.length() < 2 ||
+ currentToken.charAt(currentToken.length() - 1) != quote) {
+ throw parseException("String missing ending quote.");
+ }
+
+ try {
+ final String escaped =
+ currentToken.substring(1, currentToken.length() - 1);
+ final ByteString result = unescapeBytes(escaped);
+ nextToken();
+ list.add(result);
+ } catch (InvalidEscapeSequenceException e) {
+ throw parseException(e.getMessage());
+ }
+ }
+
+ /**
+ * Returns a {@link ParseException} with the current line and column
+ * numbers in the description, suitable for throwing.
+ */
+ public ParseException parseException(final String description) {
+ // Note: People generally prefer one-based line and column numbers.
+ return new ParseException(
+ (line + 1) + ":" + (column + 1) + ": " + description);
+ }
+
+ /**
+ * Returns a {@link ParseException} with the line and column numbers of
+ * the previous token in the description, suitable for throwing.
+ */
+ public ParseException parseExceptionPreviousToken(
+ final String description) {
+ // Note: People generally prefer one-based line and column numbers.
+ return new ParseException(
+ (previousLine + 1) + ":" + (previousColumn + 1) + ": " + description);
+ }
+
+ /**
+ * Constructs an appropriate {@link ParseException} for the given
+ * {@code NumberFormatException} when trying to parse an integer.
+ */
+ private ParseException integerParseException(
+ final NumberFormatException e) {
+ return parseException("Couldn't parse integer: " + e.getMessage());
+ }
+
+ /**
+ * Constructs an appropriate {@link ParseException} for the given
+ * {@code NumberFormatException} when trying to parse a float or double.
+ */
+ private ParseException floatParseException(final NumberFormatException e) {
+ return parseException("Couldn't parse number: " + e.getMessage());
+ }
+ }
+
+ /** Thrown when parsing an invalid text format message. */
+ public static class ParseException extends IOException {
+ private static final long serialVersionUID = 3196188060225107702L;
+
+ public ParseException(final String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Parse a text-format message from {@code input} and merge the contents
+ * into {@code builder}.
+ */
+ public static void merge(final Readable input,
+ final Message.Builder builder)
+ throws IOException {
+ merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+ }
+
+ /**
+ * Parse a text-format message from {@code input} and merge the contents
+ * into {@code builder}.
+ */
+ public static void merge(final CharSequence input,
+ final Message.Builder builder)
+ throws ParseException {
+ merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+ }
+
+ /**
+ * Parse a text-format message from {@code input} and merge the contents
+ * into {@code builder}. Extensions will be recognized if they are
+ * registered in {@code extensionRegistry}.
+ */
+ public static void merge(final Readable input,
+ final ExtensionRegistry extensionRegistry,
+ final Message.Builder builder)
+ throws IOException {
+ // Read the entire input to a String then parse that.
+
+ // If StreamTokenizer were not quite so crippled, or if there were a kind
+ // of Reader that could read in chunks that match some particular regex,
+ // or if we wanted to write a custom Reader to tokenize our stream, then
+ // we would not have to read to one big String. Alas, none of these is
+ // the case. Oh well.
+
+ merge(toStringBuilder(input), extensionRegistry, builder);
+ }
+
+ private static final int BUFFER_SIZE = 4096;
+
+ // TODO(chrisn): See if working around java.io.Reader#read(CharBuffer)
+ // overhead is worthwhile
+ private static StringBuilder toStringBuilder(final Readable input)
+ throws IOException {
+ final StringBuilder text = new StringBuilder();
+ final CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
+ while (true) {
+ final int n = input.read(buffer);
+ if (n == -1) {
+ break;
+ }
+ buffer.flip();
+ text.append(buffer, 0, n);
+ }
+ return text;
+ }
+
+ /**
+ * Parse a text-format message from {@code input} and merge the contents
+ * into {@code builder}. Extensions will be recognized if they are
+ * registered in {@code extensionRegistry}.
+ */
+ public static void merge(final CharSequence input,
+ final ExtensionRegistry extensionRegistry,
+ final Message.Builder builder)
+ throws ParseException {
+ final Tokenizer tokenizer = new Tokenizer(input);
+
+ while (!tokenizer.atEnd()) {
+ mergeField(tokenizer, extensionRegistry, builder);
+ }
+ }
+
+ /**
+ * Parse a single field from {@code tokenizer} and merge it into
+ * {@code builder}.
+ */
+ private static void mergeField(final Tokenizer tokenizer,
+ final ExtensionRegistry extensionRegistry,
+ final Message.Builder builder)
+ throws ParseException {
+ FieldDescriptor field;
+ final Descriptor type = builder.getDescriptorForType();
+ ExtensionRegistry.ExtensionInfo extension = null;
+
+ if (tokenizer.tryConsume("[")) {
+ // An extension.
+ final StringBuilder name =
+ new StringBuilder(tokenizer.consumeIdentifier());
+ while (tokenizer.tryConsume(".")) {
+ name.append('.');
+ name.append(tokenizer.consumeIdentifier());
+ }
+
+ extension = extensionRegistry.findExtensionByName(name.toString());
+
+ if (extension == null) {
+ throw tokenizer.parseExceptionPreviousToken(
+ "Extension \"" + name + "\" not found in the ExtensionRegistry.");
+ } else if (extension.descriptor.getContainingType() != type) {
+ throw tokenizer.parseExceptionPreviousToken(
+ "Extension \"" + name + "\" does not extend message type \"" +
+ type.getFullName() + "\".");
+ }
+
+ tokenizer.consume("]");
+
+ field = extension.descriptor;
+ } else {
+ final String name = tokenizer.consumeIdentifier();
+ field = type.findFieldByName(name);
+
+ // Group names are expected to be capitalized as they appear in the
+ // .proto file, which actually matches their type names, not their field
+ // names.
+ if (field == null) {
+ // Explicitly specify US locale so that this code does not break when
+ // executing in Turkey.
+ final String lowerName = name.toLowerCase(Locale.US);
+ field = type.findFieldByName(lowerName);
+ // If the case-insensitive match worked but the field is NOT a group,
+ if (field != null && field.getType() != FieldDescriptor.Type.GROUP) {
+ field = null;
+ }
+ }
+ // Again, special-case group names as described above.
+ if (field != null && field.getType() == FieldDescriptor.Type.GROUP &&
+ !field.getMessageType().getName().equals(name)) {
+ field = null;
+ }
+
+ if (field == null) {
+ throw tokenizer.parseExceptionPreviousToken(
+ "Message type \"" + type.getFullName() +
+ "\" has no field named \"" + name + "\".");
+ }
+ }
+
+ Object value = null;
+
+ if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+ tokenizer.tryConsume(":"); // optional
+
+ final String endToken;
+ if (tokenizer.tryConsume("<")) {
+ endToken = ">";
+ } else {
+ tokenizer.consume("{");
+ endToken = "}";
+ }
+
+ final Message.Builder subBuilder;
+ if (extension == null) {
+ subBuilder = builder.newBuilderForField(field);
+ } else {
+ subBuilder = extension.defaultInstance.newBuilderForType();
+ }
+
+ while (!tokenizer.tryConsume(endToken)) {
+ if (tokenizer.atEnd()) {
+ throw tokenizer.parseException(
+ "Expected \"" + endToken + "\".");
+ }
+ mergeField(tokenizer, extensionRegistry, subBuilder);
+ }
+
+ value = subBuilder.build();
+
+ } else {
+ tokenizer.consume(":");
+
+ switch (field.getType()) {
+ case INT32:
+ case SINT32:
+ case SFIXED32:
+ value = tokenizer.consumeInt32();
+ break;
+
+ case INT64:
+ case SINT64:
+ case SFIXED64:
+ value = tokenizer.consumeInt64();
+ break;
+
+ case UINT32:
+ case FIXED32:
+ value = tokenizer.consumeUInt32();
+ break;
+
+ case UINT64:
+ case FIXED64:
+ value = tokenizer.consumeUInt64();
+ break;
+
+ case FLOAT:
+ value = tokenizer.consumeFloat();
+ break;
+
+ case DOUBLE:
+ value = tokenizer.consumeDouble();
+ break;
+
+ case BOOL:
+ value = tokenizer.consumeBoolean();
+ break;
+
+ case STRING:
+ value = tokenizer.consumeString();
+ break;
+
+ case BYTES:
+ value = tokenizer.consumeByteString();
+ break;
+
+ case ENUM:
+ final EnumDescriptor enumType = field.getEnumType();
+
+ if (tokenizer.lookingAtInteger()) {
+ final int number = tokenizer.consumeInt32();
+ value = enumType.findValueByNumber(number);
+ if (value == null) {
+ throw tokenizer.parseExceptionPreviousToken(
+ "Enum type \"" + enumType.getFullName() +
+ "\" has no value with number " + number + '.');
+ }
+ } else {
+ final String id = tokenizer.consumeIdentifier();
+ value = enumType.findValueByName(id);
+ if (value == null) {
+ throw tokenizer.parseExceptionPreviousToken(
+ "Enum type \"" + enumType.getFullName() +
+ "\" has no value named \"" + id + "\".");
+ }
+ }
+
+ break;
+
+ case MESSAGE:
+ case GROUP:
+ throw new RuntimeException("Can't get here.");
+ }
+ }
+
+ if (field.isRepeated()) {
+ builder.addRepeatedField(field, value);
+ } else {
+ builder.setField(field, value);
+ }
+ }
+
+ // =================================================================
+ // Utility functions
+ //
+ // Some of these methods are package-private because Descriptors.java uses
+ // them.
+
+ /**
+ * Escapes bytes in the format used in protocol buffer text format, which
+ * is the same as the format used for C string literals. All bytes
+ * that are not printable 7-bit ASCII characters are escaped, as well as
+ * backslash, single-quote, and double-quote characters. Characters for
+ * which no defined short-hand escape sequence is defined will be escaped
+ * using 3-digit octal sequences.
+ */
+ static String escapeBytes(final ByteString input) {
+ final StringBuilder builder = new StringBuilder(input.size());
+ for (int i = 0; i < input.size(); i++) {
+ final byte b = input.byteAt(i);
+ switch (b) {
+ // Java does not recognize \a or \v, apparently.
+ case 0x07: builder.append("\\a" ); break;
+ case '\b': builder.append("\\b" ); break;
+ case '\f': builder.append("\\f" ); break;
+ case '\n': builder.append("\\n" ); break;
+ case '\r': builder.append("\\r" ); break;
+ case '\t': builder.append("\\t" ); break;
+ case 0x0b: builder.append("\\v" ); break;
+ case '\\': builder.append("\\\\"); break;
+ case '\'': builder.append("\\\'"); break;
+ case '"' : builder.append("\\\""); break;
+ default:
+ // Note: Bytes with the high-order bit set should be escaped. Since
+ // bytes are signed, such bytes will compare less than 0x20, hence
+ // the following line is correct.
+ if (b >= 0x20) {
+ builder.append((char) b);
+ } else {
+ builder.append('\\');
+ builder.append((char) ('0' + ((b >>> 6) & 3)));
+ builder.append((char) ('0' + ((b >>> 3) & 7)));
+ builder.append((char) ('0' + (b & 7)));
+ }
+ break;
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Un-escape a byte sequence as escaped using
+ * {@link #escapeBytes(ByteString)}. Two-digit hex escapes (starting with
+ * "\x") are also recognized.
+ */
+ static ByteString unescapeBytes(final CharSequence charString)
+ throws InvalidEscapeSequenceException {
+ // First convert the Java characater sequence to UTF-8 bytes.
+ ByteString input = ByteString.copyFromUtf8(charString.toString());
+ // Then unescape certain byte sequences introduced by ASCII '\\'. The valid
+ // escapes can all be expressed with ASCII characters, so it is safe to
+ // operate on bytes here.
+ //
+ // Unescaping the input byte array will result in a byte sequence that's no
+ // longer than the input. That's because each escape sequence is between
+ // two and four bytes long and stands for a single byte.
+ final byte[] result = new byte[input.size()];
+ int pos = 0;
+ for (int i = 0; i < input.size(); i++) {
+ byte c = input.byteAt(i);
+ if (c == '\\') {
+ if (i + 1 < input.size()) {
+ ++i;
+ c = input.byteAt(i);
+ if (isOctal(c)) {
+ // Octal escape.
+ int code = digitValue(c);
+ if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) {
+ ++i;
+ code = code * 8 + digitValue(input.byteAt(i));
+ }
+ if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) {
+ ++i;
+ code = code * 8 + digitValue(input.byteAt(i));
+ }
+ // TODO: Check that 0 <= code && code <= 0xFF.
+ result[pos++] = (byte)code;
+ } else {
+ switch (c) {
+ case 'a' : result[pos++] = 0x07; break;
+ case 'b' : result[pos++] = '\b'; break;
+ case 'f' : result[pos++] = '\f'; break;
+ case 'n' : result[pos++] = '\n'; break;
+ case 'r' : result[pos++] = '\r'; break;
+ case 't' : result[pos++] = '\t'; break;
+ case 'v' : result[pos++] = 0x0b; break;
+ case '\\': result[pos++] = '\\'; break;
+ case '\'': result[pos++] = '\''; break;
+ case '"' : result[pos++] = '\"'; break;
+
+ case 'x':
+ // hex escape
+ int code = 0;
+ if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) {
+ ++i;
+ code = digitValue(input.byteAt(i));
+ } else {
+ throw new InvalidEscapeSequenceException(
+ "Invalid escape sequence: '\\x' with no digits");
+ }
+ if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) {
+ ++i;
+ code = code * 16 + digitValue(input.byteAt(i));
+ }
+ result[pos++] = (byte)code;
+ break;
+
+ default:
+ throw new InvalidEscapeSequenceException(
+ "Invalid escape sequence: '\\" + (char)c + '\'');
+ }
+ }
+ } else {
+ throw new InvalidEscapeSequenceException(
+ "Invalid escape sequence: '\\' at end of string.");
+ }
+ } else {
+ result[pos++] = c;
+ }
+ }
+
+ return ByteString.copyFrom(result, 0, pos);
+ }
+
+ /**
+ * Thrown by {@link TextFormat#unescapeBytes} and
+ * {@link TextFormat#unescapeText} when an invalid escape sequence is seen.
+ */
+ static class InvalidEscapeSequenceException extends IOException {
+ private static final long serialVersionUID = -8164033650142593304L;
+
+ InvalidEscapeSequenceException(final String description) {
+ super(description);
+ }
+ }
+
+ /**
+ * Like {@link #escapeBytes(ByteString)}, but escapes a text string.
+ * Non-ASCII characters are first encoded as UTF-8, then each byte is escaped
+ * individually as a 3-digit octal escape. Yes, it's weird.
+ */
+ static String escapeText(final String input) {
+ return escapeBytes(ByteString.copyFromUtf8(input));
+ }
+
+ /**
+ * Un-escape a text string as escaped using {@link #escapeText(String)}.
+ * Two-digit hex escapes (starting with "\x") are also recognized.
+ */
+ static String unescapeText(final String input)
+ throws InvalidEscapeSequenceException {
+ return unescapeBytes(input).toStringUtf8();
+ }
+
+ /** Is this an octal digit? */
+ private static boolean isOctal(final byte c) {
+ return '0' <= c && c <= '7';
+ }
+
+ /** Is this a hex digit? */
+ private static boolean isHex(final byte c) {
+ return ('0' <= c && c <= '9') ||
+ ('a' <= c && c <= 'f') ||
+ ('A' <= c && c <= 'F');
+ }
+
+ /**
+ * Interpret a character as a digit (in any base up to 36) and return the
+ * numeric value. This is like {@code Character.digit()} but we don't accept
+ * non-ASCII digits.
+ */
+ private static int digitValue(final byte c) {
+ if ('0' <= c && c <= '9') {
+ return c - '0';
+ } else if ('a' <= c && c <= 'z') {
+ return c - 'a' + 10;
+ } else {
+ return c - 'A' + 10;
+ }
+ }
+
+ /**
+ * Parse a 32-bit signed integer from the text. Unlike the Java standard
+ * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+ * and "0" to signify hexidecimal and octal numbers, respectively.
+ */
+ static int parseInt32(final String text) throws NumberFormatException {
+ return (int) parseInteger(text, true, false);
+ }
+
+ /**
+ * Parse a 32-bit unsigned integer from the text. Unlike the Java standard
+ * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+ * and "0" to signify hexidecimal and octal numbers, respectively. The
+ * result is coerced to a (signed) {@code int} when returned since Java has
+ * no unsigned integer type.
+ */
+ static int parseUInt32(final String text) throws NumberFormatException {
+ return (int) parseInteger(text, false, false);
+ }
+
+ /**
+ * Parse a 64-bit signed integer from the text. Unlike the Java standard
+ * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+ * and "0" to signify hexidecimal and octal numbers, respectively.
+ */
+ static long parseInt64(final String text) throws NumberFormatException {
+ return parseInteger(text, true, true);
+ }
+
+ /**
+ * Parse a 64-bit unsigned integer from the text. Unlike the Java standard
+ * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+ * and "0" to signify hexidecimal and octal numbers, respectively. The
+ * result is coerced to a (signed) {@code long} when returned since Java has
+ * no unsigned long type.
+ */
+ static long parseUInt64(final String text) throws NumberFormatException {
+ return parseInteger(text, false, true);
+ }
+
+ private static long parseInteger(final String text,
+ final boolean isSigned,
+ final boolean isLong)
+ throws NumberFormatException {
+ int pos = 0;
+
+ boolean negative = false;
+ if (text.startsWith("-", pos)) {
+ if (!isSigned) {
+ throw new NumberFormatException("Number must be positive: " + text);
+ }
+ ++pos;
+ negative = true;
+ }
+
+ int radix = 10;
+ if (text.startsWith("0x", pos)) {
+ pos += 2;
+ radix = 16;
+ } else if (text.startsWith("0", pos)) {
+ radix = 8;
+ }
+
+ final String numberText = text.substring(pos);
+
+ long result = 0;
+ if (numberText.length() < 16) {
+ // Can safely assume no overflow.
+ result = Long.parseLong(numberText, radix);
+ if (negative) {
+ result = -result;
+ }
+
+ // Check bounds.
+ // No need to check for 64-bit numbers since they'd have to be 16 chars
+ // or longer to overflow.
+ if (!isLong) {
+ if (isSigned) {
+ if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
+ throw new NumberFormatException(
+ "Number out of range for 32-bit signed integer: " + text);
+ }
+ } else {
+ if (result >= (1L << 32) || result < 0) {
+ throw new NumberFormatException(
+ "Number out of range for 32-bit unsigned integer: " + text);
+ }
+ }
+ }
+ } else {
+ BigInteger bigValue = new BigInteger(numberText, radix);
+ if (negative) {
+ bigValue = bigValue.negate();
+ }
+
+ // Check bounds.
+ if (!isLong) {
+ if (isSigned) {
+ if (bigValue.bitLength() > 31) {
+ throw new NumberFormatException(
+ "Number out of range for 32-bit signed integer: " + text);
+ }
+ } else {
+ if (bigValue.bitLength() > 32) {
+ throw new NumberFormatException(
+ "Number out of range for 32-bit unsigned integer: " + text);
+ }
+ }
+ } else {
+ if (isSigned) {
+ if (bigValue.bitLength() > 63) {
+ throw new NumberFormatException(
+ "Number out of range for 64-bit signed integer: " + text);
+ }
+ } else {
+ if (bigValue.bitLength() > 64) {
+ throw new NumberFormatException(
+ "Number out of range for 64-bit unsigned integer: " + text);
+ }
+ }
+ }
+
+ result = bigValue.longValue();
+ }
+
+ return result;
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UninitializedMessageException.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UninitializedMessageException.java
new file mode 100644
index 0000000..8743c12
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UninitializedMessageException.java
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Thrown when attempting to build a protocol message that is missing required
+ * fields. This is a {@code RuntimeException} because it normally represents
+ * a programming error: it happens when some code which constructs a message
+ * fails to set all the fields. {@code parseFrom()} methods <b>do not</b>
+ * throw this; they throw an {@link InvalidProtocolBufferException} if
+ * required fields are missing, because it is not a programming error to
+ * receive an incomplete message. In other words,
+ * {@code UninitializedMessageException} should never be thrown by correct
+ * code, but {@code InvalidProtocolBufferException} might be.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class UninitializedMessageException extends RuntimeException {
+ private static final long serialVersionUID = -7466929953374883507L;
+
+ public UninitializedMessageException(final MessageLite message) {
+ super("Message was missing required fields. (Lite runtime could not " +
+ "determine which fields were missing).");
+ missingFields = null;
+ }
+
+ public UninitializedMessageException(final List<String> missingFields) {
+ super(buildDescription(missingFields));
+ this.missingFields = missingFields;
+ }
+
+ private final List<String> missingFields;
+
+ /**
+ * Get a list of human-readable names of required fields missing from this
+ * message. Each name is a full path to a field, e.g. "foo.bar[5].baz".
+ * Returns null if the lite runtime was used, since it lacks the ability to
+ * find missing fields.
+ */
+ public List<String> getMissingFields() {
+ return Collections.unmodifiableList(missingFields);
+ }
+
+ /**
+ * Converts this exception to an {@link InvalidProtocolBufferException}.
+ * When a parsed message is missing required fields, this should be thrown
+ * instead of {@code UninitializedMessageException}.
+ */
+ public InvalidProtocolBufferException asInvalidProtocolBufferException() {
+ return new InvalidProtocolBufferException(getMessage());
+ }
+
+ /** Construct the description string for this exception. */
+ private static String buildDescription(final List<String> missingFields) {
+ final StringBuilder description =
+ new StringBuilder("Message missing required fields: ");
+ boolean first = true;
+ for (final String field : missingFields) {
+ if (first) {
+ first = false;
+ } else {
+ description.append(", ");
+ }
+ description.append(field);
+ }
+ return description.toString();
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UnknownFieldSet.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
new file mode 100644
index 0000000..26a15d0
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
@@ -0,0 +1,953 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * {@code UnknownFieldSet} is used to keep track of fields which were seen when
+ * parsing a protocol message but whose field numbers or types are unrecognized.
+ * This most frequently occurs when new fields are added to a message type
+ * and then messages containing those feilds are read by old software that was
+ * compiled before the new types were added.
+ *
+ * <p>Every {@link Message} contains an {@code UnknownFieldSet} (and every
+ * {@link Message.Builder} contains an {@link Builder}).
+ *
+ * <p>Most users will never need to use this class.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class UnknownFieldSet implements MessageLite {
+ private UnknownFieldSet() {}
+
+ /** Create a new {@link Builder}. */
+ public static Builder newBuilder() {
+ return Builder.create();
+ }
+
+ /**
+ * Create a new {@link Builder} and initialize it to be a copy
+ * of {@code copyFrom}.
+ */
+ public static Builder newBuilder(final UnknownFieldSet copyFrom) {
+ return newBuilder().mergeFrom(copyFrom);
+ }
+
+ /** Get an empty {@code UnknownFieldSet}. */
+ public static UnknownFieldSet getDefaultInstance() {
+ return defaultInstance;
+ }
+ public UnknownFieldSet getDefaultInstanceForType() {
+ return defaultInstance;
+ }
+ private static final UnknownFieldSet defaultInstance =
+ new UnknownFieldSet(Collections.<Integer, Field>emptyMap());
+
+ /**
+ * Construct an {@code UnknownFieldSet} around the given map. The map is
+ * expected to be immutable.
+ */
+ private UnknownFieldSet(final Map<Integer, Field> fields) {
+ this.fields = fields;
+ }
+ private Map<Integer, Field> fields;
+
+ @Override
+ public boolean equals(final Object other) {
+ if (this == other) {
+ return true;
+ }
+ return (other instanceof UnknownFieldSet) &&
+ fields.equals(((UnknownFieldSet) other).fields);
+ }
+
+ @Override
+ public int hashCode() {
+ return fields.hashCode();
+ }
+
+ /** Get a map of fields in the set by number. */
+ public Map<Integer, Field> asMap() {
+ return fields;
+ }
+
+ /** Check if the given field number is present in the set. */
+ public boolean hasField(final int number) {
+ return fields.containsKey(number);
+ }
+
+ /**
+ * Get a field by number. Returns an empty field if not present. Never
+ * returns {@code null}.
+ */
+ public Field getField(final int number) {
+ final Field result = fields.get(number);
+ return (result == null) ? Field.getDefaultInstance() : result;
+ }
+
+ /** Serializes the set and writes it to {@code output}. */
+ public void writeTo(final CodedOutputStream output) throws IOException {
+ for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+ entry.getValue().writeTo(entry.getKey(), output);
+ }
+ }
+
+ /**
+ * Converts the set to a string in protocol buffer text format. This is
+ * just a trivial wrapper around
+ * {@link TextFormat#printToString(UnknownFieldSet)}.
+ */
+ @Override
+ public String toString() {
+ return TextFormat.printToString(this);
+ }
+
+ /**
+ * Serializes the message to a {@code ByteString} and returns it. This is
+ * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
+ */
+ public ByteString toByteString() {
+ try {
+ final ByteString.CodedBuilder out =
+ ByteString.newCodedBuilder(getSerializedSize());
+ writeTo(out.getCodedOutput());
+ return out.build();
+ } catch (final IOException e) {
+ throw new RuntimeException(
+ "Serializing to a ByteString threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ /**
+ * Serializes the message to a {@code byte} array and returns it. This is
+ * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
+ */
+ public byte[] toByteArray() {
+ try {
+ final byte[] result = new byte[getSerializedSize()];
+ final CodedOutputStream output = CodedOutputStream.newInstance(result);
+ writeTo(output);
+ output.checkNoSpaceLeft();
+ return result;
+ } catch (final IOException e) {
+ throw new RuntimeException(
+ "Serializing to a byte array threw an IOException " +
+ "(should never happen).", e);
+ }
+ }
+
+ /**
+ * Serializes the message and writes it to {@code output}. This is just a
+ * trivial wrapper around {@link #writeTo(CodedOutputStream)}.
+ */
+ public void writeTo(final OutputStream output) throws IOException {
+ final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
+ writeTo(codedOutput);
+ codedOutput.flush();
+ }
+
+ public void writeDelimitedTo(OutputStream output) throws IOException {
+ final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
+ codedOutput.writeRawVarint32(getSerializedSize());
+ writeTo(codedOutput);
+ codedOutput.flush();
+ }
+
+ /** Get the number of bytes required to encode this set. */
+ public int getSerializedSize() {
+ int result = 0;
+ for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+ result += entry.getValue().getSerializedSize(entry.getKey());
+ }
+ return result;
+ }
+
+ /**
+ * Serializes the set and writes it to {@code output} using
+ * {@code MessageSet} wire format.
+ */
+ public void writeAsMessageSetTo(final CodedOutputStream output)
+ throws IOException {
+ for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+ entry.getValue().writeAsMessageSetExtensionTo(
+ entry.getKey(), output);
+ }
+ }
+
+ /**
+ * Get the number of bytes required to encode this set using
+ * {@code MessageSet} wire format.
+ */
+ public int getSerializedSizeAsMessageSet() {
+ int result = 0;
+ for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+ result += entry.getValue().getSerializedSizeAsMessageSetExtension(
+ entry.getKey());
+ }
+ return result;
+ }
+
+ public boolean isInitialized() {
+ // UnknownFieldSets do not have required fields, so they are always
+ // initialized.
+ return true;
+ }
+
+ /** Parse an {@code UnknownFieldSet} from the given input stream. */
+ public static UnknownFieldSet parseFrom(final CodedInputStream input)
+ throws IOException {
+ return newBuilder().mergeFrom(input).build();
+ }
+
+ /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
+ public static UnknownFieldSet parseFrom(final ByteString data)
+ throws InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).build();
+ }
+
+ /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
+ public static UnknownFieldSet parseFrom(final byte[] data)
+ throws InvalidProtocolBufferException {
+ return newBuilder().mergeFrom(data).build();
+ }
+
+ /** Parse an {@code UnknownFieldSet} from {@code input} and return it. */
+ public static UnknownFieldSet parseFrom(final InputStream input)
+ throws IOException {
+ return newBuilder().mergeFrom(input).build();
+ }
+
+ public Builder newBuilderForType() {
+ return newBuilder();
+ }
+
+ public Builder toBuilder() {
+ return newBuilder().mergeFrom(this);
+ }
+
+ /**
+ * Builder for {@link UnknownFieldSet}s.
+ *
+ * <p>Note that this class maintains {@link Field.Builder}s for all fields
+ * in the set. Thus, adding one element to an existing {@link Field} does not
+ * require making a copy. This is important for efficient parsing of
+ * unknown repeated fields. However, it implies that {@link Field}s cannot
+ * be constructed independently, nor can two {@link UnknownFieldSet}s share
+ * the same {@code Field} object.
+ *
+ * <p>Use {@link UnknownFieldSet#newBuilder()} to construct a {@code Builder}.
+ */
+ public static final class Builder implements MessageLite.Builder {
+ // This constructor should never be called directly (except from 'create').
+ private Builder() {}
+
+ private Map<Integer, Field> fields;
+
+ // Optimization: We keep around a builder for the last field that was
+ // modified so that we can efficiently add to it multiple times in a
+ // row (important when parsing an unknown repeated field).
+ private int lastFieldNumber;
+ private Field.Builder lastField;
+
+ private static Builder create() {
+ Builder builder = new Builder();
+ builder.reinitialize();
+ return builder;
+ }
+
+ /**
+ * Get a field builder for the given field number which includes any
+ * values that already exist.
+ */
+ private Field.Builder getFieldBuilder(final int number) {
+ if (lastField != null) {
+ if (number == lastFieldNumber) {
+ return lastField;
+ }
+ // Note: addField() will reset lastField and lastFieldNumber.
+ addField(lastFieldNumber, lastField.build());
+ }
+ if (number == 0) {
+ return null;
+ } else {
+ final Field existing = fields.get(number);
+ lastFieldNumber = number;
+ lastField = Field.newBuilder();
+ if (existing != null) {
+ lastField.mergeFrom(existing);
+ }
+ return lastField;
+ }
+ }
+
+ /**
+ * Build the {@link UnknownFieldSet} and return it.
+ *
+ * <p>Once {@code build()} has been called, the {@code Builder} will no
+ * longer be usable. Calling any method after {@code build()} will result
+ * in undefined behavior and can cause a {@code NullPointerException} to be
+ * thrown.
+ */
+ public UnknownFieldSet build() {
+ getFieldBuilder(0); // Force lastField to be built.
+ final UnknownFieldSet result;
+ if (fields.isEmpty()) {
+ result = getDefaultInstance();
+ } else {
+ result = new UnknownFieldSet(Collections.unmodifiableMap(fields));
+ }
+ fields = null;
+ return result;
+ }
+
+ public UnknownFieldSet buildPartial() {
+ // No required fields, so this is the same as build().
+ return build();
+ }
+
+ @Override
+ public Builder clone() {
+ getFieldBuilder(0); // Force lastField to be built.
+ return UnknownFieldSet.newBuilder().mergeFrom(
+ new UnknownFieldSet(fields));
+ }
+
+ public UnknownFieldSet getDefaultInstanceForType() {
+ return UnknownFieldSet.getDefaultInstance();
+ }
+
+ private void reinitialize() {
+ fields = Collections.emptyMap();
+ lastFieldNumber = 0;
+ lastField = null;
+ }
+
+ /** Reset the builder to an empty set. */
+ public Builder clear() {
+ reinitialize();
+ return this;
+ }
+
+ /**
+ * Merge the fields from {@code other} into this set. If a field number
+ * exists in both sets, {@code other}'s values for that field will be
+ * appended to the values in this set.
+ */
+ public Builder mergeFrom(final UnknownFieldSet other) {
+ if (other != getDefaultInstance()) {
+ for (final Map.Entry<Integer, Field> entry : other.fields.entrySet()) {
+ mergeField(entry.getKey(), entry.getValue());
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Add a field to the {@code UnknownFieldSet}. If a field with the same
+ * number already exists, the two are merged.
+ */
+ public Builder mergeField(final int number, final Field field) {
+ if (number == 0) {
+ throw new IllegalArgumentException("Zero is not a valid field number.");
+ }
+ if (hasField(number)) {
+ getFieldBuilder(number).mergeFrom(field);
+ } else {
+ // Optimization: We could call getFieldBuilder(number).mergeFrom(field)
+ // in this case, but that would create a copy of the Field object.
+ // We'd rather reuse the one passed to us, so call addField() instead.
+ addField(number, field);
+ }
+ return this;
+ }
+
+ /**
+ * Convenience method for merging a new field containing a single varint
+ * value. This is used in particular when an unknown enum value is
+ * encountered.
+ */
+ public Builder mergeVarintField(final int number, final int value) {
+ if (number == 0) {
+ throw new IllegalArgumentException("Zero is not a valid field number.");
+ }
+ getFieldBuilder(number).addVarint(value);
+ return this;
+ }
+
+ /** Check if the given field number is present in the set. */
+ public boolean hasField(final int number) {
+ if (number == 0) {
+ throw new IllegalArgumentException("Zero is not a valid field number.");
+ }
+ return number == lastFieldNumber || fields.containsKey(number);
+ }
+
+ /**
+ * Add a field to the {@code UnknownFieldSet}. If a field with the same
+ * number already exists, it is removed.
+ */
+ public Builder addField(final int number, final Field field) {
+ if (number == 0) {
+ throw new IllegalArgumentException("Zero is not a valid field number.");
+ }
+ if (lastField != null && lastFieldNumber == number) {
+ // Discard this.
+ lastField = null;
+ lastFieldNumber = 0;
+ }
+ if (fields.isEmpty()) {
+ fields = new TreeMap<Integer,Field>();
+ }
+ fields.put(number, field);
+ return this;
+ }
+
+ /**
+ * Get all present {@code Field}s as an immutable {@code Map}. If more
+ * fields are added, the changes may or may not be reflected in this map.
+ */
+ public Map<Integer, Field> asMap() {
+ getFieldBuilder(0); // Force lastField to be built.
+ return Collections.unmodifiableMap(fields);
+ }
+
+ /**
+ * Parse an entire message from {@code input} and merge its fields into
+ * this set.
+ */
+ public Builder mergeFrom(final CodedInputStream input) throws IOException {
+ while (true) {
+ final int tag = input.readTag();
+ if (tag == 0 || !mergeFieldFrom(tag, input)) {
+ break;
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Parse a single field from {@code input} and merge it into this set.
+ * @param tag The field's tag number, which was already parsed.
+ * @return {@code false} if the tag is an engroup tag.
+ */
+ public boolean mergeFieldFrom(final int tag, final CodedInputStream input)
+ throws IOException {
+ final int number = WireFormat.getTagFieldNumber(tag);
+ switch (WireFormat.getTagWireType(tag)) {
+ case WireFormat.WIRETYPE_VARINT:
+ getFieldBuilder(number).addVarint(input.readInt64());
+ return true;
+ case WireFormat.WIRETYPE_FIXED64:
+ getFieldBuilder(number).addFixed64(input.readFixed64());
+ return true;
+ case WireFormat.WIRETYPE_LENGTH_DELIMITED:
+ getFieldBuilder(number).addLengthDelimited(input.readBytes());
+ return true;
+ case WireFormat.WIRETYPE_START_GROUP:
+ final Builder subBuilder = newBuilder();
+ input.readGroup(number, subBuilder,
+ ExtensionRegistry.getEmptyRegistry());
+ getFieldBuilder(number).addGroup(subBuilder.build());
+ return true;
+ case WireFormat.WIRETYPE_END_GROUP:
+ return false;
+ case WireFormat.WIRETYPE_FIXED32:
+ getFieldBuilder(number).addFixed32(input.readFixed32());
+ return true;
+ default:
+ throw InvalidProtocolBufferException.invalidWireType();
+ }
+ }
+
+ /**
+ * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the
+ * set being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream)}.
+ */
+ public Builder mergeFrom(final ByteString data)
+ throws InvalidProtocolBufferException {
+ try {
+ final CodedInputStream input = data.newCodedInput();
+ mergeFrom(input);
+ input.checkLastTagWas(0);
+ return this;
+ } catch (final InvalidProtocolBufferException e) {
+ throw e;
+ } catch (final IOException e) {
+ throw new RuntimeException(
+ "Reading from a ByteString threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ /**
+ * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the
+ * set being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream)}.
+ */
+ public Builder mergeFrom(final byte[] data)
+ throws InvalidProtocolBufferException {
+ try {
+ final CodedInputStream input = CodedInputStream.newInstance(data);
+ mergeFrom(input);
+ input.checkLastTagWas(0);
+ return this;
+ } catch (final InvalidProtocolBufferException e) {
+ throw e;
+ } catch (final IOException e) {
+ throw new RuntimeException(
+ "Reading from a byte array threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ /**
+ * Parse an {@code UnknownFieldSet} from {@code input} and merge it with the
+ * set being built. This is just a small wrapper around
+ * {@link #mergeFrom(CodedInputStream)}.
+ */
+ public Builder mergeFrom(final InputStream input) throws IOException {
+ final CodedInputStream codedInput = CodedInputStream.newInstance(input);
+ mergeFrom(codedInput);
+ codedInput.checkLastTagWas(0);
+ return this;
+ }
+
+ public boolean mergeDelimitedFrom(InputStream input)
+ throws IOException {
+ final int firstByte = input.read();
+ if (firstByte == -1) {
+ return false;
+ }
+ final int size = CodedInputStream.readRawVarint32(firstByte, input);
+ final InputStream limitedInput = new LimitedInputStream(input, size);
+ mergeFrom(limitedInput);
+ return true;
+ }
+
+ public boolean mergeDelimitedFrom(
+ InputStream input,
+ ExtensionRegistryLite extensionRegistry) throws IOException {
+ // UnknownFieldSet has no extensions.
+ return mergeDelimitedFrom(input);
+ }
+
+ public Builder mergeFrom(
+ CodedInputStream input,
+ ExtensionRegistryLite extensionRegistry) throws IOException {
+ // UnknownFieldSet has no extensions.
+ return mergeFrom(input);
+ }
+
+ public Builder mergeFrom(
+ ByteString data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ // UnknownFieldSet has no extensions.
+ return mergeFrom(data);
+ }
+
+ public Builder mergeFrom(byte[] data, int off, int len)
+ throws InvalidProtocolBufferException {
+ try {
+ final CodedInputStream input =
+ CodedInputStream.newInstance(data, off, len);
+ mergeFrom(input);
+ input.checkLastTagWas(0);
+ return this;
+ } catch (InvalidProtocolBufferException e) {
+ throw e;
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Reading from a byte array threw an IOException (should " +
+ "never happen).", e);
+ }
+ }
+
+ public Builder mergeFrom(
+ byte[] data,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ // UnknownFieldSet has no extensions.
+ return mergeFrom(data);
+ }
+
+ public Builder mergeFrom(
+ byte[] data, int off, int len,
+ ExtensionRegistryLite extensionRegistry)
+ throws InvalidProtocolBufferException {
+ // UnknownFieldSet has no extensions.
+ return mergeFrom(data, off, len);
+ }
+
+ public Builder mergeFrom(
+ InputStream input,
+ ExtensionRegistryLite extensionRegistry) throws IOException {
+ // UnknownFieldSet has no extensions.
+ return mergeFrom(input);
+ }
+
+ public boolean isInitialized() {
+ // UnknownFieldSets do not have required fields, so they are always
+ // initialized.
+ return true;
+ }
+ }
+
+ /**
+ * Represents a single field in an {@code UnknownFieldSet}.
+ *
+ * <p>A {@code Field} consists of five lists of values. The lists correspond
+ * to the five "wire types" used in the protocol buffer binary format.
+ * The wire type of each field can be determined from the encoded form alone,
+ * without knowing the field's declared type. So, we are able to parse
+ * unknown values at least this far and separate them. Normally, only one
+ * of the five lists will contain any values, since it is impossible to
+ * define a valid message type that declares two different types for the
+ * same field number. However, the code is designed to allow for the case
+ * where the same unknown field number is encountered using multiple different
+ * wire types.
+ *
+ * <p>{@code Field} is an immutable class. To construct one, you must use a
+ * {@link Builder}.
+ *
+ * @see UnknownFieldSet
+ */
+ public static final class Field {
+ private Field() {}
+
+ /** Construct a new {@link Builder}. */
+ public static Builder newBuilder() {
+ return Builder.create();
+ }
+
+ /**
+ * Construct a new {@link Builder} and initialize it to a copy of
+ * {@code copyFrom}.
+ */
+ public static Builder newBuilder(final Field copyFrom) {
+ return newBuilder().mergeFrom(copyFrom);
+ }
+
+ /** Get an empty {@code Field}. */
+ public static Field getDefaultInstance() {
+ return fieldDefaultInstance;
+ }
+ private static final Field fieldDefaultInstance = newBuilder().build();
+
+ /** Get the list of varint values for this field. */
+ public List<Long> getVarintList() { return varint; }
+
+ /** Get the list of fixed32 values for this field. */
+ public List<Integer> getFixed32List() { return fixed32; }
+
+ /** Get the list of fixed64 values for this field. */
+ public List<Long> getFixed64List() { return fixed64; }
+
+ /** Get the list of length-delimited values for this field. */
+ public List<ByteString> getLengthDelimitedList() { return lengthDelimited; }
+
+ /**
+ * Get the list of embedded group values for this field. These are
+ * represented using {@link UnknownFieldSet}s rather than {@link Message}s
+ * since the group's type is presumably unknown.
+ */
+ public List<UnknownFieldSet> getGroupList() { return group; }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof Field)) {
+ return false;
+ }
+ return Arrays.equals(getIdentityArray(),
+ ((Field) other).getIdentityArray());
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(getIdentityArray());
+ }
+
+ /**
+ * Returns the array of objects to be used to uniquely identify this
+ * {@link Field} instance.
+ */
+ private Object[] getIdentityArray() {
+ return new Object[] {
+ varint,
+ fixed32,
+ fixed64,
+ lengthDelimited,
+ group};
+ }
+
+ /**
+ * Serializes the field, including field number, and writes it to
+ * {@code output}.
+ */
+ public void writeTo(final int fieldNumber, final CodedOutputStream output)
+ throws IOException {
+ for (final long value : varint) {
+ output.writeUInt64(fieldNumber, value);
+ }
+ for (final int value : fixed32) {
+ output.writeFixed32(fieldNumber, value);
+ }
+ for (final long value : fixed64) {
+ output.writeFixed64(fieldNumber, value);
+ }
+ for (final ByteString value : lengthDelimited) {
+ output.writeBytes(fieldNumber, value);
+ }
+ for (final UnknownFieldSet value : group) {
+ output.writeGroup(fieldNumber, value);
+ }
+ }
+
+ /**
+ * Get the number of bytes required to encode this field, including field
+ * number.
+ */
+ public int getSerializedSize(final int fieldNumber) {
+ int result = 0;
+ for (final long value : varint) {
+ result += CodedOutputStream.computeUInt64Size(fieldNumber, value);
+ }
+ for (final int value : fixed32) {
+ result += CodedOutputStream.computeFixed32Size(fieldNumber, value);
+ }
+ for (final long value : fixed64) {
+ result += CodedOutputStream.computeFixed64Size(fieldNumber, value);
+ }
+ for (final ByteString value : lengthDelimited) {
+ result += CodedOutputStream.computeBytesSize(fieldNumber, value);
+ }
+ for (final UnknownFieldSet value : group) {
+ result += CodedOutputStream.computeGroupSize(fieldNumber, value);
+ }
+ return result;
+ }
+
+ /**
+ * Serializes the field, including field number, and writes it to
+ * {@code output}, using {@code MessageSet} wire format.
+ */
+ public void writeAsMessageSetExtensionTo(
+ final int fieldNumber,
+ final CodedOutputStream output)
+ throws IOException {
+ for (final ByteString value : lengthDelimited) {
+ output.writeRawMessageSetExtension(fieldNumber, value);
+ }
+ }
+
+ /**
+ * Get the number of bytes required to encode this field, including field
+ * number, using {@code MessageSet} wire format.
+ */
+ public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) {
+ int result = 0;
+ for (final ByteString value : lengthDelimited) {
+ result += CodedOutputStream.computeRawMessageSetExtensionSize(
+ fieldNumber, value);
+ }
+ return result;
+ }
+
+ private List<Long> varint;
+ private List<Integer> fixed32;
+ private List<Long> fixed64;
+ private List<ByteString> lengthDelimited;
+ private List<UnknownFieldSet> group;
+
+ /**
+ * Used to build a {@link Field} within an {@link UnknownFieldSet}.
+ *
+ * <p>Use {@link Field#newBuilder()} to construct a {@code Builder}.
+ */
+ public static final class Builder {
+ // This constructor should never be called directly (except from 'create').
+ private Builder() {}
+
+ private static Builder create() {
+ Builder builder = new Builder();
+ builder.result = new Field();
+ return builder;
+ }
+
+ private Field result;
+
+ /**
+ * Build the field. After {@code build()} has been called, the
+ * {@code Builder} is no longer usable. Calling any other method will
+ * result in undefined behavior and can cause a
+ * {@code NullPointerException} to be thrown.
+ */
+ public Field build() {
+ if (result.varint == null) {
+ result.varint = Collections.emptyList();
+ } else {
+ result.varint = Collections.unmodifiableList(result.varint);
+ }
+ if (result.fixed32 == null) {
+ result.fixed32 = Collections.emptyList();
+ } else {
+ result.fixed32 = Collections.unmodifiableList(result.fixed32);
+ }
+ if (result.fixed64 == null) {
+ result.fixed64 = Collections.emptyList();
+ } else {
+ result.fixed64 = Collections.unmodifiableList(result.fixed64);
+ }
+ if (result.lengthDelimited == null) {
+ result.lengthDelimited = Collections.emptyList();
+ } else {
+ result.lengthDelimited =
+ Collections.unmodifiableList(result.lengthDelimited);
+ }
+ if (result.group == null) {
+ result.group = Collections.emptyList();
+ } else {
+ result.group = Collections.unmodifiableList(result.group);
+ }
+
+ final Field returnMe = result;
+ result = null;
+ return returnMe;
+ }
+
+ /** Discard the field's contents. */
+ public Builder clear() {
+ result = new Field();
+ return this;
+ }
+
+ /**
+ * Merge the values in {@code other} into this field. For each list
+ * of values, {@code other}'s values are append to the ones in this
+ * field.
+ */
+ public Builder mergeFrom(final Field other) {
+ if (!other.varint.isEmpty()) {
+ if (result.varint == null) {
+ result.varint = new ArrayList<Long>();
+ }
+ result.varint.addAll(other.varint);
+ }
+ if (!other.fixed32.isEmpty()) {
+ if (result.fixed32 == null) {
+ result.fixed32 = new ArrayList<Integer>();
+ }
+ result.fixed32.addAll(other.fixed32);
+ }
+ if (!other.fixed64.isEmpty()) {
+ if (result.fixed64 == null) {
+ result.fixed64 = new ArrayList<Long>();
+ }
+ result.fixed64.addAll(other.fixed64);
+ }
+ if (!other.lengthDelimited.isEmpty()) {
+ if (result.lengthDelimited == null) {
+ result.lengthDelimited = new ArrayList<ByteString>();
+ }
+ result.lengthDelimited.addAll(other.lengthDelimited);
+ }
+ if (!other.group.isEmpty()) {
+ if (result.group == null) {
+ result.group = new ArrayList<UnknownFieldSet>();
+ }
+ result.group.addAll(other.group);
+ }
+ return this;
+ }
+
+ /** Add a varint value. */
+ public Builder addVarint(final long value) {
+ if (result.varint == null) {
+ result.varint = new ArrayList<Long>();
+ }
+ result.varint.add(value);
+ return this;
+ }
+
+ /** Add a fixed32 value. */
+ public Builder addFixed32(final int value) {
+ if (result.fixed32 == null) {
+ result.fixed32 = new ArrayList<Integer>();
+ }
+ result.fixed32.add(value);
+ return this;
+ }
+
+ /** Add a fixed64 value. */
+ public Builder addFixed64(final long value) {
+ if (result.fixed64 == null) {
+ result.fixed64 = new ArrayList<Long>();
+ }
+ result.fixed64.add(value);
+ return this;
+ }
+
+ /** Add a length-delimited value. */
+ public Builder addLengthDelimited(final ByteString value) {
+ if (result.lengthDelimited == null) {
+ result.lengthDelimited = new ArrayList<ByteString>();
+ }
+ result.lengthDelimited.add(value);
+ return this;
+ }
+
+ /** Add an embedded group. */
+ public Builder addGroup(final UnknownFieldSet value) {
+ if (result.group == null) {
+ result.group = new ArrayList<UnknownFieldSet>();
+ }
+ result.group.add(value);
+ return this;
+ }
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
new file mode 100644
index 0000000..83e5c79
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
@@ -0,0 +1,146 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.AbstractList;
+import java.util.RandomAccess;
+import java.util.ListIterator;
+import java.util.Iterator;
+
+/**
+ * An implementation of {@link LazyStringList} that wraps another
+ * {@link LazyStringList} such that it cannot be modified via the wrapper.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class UnmodifiableLazyStringList extends AbstractList<String>
+ implements LazyStringList, RandomAccess {
+
+ private final LazyStringList list;
+
+ public UnmodifiableLazyStringList(LazyStringList list) {
+ this.list = list;
+ }
+
+ @Override
+ public String get(int index) {
+ return list.get(index);
+ }
+
+ @Override
+ public int size() {
+ return list.size();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public ByteString getByteString(int index) {
+ return list.getByteString(index);
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void add(ByteString element) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public ListIterator<String> listIterator(final int index) {
+ return new ListIterator<String>() {
+ ListIterator<String> iter = list.listIterator(index);
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public String next() {
+ return iter.next();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasPrevious() {
+ return iter.hasPrevious();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public String previous() {
+ return iter.previous();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public int nextIndex() {
+ return iter.nextIndex();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public int previousIndex() {
+ return iter.previousIndex();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void set(String o) {
+ throw new UnsupportedOperationException();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void add(String o) {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override
+ public Iterator<String> iterator() {
+ return new Iterator<String>() {
+ Iterator<String> iter = list.iterator();
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public String next() {
+ return iter.next();
+ }
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+}
diff --git a/src/third_party/protobuf/java/src/main/java/com/google/protobuf/WireFormat.java b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/WireFormat.java
new file mode 100644
index 0000000..a30f2a3
--- /dev/null
+++ b/src/third_party/protobuf/java/src/main/java/com/google/protobuf/WireFormat.java
@@ -0,0 +1,163 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * This class is used internally by the Protocol Buffer library and generated
+ * message implementations. It is public only because those generated messages
+ * do not reside in the {@code protobuf} package. Others should not use this
+ * class directly.
+ *
+ * This class contains constants and helper functions useful for dealing with
+ * the Protocol Buffer wire format.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class WireFormat {
+ // Do not allow instantiation.
+ private WireFormat() {}
+
+ public static final int WIRETYPE_VARINT = 0;
+ public static final int WIRETYPE_FIXED64 = 1;
+ public static final int WIRETYPE_LENGTH_DELIMITED = 2;
+ public static final int WIRETYPE_START_GROUP = 3;
+ public static final int WIRETYPE_END_GROUP = 4;
+ public static final int WIRETYPE_FIXED32 = 5;
+
+ static final int TAG_TYPE_BITS = 3;
+ static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
+
+ /** Given a tag value, determines the wire type (the lower 3 bits). */
+ static int getTagWireType(final int tag) {
+ return tag & TAG_TYPE_MASK;
+ }
+
+ /** Given a tag value, determines the field number (the upper 29 bits). */
+ public static int getTagFieldNumber(final int tag) {
+ return tag >>> TAG_TYPE_BITS;
+ }
+
+ /** Makes a tag value given a field number and wire type. */
+ static int makeTag(final int fieldNumber, final int wireType) {
+ return (fieldNumber << TAG_TYPE_BITS) | wireType;
+ }
+
+ /**
+ * Lite equivalent to {@link Descriptors.FieldDescriptor.JavaType}. This is
+ * only here to support the lite runtime and should not be used by users.
+ */
+ public enum JavaType {
+ INT(0),
+ LONG(0L),
+ FLOAT(0F),
+ DOUBLE(0D),
+ BOOLEAN(false),
+ STRING(""),
+ BYTE_STRING(ByteString.EMPTY),
+ ENUM(null),
+ MESSAGE(null);
+
+ JavaType(final Object defaultDefault) {
+ this.defaultDefault = defaultDefault;
+ }
+
+ /**
+ * The default default value for fields of this type, if it's a primitive
+ * type.
+ */
+ Object getDefaultDefault() {
+ return defaultDefault;
+ }
+
+ private final Object defaultDefault;
+ }
+
+ /**
+ * Lite equivalent to {@link Descriptors.FieldDescriptor.Type}. This is
+ * only here to support the lite runtime and should not be used by users.
+ */
+ public enum FieldType {
+ DOUBLE (JavaType.DOUBLE , WIRETYPE_FIXED64 ),
+ FLOAT (JavaType.FLOAT , WIRETYPE_FIXED32 ),
+ INT64 (JavaType.LONG , WIRETYPE_VARINT ),
+ UINT64 (JavaType.LONG , WIRETYPE_VARINT ),
+ INT32 (JavaType.INT , WIRETYPE_VARINT ),
+ FIXED64 (JavaType.LONG , WIRETYPE_FIXED64 ),
+ FIXED32 (JavaType.INT , WIRETYPE_FIXED32 ),
+ BOOL (JavaType.BOOLEAN , WIRETYPE_VARINT ),
+ STRING (JavaType.STRING , WIRETYPE_LENGTH_DELIMITED) {
+ public boolean isPackable() { return false; }
+ },
+ GROUP (JavaType.MESSAGE , WIRETYPE_START_GROUP ) {
+ public boolean isPackable() { return false; }
+ },
+ MESSAGE (JavaType.MESSAGE , WIRETYPE_LENGTH_DELIMITED) {
+ public boolean isPackable() { return false; }
+ },
+ BYTES (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) {
+ public boolean isPackable() { return false; }
+ },
+ UINT32 (JavaType.INT , WIRETYPE_VARINT ),
+ ENUM (JavaType.ENUM , WIRETYPE_VARINT ),
+ SFIXED32(JavaType.INT , WIRETYPE_FIXED32 ),
+ SFIXED64(JavaType.LONG , WIRETYPE_FIXED64 ),
+ SINT32 (JavaType.INT , WIRETYPE_VARINT ),
+ SINT64 (JavaType.LONG , WIRETYPE_VARINT );
+
+ FieldType(final JavaType javaType, final int wireType) {
+ this.javaType = javaType;
+ this.wireType = wireType;
+ }
+
+ private final JavaType javaType;
+ private final int wireType;
+
+ public JavaType getJavaType() { return javaType; }
+ public int getWireType() { return wireType; }
+
+ public boolean isPackable() { return true; }
+ }
+
+ // Field numbers for feilds in MessageSet wire format.
+ static final int MESSAGE_SET_ITEM = 1;
+ static final int MESSAGE_SET_TYPE_ID = 2;
+ static final int MESSAGE_SET_MESSAGE = 3;
+
+ // Tag numbers.
+ static final int MESSAGE_SET_ITEM_TAG =
+ makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP);
+ static final int MESSAGE_SET_ITEM_END_TAG =
+ makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP);
+ static final int MESSAGE_SET_TYPE_ID_TAG =
+ makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT);
+ static final int MESSAGE_SET_MESSAGE_TAG =
+ makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED);
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
new file mode 100644
index 0000000..d53ce8d
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
@@ -0,0 +1,460 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestRequiredForeign;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+
+import junit.framework.TestCase;
+
+import java.util.Map;
+
+/**
+ * Unit test for {@link AbstractMessage}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class AbstractMessageTest extends TestCase {
+ /**
+ * Extends AbstractMessage and wraps some other message object. The methods
+ * of the Message interface which aren't explicitly implemented by
+ * AbstractMessage are forwarded to the wrapped object. This allows us to
+ * test that AbstractMessage's implementations work even if the wrapped
+ * object does not use them.
+ */
+ private static class AbstractMessageWrapper extends AbstractMessage {
+ private final Message wrappedMessage;
+
+ public AbstractMessageWrapper(Message wrappedMessage) {
+ this.wrappedMessage = wrappedMessage;
+ }
+
+ public Descriptors.Descriptor getDescriptorForType() {
+ return wrappedMessage.getDescriptorForType();
+ }
+ public AbstractMessageWrapper getDefaultInstanceForType() {
+ return new AbstractMessageWrapper(
+ wrappedMessage.getDefaultInstanceForType());
+ }
+ public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
+ return wrappedMessage.getAllFields();
+ }
+ public boolean hasField(Descriptors.FieldDescriptor field) {
+ return wrappedMessage.hasField(field);
+ }
+ public Object getField(Descriptors.FieldDescriptor field) {
+ return wrappedMessage.getField(field);
+ }
+ public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
+ return wrappedMessage.getRepeatedFieldCount(field);
+ }
+ public Object getRepeatedField(
+ Descriptors.FieldDescriptor field, int index) {
+ return wrappedMessage.getRepeatedField(field, index);
+ }
+ public UnknownFieldSet getUnknownFields() {
+ return wrappedMessage.getUnknownFields();
+ }
+ public Builder newBuilderForType() {
+ return new Builder(wrappedMessage.newBuilderForType());
+ }
+ public Builder toBuilder() {
+ return new Builder(wrappedMessage.toBuilder());
+ }
+
+ static class Builder extends AbstractMessage.Builder<Builder> {
+ private final Message.Builder wrappedBuilder;
+
+ public Builder(Message.Builder wrappedBuilder) {
+ this.wrappedBuilder = wrappedBuilder;
+ }
+
+ public AbstractMessageWrapper build() {
+ return new AbstractMessageWrapper(wrappedBuilder.build());
+ }
+ public AbstractMessageWrapper buildPartial() {
+ return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
+ }
+ public Builder clone() {
+ return new Builder(wrappedBuilder.clone());
+ }
+ public boolean isInitialized() {
+ return clone().buildPartial().isInitialized();
+ }
+ public Descriptors.Descriptor getDescriptorForType() {
+ return wrappedBuilder.getDescriptorForType();
+ }
+ public AbstractMessageWrapper getDefaultInstanceForType() {
+ return new AbstractMessageWrapper(
+ wrappedBuilder.getDefaultInstanceForType());
+ }
+ public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
+ return wrappedBuilder.getAllFields();
+ }
+ public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
+ return new Builder(wrappedBuilder.newBuilderForField(field));
+ }
+ public boolean hasField(Descriptors.FieldDescriptor field) {
+ return wrappedBuilder.hasField(field);
+ }
+ public Object getField(Descriptors.FieldDescriptor field) {
+ return wrappedBuilder.getField(field);
+ }
+ public Builder setField(Descriptors.FieldDescriptor field, Object value) {
+ wrappedBuilder.setField(field, value);
+ return this;
+ }
+ public Builder clearField(Descriptors.FieldDescriptor field) {
+ wrappedBuilder.clearField(field);
+ return this;
+ }
+ public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
+ return wrappedBuilder.getRepeatedFieldCount(field);
+ }
+ public Object getRepeatedField(
+ Descriptors.FieldDescriptor field, int index) {
+ return wrappedBuilder.getRepeatedField(field, index);
+ }
+ public Builder setRepeatedField(Descriptors.FieldDescriptor field,
+ int index, Object value) {
+ wrappedBuilder.setRepeatedField(field, index, value);
+ return this;
+ }
+ public Builder addRepeatedField(
+ Descriptors.FieldDescriptor field, Object value) {
+ wrappedBuilder.addRepeatedField(field, value);
+ return this;
+ }
+ public UnknownFieldSet getUnknownFields() {
+ return wrappedBuilder.getUnknownFields();
+ }
+ public Builder setUnknownFields(UnknownFieldSet unknownFields) {
+ wrappedBuilder.setUnknownFields(unknownFields);
+ return this;
+ }
+ }
+ }
+
+ // =================================================================
+
+ TestUtil.ReflectionTester reflectionTester =
+ new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+ TestUtil.ReflectionTester extensionsReflectionTester =
+ new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+ TestUtil.getExtensionRegistry());
+
+ public void testClear() throws Exception {
+ AbstractMessageWrapper message =
+ new AbstractMessageWrapper.Builder(
+ TestAllTypes.newBuilder(TestUtil.getAllSet()))
+ .clear().build();
+ TestUtil.assertClear((TestAllTypes) message.wrappedMessage);
+ }
+
+ public void testCopy() throws Exception {
+ AbstractMessageWrapper message =
+ new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder())
+ .mergeFrom(TestUtil.getAllSet()).build();
+ TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
+ }
+
+ public void testSerializedSize() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+ Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());
+
+ assertEquals(message.getSerializedSize(),
+ abstractMessage.getSerializedSize());
+ }
+
+ public void testSerialization() throws Exception {
+ Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());
+
+ TestUtil.assertAllFieldsSet(
+ TestAllTypes.parseFrom(abstractMessage.toByteString()));
+
+ assertEquals(TestUtil.getAllSet().toByteString(),
+ abstractMessage.toByteString());
+ }
+
+ public void testParsing() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getAllSet().toByteString()).build();
+ TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
+ }
+
+ public void testPackedSerialization() throws Exception {
+ Message abstractMessage =
+ new AbstractMessageWrapper(TestUtil.getPackedSet());
+
+ TestUtil.assertPackedFieldsSet(
+ TestPackedTypes.parseFrom(abstractMessage.toByteString()));
+
+ assertEquals(TestUtil.getPackedSet().toByteString(),
+ abstractMessage.toByteString());
+ }
+
+ public void testPackedParsing() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+ TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
+ }
+
+ public void testUnpackedSerialization() throws Exception {
+ Message abstractMessage =
+ new AbstractMessageWrapper(TestUtil.getUnpackedSet());
+
+ TestUtil.assertUnpackedFieldsSet(
+ TestUnpackedTypes.parseFrom(abstractMessage.toByteString()));
+
+ assertEquals(TestUtil.getUnpackedSet().toByteString(),
+ abstractMessage.toByteString());
+ }
+
+ public void testParsePackedToUnpacked() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+ TestUtil.assertUnpackedFieldsSet(
+ (TestUnpackedTypes) message.wrappedMessage);
+ }
+
+ public void testParseUnpackedToPacked() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+ TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
+ }
+
+ public void testUnpackedParsing() throws Exception {
+ AbstractMessageWrapper.Builder builder =
+ new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
+ AbstractMessageWrapper message =
+ builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+ TestUtil.assertUnpackedFieldsSet(
+ (TestUnpackedTypes) message.wrappedMessage);
+ }
+
+ public void testOptimizedForSize() throws Exception {
+ // We're mostly only checking that this class was compiled successfully.
+ TestOptimizedForSize message =
+ TestOptimizedForSize.newBuilder().setI(1).build();
+ message = TestOptimizedForSize.parseFrom(message.toByteString());
+ assertEquals(2, message.getSerializedSize());
+ }
+
+ // -----------------------------------------------------------------
+ // Tests for isInitialized().
+
+ private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
+ TestRequired.getDefaultInstance();
+ private static final TestRequired TEST_REQUIRED_INITIALIZED =
+ TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
+
+ public void testIsInitialized() throws Exception {
+ TestRequired.Builder builder = TestRequired.newBuilder();
+ AbstractMessageWrapper.Builder abstractBuilder =
+ new AbstractMessageWrapper.Builder(builder);
+
+ assertFalse(abstractBuilder.isInitialized());
+ builder.setA(1);
+ assertFalse(abstractBuilder.isInitialized());
+ builder.setB(1);
+ assertFalse(abstractBuilder.isInitialized());
+ builder.setC(1);
+ assertTrue(abstractBuilder.isInitialized());
+ }
+
+ public void testForeignIsInitialized() throws Exception {
+ TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
+ AbstractMessageWrapper.Builder abstractBuilder =
+ new AbstractMessageWrapper.Builder(builder);
+
+ assertTrue(abstractBuilder.isInitialized());
+
+ builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(abstractBuilder.isInitialized());
+
+ builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
+ assertTrue(abstractBuilder.isInitialized());
+
+ builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(abstractBuilder.isInitialized());
+
+ builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
+ assertTrue(abstractBuilder.isInitialized());
+ }
+
+ // -----------------------------------------------------------------
+ // Tests for mergeFrom
+
+ static final TestAllTypes MERGE_SOURCE =
+ TestAllTypes.newBuilder()
+ .setOptionalInt32(1)
+ .setOptionalString("foo")
+ .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
+ .addRepeatedString("bar")
+ .build();
+
+ static final TestAllTypes MERGE_DEST =
+ TestAllTypes.newBuilder()
+ .setOptionalInt64(2)
+ .setOptionalString("baz")
+ .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
+ .addRepeatedString("qux")
+ .build();
+
+ static final String MERGE_RESULT_TEXT =
+ "optional_int32: 1\n" +
+ "optional_int64: 2\n" +
+ "optional_string: \"foo\"\n" +
+ "optional_foreign_message {\n" +
+ " c: 3\n" +
+ "}\n" +
+ "repeated_string: \"qux\"\n" +
+ "repeated_string: \"bar\"\n";
+
+ public void testMergeFrom() throws Exception {
+ AbstractMessageWrapper result =
+ new AbstractMessageWrapper.Builder(
+ TestAllTypes.newBuilder(MERGE_DEST))
+ .mergeFrom(MERGE_SOURCE).build();
+
+ assertEquals(MERGE_RESULT_TEXT, result.toString());
+ }
+
+ // -----------------------------------------------------------------
+ // Tests for equals and hashCode
+
+ public void testEqualsAndHashCode() throws Exception {
+ TestAllTypes a = TestUtil.getAllSet();
+ TestAllTypes b = TestAllTypes.newBuilder().build();
+ TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build();
+ TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build();
+ TestAllExtensions e = TestUtil.getAllExtensionsSet();
+ TestAllExtensions f = TestAllExtensions.newBuilder(e)
+ .addExtension(UnittestProto.repeatedInt32Extension, 999).build();
+
+ checkEqualsIsConsistent(a);
+ checkEqualsIsConsistent(b);
+ checkEqualsIsConsistent(c);
+ checkEqualsIsConsistent(d);
+ checkEqualsIsConsistent(e);
+ checkEqualsIsConsistent(f);
+
+ checkNotEqual(a, b);
+ checkNotEqual(a, c);
+ checkNotEqual(a, d);
+ checkNotEqual(a, e);
+ checkNotEqual(a, f);
+
+ checkNotEqual(b, c);
+ checkNotEqual(b, d);
+ checkNotEqual(b, e);
+ checkNotEqual(b, f);
+
+ checkNotEqual(c, d);
+ checkNotEqual(c, e);
+ checkNotEqual(c, f);
+
+ checkNotEqual(d, e);
+ checkNotEqual(d, f);
+
+ checkNotEqual(e, f);
+
+ // Deserializing into the TestEmptyMessage such that every field
+ // is an {@link UnknownFieldSet.Field}.
+ UnittestProto.TestEmptyMessage eUnknownFields =
+ UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
+ UnittestProto.TestEmptyMessage fUnknownFields =
+ UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray());
+ checkNotEqual(eUnknownFields, fUnknownFields);
+ checkEqualsIsConsistent(eUnknownFields);
+ checkEqualsIsConsistent(fUnknownFields);
+
+ // Subsequent reconstitutions should be identical
+ UnittestProto.TestEmptyMessage eUnknownFields2 =
+ UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
+ checkEqualsIsConsistent(eUnknownFields, eUnknownFields2);
+ }
+
+
+ /**
+ * Asserts that the given proto has symetric equals and hashCode methods.
+ */
+ private void checkEqualsIsConsistent(Message message) {
+ // Object should be equal to itself.
+ assertEquals(message, message);
+
+ // Object should be equal to a dynamic copy of itself.
+ DynamicMessage dynamic = DynamicMessage.newBuilder(message).build();
+ checkEqualsIsConsistent(message, dynamic);
+ }
+
+ /**
+ * Asserts that the given protos are equal and have the same hash code.
+ */
+ private void checkEqualsIsConsistent(Message message1, Message message2) {
+ assertEquals(message1, message2);
+ assertEquals(message2, message1);
+ assertEquals(message2.hashCode(), message1.hashCode());
+ }
+
+ /**
+ * Asserts that the given protos are not equal and have different hash codes.
+ *
+ * @warning It's valid for non-equal objects to have the same hash code, so
+ * this test is stricter than it needs to be. However, this should happen
+ * relatively rarely.
+ */
+ private void checkNotEqual(Message m1, Message m2) {
+ String equalsError = String.format("%s should not be equal to %s", m1, m2);
+ assertFalse(equalsError, m1.equals(m2));
+ assertFalse(equalsError, m2.equals(m1));
+
+ assertFalse(
+ String.format("%s should have a different hash code from %s", m1, m2),
+ m1.hashCode() == m2.hashCode());
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java
new file mode 100644
index 0000000..83f7f8d
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java
@@ -0,0 +1,528 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestRecursiveMessage;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Unit test for {@link CodedInputStream}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class CodedInputStreamTest extends TestCase {
+ /**
+ * Helper to construct a byte array from a bunch of bytes. The inputs are
+ * actually ints so that I can use hex notation and not get stupid errors
+ * about precision.
+ */
+ private byte[] bytes(int... bytesAsInts) {
+ byte[] bytes = new byte[bytesAsInts.length];
+ for (int i = 0; i < bytesAsInts.length; i++) {
+ bytes[i] = (byte) bytesAsInts[i];
+ }
+ return bytes;
+ }
+
+ /**
+ * An InputStream which limits the number of bytes it reads at a time.
+ * We use this to make sure that CodedInputStream doesn't screw up when
+ * reading in small blocks.
+ */
+ private static final class SmallBlockInputStream extends FilterInputStream {
+ private final int blockSize;
+
+ public SmallBlockInputStream(byte[] data, int blockSize) {
+ this(new ByteArrayInputStream(data), blockSize);
+ }
+
+ public SmallBlockInputStream(InputStream in, int blockSize) {
+ super(in);
+ this.blockSize = blockSize;
+ }
+
+ public int read(byte[] b) throws IOException {
+ return super.read(b, 0, Math.min(b.length, blockSize));
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ return super.read(b, off, Math.min(len, blockSize));
+ }
+ }
+
+ /**
+ * Parses the given bytes using readRawVarint32() and readRawVarint64() and
+ * checks that the result matches the given value.
+ */
+ private void assertReadVarint(byte[] data, long value) throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ assertEquals((int)value, input.readRawVarint32());
+
+ input = CodedInputStream.newInstance(data);
+ assertEquals(value, input.readRawVarint64());
+ assertTrue(input.isAtEnd());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals((int)value, input.readRawVarint32());
+
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals(value, input.readRawVarint64());
+ assertTrue(input.isAtEnd());
+ }
+
+ // Try reading direct from an InputStream. We want to verify that it
+ // doesn't read past the end of the input, so we copy to a new, bigger
+ // array first.
+ byte[] longerData = new byte[data.length + 1];
+ System.arraycopy(data, 0, longerData, 0, data.length);
+ InputStream rawInput = new ByteArrayInputStream(longerData);
+ assertEquals((int)value, CodedInputStream.readRawVarint32(rawInput));
+ assertEquals(1, rawInput.available());
+ }
+
+ /**
+ * Parses the given bytes using readRawVarint32() and readRawVarint64() and
+ * expects them to fail with an InvalidProtocolBufferException whose
+ * description matches the given one.
+ */
+ private void assertReadVarintFailure(
+ InvalidProtocolBufferException expected, byte[] data)
+ throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ try {
+ input.readRawVarint32();
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(expected.getMessage(), e.getMessage());
+ }
+
+ input = CodedInputStream.newInstance(data);
+ try {
+ input.readRawVarint64();
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(expected.getMessage(), e.getMessage());
+ }
+
+ // Make sure we get the same error when reading direct from an InputStream.
+ try {
+ CodedInputStream.readRawVarint32(new ByteArrayInputStream(data));
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(expected.getMessage(), e.getMessage());
+ }
+ }
+
+ /** Tests readRawVarint32() and readRawVarint64(). */
+ public void testReadVarint() throws Exception {
+ assertReadVarint(bytes(0x00), 0);
+ assertReadVarint(bytes(0x01), 1);
+ assertReadVarint(bytes(0x7f), 127);
+ // 14882
+ assertReadVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+ // 2961488830
+ assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x0bL << 28));
+
+ // 64-bit
+ // 7256456126
+ assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x1bL << 28));
+ // 41256202580718336
+ assertReadVarint(
+ bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+ // 11964378330978735131
+ assertReadVarint(
+ bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+ (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
+ (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
+
+ // Failures
+ assertReadVarintFailure(
+ InvalidProtocolBufferException.malformedVarint(),
+ bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x00));
+ assertReadVarintFailure(
+ InvalidProtocolBufferException.truncatedMessage(),
+ bytes(0x80));
+ }
+
+ /**
+ * Parses the given bytes using readRawLittleEndian32() and checks
+ * that the result matches the given value.
+ */
+ private void assertReadLittleEndian32(byte[] data, int value)
+ throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ assertEquals(value, input.readRawLittleEndian32());
+ assertTrue(input.isAtEnd());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals(value, input.readRawLittleEndian32());
+ assertTrue(input.isAtEnd());
+ }
+ }
+
+ /**
+ * Parses the given bytes using readRawLittleEndian64() and checks
+ * that the result matches the given value.
+ */
+ private void assertReadLittleEndian64(byte[] data, long value)
+ throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(data);
+ assertEquals(value, input.readRawLittleEndian64());
+ assertTrue(input.isAtEnd());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(data, blockSize));
+ assertEquals(value, input.readRawLittleEndian64());
+ assertTrue(input.isAtEnd());
+ }
+ }
+
+ /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */
+ public void testReadLittleEndian() throws Exception {
+ assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+ assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+ assertReadLittleEndian64(
+ bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
+ 0x123456789abcdef0L);
+ assertReadLittleEndian64(
+ bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a),
+ 0x9abcdef012345678L);
+ }
+
+ /** Test decodeZigZag32() and decodeZigZag64(). */
+ public void testDecodeZigZag() throws Exception {
+ assertEquals( 0, CodedInputStream.decodeZigZag32(0));
+ assertEquals(-1, CodedInputStream.decodeZigZag32(1));
+ assertEquals( 1, CodedInputStream.decodeZigZag32(2));
+ assertEquals(-2, CodedInputStream.decodeZigZag32(3));
+ assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE));
+ assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF));
+ assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE));
+ assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF));
+
+ assertEquals( 0, CodedInputStream.decodeZigZag64(0));
+ assertEquals(-1, CodedInputStream.decodeZigZag64(1));
+ assertEquals( 1, CodedInputStream.decodeZigZag64(2));
+ assertEquals(-2, CodedInputStream.decodeZigZag64(3));
+ assertEquals(0x000000003FFFFFFFL,
+ CodedInputStream.decodeZigZag64(0x000000007FFFFFFEL));
+ assertEquals(0xFFFFFFFFC0000000L,
+ CodedInputStream.decodeZigZag64(0x000000007FFFFFFFL));
+ assertEquals(0x000000007FFFFFFFL,
+ CodedInputStream.decodeZigZag64(0x00000000FFFFFFFEL));
+ assertEquals(0xFFFFFFFF80000000L,
+ CodedInputStream.decodeZigZag64(0x00000000FFFFFFFFL));
+ assertEquals(0x7FFFFFFFFFFFFFFFL,
+ CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFEL));
+ assertEquals(0x8000000000000000L,
+ CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFFL));
+ }
+
+ /** Tests reading and parsing a whole message with every field type. */
+ public void testReadWholeMessage() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+
+ byte[] rawBytes = message.toByteArray();
+ assertEquals(rawBytes.length, message.getSerializedSize());
+
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+ TestUtil.assertAllFieldsSet(message2);
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
+ message2 = TestAllTypes.parseFrom(
+ new SmallBlockInputStream(rawBytes, blockSize));
+ TestUtil.assertAllFieldsSet(message2);
+ }
+ }
+
+ /** Tests skipField(). */
+ public void testSkipWholeMessage() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+ byte[] rawBytes = message.toByteArray();
+
+ // Create two parallel inputs. Parse one as unknown fields while using
+ // skipField() to skip each field on the other. Expect the same tags.
+ CodedInputStream input1 = CodedInputStream.newInstance(rawBytes);
+ CodedInputStream input2 = CodedInputStream.newInstance(rawBytes);
+ UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder();
+
+ while (true) {
+ int tag = input1.readTag();
+ assertEquals(tag, input2.readTag());
+ if (tag == 0) {
+ break;
+ }
+ unknownFields.mergeFieldFrom(tag, input1);
+ input2.skipField(tag);
+ }
+ }
+
+ /**
+ * Test that a bug in skipRawBytes() has been fixed: if the skip skips
+ * exactly up to a limit, this should not break things.
+ */
+ public void testSkipRawBytesBug() throws Exception {
+ byte[] rawBytes = new byte[] { 1, 2 };
+ CodedInputStream input = CodedInputStream.newInstance(rawBytes);
+
+ int limit = input.pushLimit(1);
+ input.skipRawBytes(1);
+ input.popLimit(limit);
+ assertEquals(2, input.readRawByte());
+ }
+
+ /**
+ * Test that a bug in skipRawBytes() has been fixed: if the skip skips
+ * past the end of a buffer with a limit that has been set past the end of
+ * that buffer, this should not break things.
+ */
+ public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
+ byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
+ CodedInputStream input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(rawBytes, 3));
+
+ int limit = input.pushLimit(4);
+ // In order to expose the bug we need to read at least one byte to prime the
+ // buffer inside the CodedInputStream.
+ assertEquals(1, input.readRawByte());
+ // Skip to the end of the limit.
+ input.skipRawBytes(3);
+ assertTrue(input.isAtEnd());
+ input.popLimit(limit);
+ assertEquals(5, input.readRawByte());
+ }
+
+ public void testReadHugeBlob() throws Exception {
+ // Allocate and initialize a 1MB blob.
+ byte[] blob = new byte[1 << 20];
+ for (int i = 0; i < blob.length; i++) {
+ blob[i] = (byte)i;
+ }
+
+ // Make a message containing it.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ builder.setOptionalBytes(ByteString.copyFrom(blob));
+ TestAllTypes message = builder.build();
+
+ // Serialize and parse it. Make sure to parse from an InputStream, not
+ // directly from a ByteString, so that CodedInputStream uses buffered
+ // reading.
+ TestAllTypes message2 =
+ TestAllTypes.parseFrom(message.toByteString().newInput());
+
+ assertEquals(message.getOptionalBytes(), message2.getOptionalBytes());
+
+ // Make sure all the other fields were parsed correctly.
+ TestAllTypes message3 = TestAllTypes.newBuilder(message2)
+ .setOptionalBytes(TestUtil.getAllSet().getOptionalBytes())
+ .build();
+ TestUtil.assertAllFieldsSet(message3);
+ }
+
+ public void testReadMaliciouslyLargeBlob() throws Exception {
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+
+ int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ output.writeRawVarint32(tag);
+ output.writeRawVarint32(0x7FFFFFFF);
+ output.writeRawBytes(new byte[32]); // Pad with a few random bytes.
+ output.flush();
+
+ CodedInputStream input = rawOutput.toByteString().newCodedInput();
+ assertEquals(tag, input.readTag());
+
+ try {
+ input.readBytes();
+ fail("Should have thrown an exception!");
+ } catch (InvalidProtocolBufferException e) {
+ // success.
+ }
+ }
+
+ private TestRecursiveMessage makeRecursiveMessage(int depth) {
+ if (depth == 0) {
+ return TestRecursiveMessage.newBuilder().setI(5).build();
+ } else {
+ return TestRecursiveMessage.newBuilder()
+ .setA(makeRecursiveMessage(depth - 1)).build();
+ }
+ }
+
+ private void assertMessageDepth(TestRecursiveMessage message, int depth) {
+ if (depth == 0) {
+ assertFalse(message.hasA());
+ assertEquals(5, message.getI());
+ } else {
+ assertTrue(message.hasA());
+ assertMessageDepth(message.getA(), depth - 1);
+ }
+ }
+
+ public void testMaliciousRecursion() throws Exception {
+ ByteString data64 = makeRecursiveMessage(64).toByteString();
+ ByteString data65 = makeRecursiveMessage(65).toByteString();
+
+ assertMessageDepth(TestRecursiveMessage.parseFrom(data64), 64);
+
+ try {
+ TestRecursiveMessage.parseFrom(data65);
+ fail("Should have thrown an exception!");
+ } catch (InvalidProtocolBufferException e) {
+ // success.
+ }
+
+ CodedInputStream input = data64.newCodedInput();
+ input.setRecursionLimit(8);
+ try {
+ TestRecursiveMessage.parseFrom(input);
+ fail("Should have thrown an exception!");
+ } catch (InvalidProtocolBufferException e) {
+ // success.
+ }
+ }
+
+ public void testSizeLimit() throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(
+ TestUtil.getAllSet().toByteString().newInput());
+ input.setSizeLimit(16);
+
+ try {
+ TestAllTypes.parseFrom(input);
+ fail("Should have thrown an exception!");
+ } catch (InvalidProtocolBufferException e) {
+ // success.
+ }
+ }
+
+ public void testResetSizeCounter() throws Exception {
+ CodedInputStream input = CodedInputStream.newInstance(
+ new SmallBlockInputStream(new byte[256], 8));
+ input.setSizeLimit(16);
+ input.readRawBytes(16);
+ assertEquals(16, input.getTotalBytesRead());
+
+ try {
+ input.readRawByte();
+ fail("Should have thrown an exception!");
+ } catch (InvalidProtocolBufferException e) {
+ // success.
+ }
+
+ input.resetSizeCounter();
+ assertEquals(0, input.getTotalBytesRead());
+ input.readRawByte(); // No exception thrown.
+ input.resetSizeCounter();
+ assertEquals(0, input.getTotalBytesRead());
+
+ try {
+ input.readRawBytes(16); // Hits limit again.
+ fail("Should have thrown an exception!");
+ } catch (InvalidProtocolBufferException e) {
+ // success.
+ }
+ }
+
+ /**
+ * Tests that if we read an string that contains invalid UTF-8, no exception
+ * is thrown. Instead, the invalid bytes are replaced with the Unicode
+ * "replacement character" U+FFFD.
+ */
+ public void testReadInvalidUtf8() throws Exception {
+ ByteString.Output rawOutput = ByteString.newOutput();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+
+ int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+ output.writeRawVarint32(tag);
+ output.writeRawVarint32(1);
+ output.writeRawBytes(new byte[] { (byte)0x80 });
+ output.flush();
+
+ CodedInputStream input = rawOutput.toByteString().newCodedInput();
+ assertEquals(tag, input.readTag());
+ String text = input.readString();
+ assertEquals(0xfffd, text.charAt(0));
+ }
+
+ public void testReadFromSlice() throws Exception {
+ byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5);
+ assertEquals(0, in.getTotalBytesRead());
+ for (int i = 3; i < 8; i++) {
+ assertEquals(i, in.readRawByte());
+ assertEquals(i-2, in.getTotalBytesRead());
+ }
+ // eof
+ assertEquals(0, in.readTag());
+ assertEquals(5, in.getTotalBytesRead());
+ }
+
+ public void testInvalidTag() throws Exception {
+ // Any tag number which corresponds to field number zero is invalid and
+ // should throw InvalidProtocolBufferException.
+ for (int i = 0; i < 8; i++) {
+ try {
+ CodedInputStream.newInstance(bytes(i)).readTag();
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(InvalidProtocolBufferException.invalidTag().getMessage(),
+ e.getMessage());
+ }
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
new file mode 100644
index 0000000..74476e3
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
@@ -0,0 +1,318 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Unit test for {@link CodedOutputStream}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class CodedOutputStreamTest extends TestCase {
+ /**
+ * Helper to construct a byte array from a bunch of bytes. The inputs are
+ * actually ints so that I can use hex notation and not get stupid errors
+ * about precision.
+ */
+ private byte[] bytes(int... bytesAsInts) {
+ byte[] bytes = new byte[bytesAsInts.length];
+ for (int i = 0; i < bytesAsInts.length; i++) {
+ bytes[i] = (byte) bytesAsInts[i];
+ }
+ return bytes;
+ }
+
+ /** Arrays.asList() does not work with arrays of primitives. :( */
+ private List<Byte> toList(byte[] bytes) {
+ List<Byte> result = new ArrayList<Byte>();
+ for (byte b : bytes) {
+ result.add(b);
+ }
+ return result;
+ }
+
+ private void assertEqualBytes(byte[] a, byte[] b) {
+ assertEquals(toList(a), toList(b));
+ }
+
+ /**
+ * Writes the given value using writeRawVarint32() and writeRawVarint64() and
+ * checks that the result matches the given bytes.
+ */
+ private void assertWriteVarint(byte[] data, long value) throws Exception {
+ // Only do 32-bit write if the value fits in 32 bits.
+ if ((value >>> 32) == 0) {
+ ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+ output.writeRawVarint32((int) value);
+ output.flush();
+ assertEqualBytes(data, rawOutput.toByteArray());
+
+ // Also try computing size.
+ assertEquals(data.length,
+ CodedOutputStream.computeRawVarint32Size((int) value));
+ }
+
+ {
+ ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+ output.writeRawVarint64(value);
+ output.flush();
+ assertEqualBytes(data, rawOutput.toByteArray());
+
+ // Also try computing size.
+ assertEquals(data.length,
+ CodedOutputStream.computeRawVarint64Size(value));
+ }
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ // Only do 32-bit write if the value fits in 32 bits.
+ if ((value >>> 32) == 0) {
+ ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+ CodedOutputStream output =
+ CodedOutputStream.newInstance(rawOutput, blockSize);
+ output.writeRawVarint32((int) value);
+ output.flush();
+ assertEqualBytes(data, rawOutput.toByteArray());
+ }
+
+ {
+ ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+ CodedOutputStream output =
+ CodedOutputStream.newInstance(rawOutput, blockSize);
+ output.writeRawVarint64(value);
+ output.flush();
+ assertEqualBytes(data, rawOutput.toByteArray());
+ }
+ }
+ }
+
+ /** Tests writeRawVarint32() and writeRawVarint64(). */
+ public void testWriteVarint() throws Exception {
+ assertWriteVarint(bytes(0x00), 0);
+ assertWriteVarint(bytes(0x01), 1);
+ assertWriteVarint(bytes(0x7f), 127);
+ // 14882
+ assertWriteVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+ // 2961488830
+ assertWriteVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x0bL << 28));
+
+ // 64-bit
+ // 7256456126
+ assertWriteVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x1bL << 28));
+ // 41256202580718336
+ assertWriteVarint(
+ bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+ // 11964378330978735131
+ assertWriteVarint(
+ bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+ (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
+ (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
+ }
+
+ /**
+ * Parses the given bytes using writeRawLittleEndian32() and checks
+ * that the result matches the given value.
+ */
+ private void assertWriteLittleEndian32(byte[] data, int value)
+ throws Exception {
+ ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+ output.writeRawLittleEndian32(value);
+ output.flush();
+ assertEqualBytes(data, rawOutput.toByteArray());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ rawOutput = new ByteArrayOutputStream();
+ output = CodedOutputStream.newInstance(rawOutput, blockSize);
+ output.writeRawLittleEndian32(value);
+ output.flush();
+ assertEqualBytes(data, rawOutput.toByteArray());
+ }
+ }
+
+ /**
+ * Parses the given bytes using writeRawLittleEndian64() and checks
+ * that the result matches the given value.
+ */
+ private void assertWriteLittleEndian64(byte[] data, long value)
+ throws Exception {
+ ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+ CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+ output.writeRawLittleEndian64(value);
+ output.flush();
+ assertEqualBytes(data, rawOutput.toByteArray());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+ rawOutput = new ByteArrayOutputStream();
+ output = CodedOutputStream.newInstance(rawOutput, blockSize);
+ output.writeRawLittleEndian64(value);
+ output.flush();
+ assertEqualBytes(data, rawOutput.toByteArray());
+ }
+ }
+
+ /** Tests writeRawLittleEndian32() and writeRawLittleEndian64(). */
+ public void testWriteLittleEndian() throws Exception {
+ assertWriteLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+ assertWriteLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+ assertWriteLittleEndian64(
+ bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
+ 0x123456789abcdef0L);
+ assertWriteLittleEndian64(
+ bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a),
+ 0x9abcdef012345678L);
+ }
+
+ /** Test encodeZigZag32() and encodeZigZag64(). */
+ public void testEncodeZigZag() throws Exception {
+ assertEquals(0, CodedOutputStream.encodeZigZag32( 0));
+ assertEquals(1, CodedOutputStream.encodeZigZag32(-1));
+ assertEquals(2, CodedOutputStream.encodeZigZag32( 1));
+ assertEquals(3, CodedOutputStream.encodeZigZag32(-2));
+ assertEquals(0x7FFFFFFE, CodedOutputStream.encodeZigZag32(0x3FFFFFFF));
+ assertEquals(0x7FFFFFFF, CodedOutputStream.encodeZigZag32(0xC0000000));
+ assertEquals(0xFFFFFFFE, CodedOutputStream.encodeZigZag32(0x7FFFFFFF));
+ assertEquals(0xFFFFFFFF, CodedOutputStream.encodeZigZag32(0x80000000));
+
+ assertEquals(0, CodedOutputStream.encodeZigZag64( 0));
+ assertEquals(1, CodedOutputStream.encodeZigZag64(-1));
+ assertEquals(2, CodedOutputStream.encodeZigZag64( 1));
+ assertEquals(3, CodedOutputStream.encodeZigZag64(-2));
+ assertEquals(0x000000007FFFFFFEL,
+ CodedOutputStream.encodeZigZag64(0x000000003FFFFFFFL));
+ assertEquals(0x000000007FFFFFFFL,
+ CodedOutputStream.encodeZigZag64(0xFFFFFFFFC0000000L));
+ assertEquals(0x00000000FFFFFFFEL,
+ CodedOutputStream.encodeZigZag64(0x000000007FFFFFFFL));
+ assertEquals(0x00000000FFFFFFFFL,
+ CodedOutputStream.encodeZigZag64(0xFFFFFFFF80000000L));
+ assertEquals(0xFFFFFFFFFFFFFFFEL,
+ CodedOutputStream.encodeZigZag64(0x7FFFFFFFFFFFFFFFL));
+ assertEquals(0xFFFFFFFFFFFFFFFFL,
+ CodedOutputStream.encodeZigZag64(0x8000000000000000L));
+
+ // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
+ // were chosen semi-randomly via keyboard bashing.
+ assertEquals(0,
+ CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(0)));
+ assertEquals(1,
+ CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(1)));
+ assertEquals(-1,
+ CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-1)));
+ assertEquals(14927,
+ CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(14927)));
+ assertEquals(-3612,
+ CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-3612)));
+
+ assertEquals(0,
+ CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(0)));
+ assertEquals(1,
+ CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(1)));
+ assertEquals(-1,
+ CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-1)));
+ assertEquals(14927,
+ CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(14927)));
+ assertEquals(-3612,
+ CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-3612)));
+
+ assertEquals(856912304801416L,
+ CodedOutputStream.encodeZigZag64(
+ CodedInputStream.decodeZigZag64(
+ 856912304801416L)));
+ assertEquals(-75123905439571256L,
+ CodedOutputStream.encodeZigZag64(
+ CodedInputStream.decodeZigZag64(
+ -75123905439571256L)));
+ }
+
+ /** Tests writing a whole message with every field type. */
+ public void testWriteWholeMessage() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+
+ byte[] rawBytes = message.toByteArray();
+ assertEqualBytes(TestUtil.getGoldenMessage().toByteArray(), rawBytes);
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
+ ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+ CodedOutputStream output =
+ CodedOutputStream.newInstance(rawOutput, blockSize);
+ message.writeTo(output);
+ output.flush();
+ assertEqualBytes(rawBytes, rawOutput.toByteArray());
+ }
+ }
+
+ /** Tests writing a whole message with every packed field type. Ensures the
+ * wire format of packed fields is compatible with C++. */
+ public void testWriteWholePackedFieldsMessage() throws Exception {
+ TestPackedTypes message = TestUtil.getPackedSet();
+
+ byte[] rawBytes = message.toByteArray();
+ assertEqualBytes(TestUtil.getGoldenPackedFieldsMessage().toByteArray(),
+ rawBytes);
+ }
+
+ /** Test writing a message containing a negative enum value. This used to
+ * fail because the size was not properly computed as a sign-extended varint. */
+ public void testWriteMessageWithNegativeEnumValue() throws Exception {
+ protobuf_unittest.UnittestProto.SparseEnumMessage message =
+ protobuf_unittest.UnittestProto.SparseEnumMessage.newBuilder()
+ .setSparseEnum(protobuf_unittest.UnittestProto.TestSparseEnum.SPARSE_E)
+ .build();
+ assertTrue(message.getSparseEnum().getNumber() < 0);
+ byte[] rawBytes = message.toByteArray();
+ protobuf_unittest.UnittestProto.SparseEnumMessage message2 =
+ protobuf_unittest.UnittestProto.SparseEnumMessage.parseFrom(rawBytes);
+ assertEquals(protobuf_unittest.UnittestProto.TestSparseEnum.SPARSE_E,
+ message2.getSparseEnum());
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
new file mode 100644
index 0000000..1f8bb44
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestDeprecatedFields;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+/**
+ * Test field deprecation
+ *
+ * @author birdo@google.com (Roberto Scaramuzzi)
+ */
+public class DeprecatedFieldTest extends TestCase {
+ private String[] deprecatedGetterNames = {
+ "hasDeprecatedInt32",
+ "getDeprecatedInt32"};
+
+ private String[] deprecatedBuilderGetterNames = {
+ "hasDeprecatedInt32",
+ "getDeprecatedInt32",
+ "clearDeprecatedInt32"};
+
+ private String[] deprecatedBuilderSetterNames = {
+ "setDeprecatedInt32"};
+
+ public void testDeprecatedField() throws Exception {
+ Class<?> deprecatedFields = TestDeprecatedFields.class;
+ Class<?> deprecatedFieldsBuilder = TestDeprecatedFields.Builder.class;
+ for (String name : deprecatedGetterNames) {
+ Method method = deprecatedFields.getMethod(name);
+ assertTrue("Method " + name + " should be deprecated",
+ isDeprecated(method));
+ }
+ for (String name : deprecatedBuilderGetterNames) {
+ Method method = deprecatedFieldsBuilder.getMethod(name);
+ assertTrue("Method " + name + " should be deprecated",
+ isDeprecated(method));
+ }
+ for (String name : deprecatedBuilderSetterNames) {
+ Method method = deprecatedFieldsBuilder.getMethod(name, int.class);
+ assertTrue("Method " + name + " should be deprecated",
+ isDeprecated(method));
+ }
+ }
+
+ private boolean isDeprecated(AnnotatedElement annotated) {
+ return annotated.isAnnotationPresent(Deprecated.class);
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DescriptorsTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DescriptorsTest.java
new file mode 100644
index 0000000..65d06e3
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DescriptorsTest.java
@@ -0,0 +1,460 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.DescriptorProtos.DescriptorProto;
+import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
+import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
+import com.google.protobuf.Descriptors.DescriptorValidationException;
+import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.ServiceDescriptor;
+import com.google.protobuf.Descriptors.MethodDescriptor;
+
+import com.google.protobuf.test.UnittestImport;
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestService;
+import protobuf_unittest.UnittestCustomOptions;
+
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * Unit test for {@link Descriptors}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class DescriptorsTest extends TestCase {
+
+ // Regression test for bug where referencing a FieldDescriptor.Type value
+ // before a FieldDescriptorProto.Type value would yield a
+ // ExceptionInInitializerError.
+ @SuppressWarnings("unused")
+ private static final Object STATIC_INIT_TEST = FieldDescriptor.Type.BOOL;
+
+ public void testFieldTypeEnumMapping() throws Exception {
+ assertEquals(FieldDescriptor.Type.values().length,
+ FieldDescriptorProto.Type.values().length);
+ for (FieldDescriptor.Type type : FieldDescriptor.Type.values()) {
+ FieldDescriptorProto.Type protoType = type.toProto();
+ assertEquals("TYPE_" + type.name(), protoType.name());
+ assertEquals(type, FieldDescriptor.Type.valueOf(protoType));
+ }
+ }
+
+ public void testFileDescriptor() throws Exception {
+ FileDescriptor file = UnittestProto.getDescriptor();
+
+ assertEquals("google/protobuf/unittest.proto", file.getName());
+ assertEquals("protobuf_unittest", file.getPackage());
+
+ assertEquals("UnittestProto", file.getOptions().getJavaOuterClassname());
+ assertEquals("google/protobuf/unittest.proto",
+ file.toProto().getName());
+
+ assertEquals(Arrays.asList(UnittestImport.getDescriptor()),
+ file.getDependencies());
+
+ Descriptor messageType = TestAllTypes.getDescriptor();
+ assertEquals(messageType, file.getMessageTypes().get(0));
+ assertEquals(messageType, file.findMessageTypeByName("TestAllTypes"));
+ assertNull(file.findMessageTypeByName("NoSuchType"));
+ assertNull(file.findMessageTypeByName("protobuf_unittest.TestAllTypes"));
+ for (int i = 0; i < file.getMessageTypes().size(); i++) {
+ assertEquals(i, file.getMessageTypes().get(i).getIndex());
+ }
+
+ EnumDescriptor enumType = ForeignEnum.getDescriptor();
+ assertEquals(enumType, file.getEnumTypes().get(0));
+ assertEquals(enumType, file.findEnumTypeByName("ForeignEnum"));
+ assertNull(file.findEnumTypeByName("NoSuchType"));
+ assertNull(file.findEnumTypeByName("protobuf_unittest.ForeignEnum"));
+ assertEquals(Arrays.asList(ImportEnum.getDescriptor()),
+ UnittestImport.getDescriptor().getEnumTypes());
+ for (int i = 0; i < file.getEnumTypes().size(); i++) {
+ assertEquals(i, file.getEnumTypes().get(i).getIndex());
+ }
+
+ ServiceDescriptor service = TestService.getDescriptor();
+ assertEquals(service, file.getServices().get(0));
+ assertEquals(service, file.findServiceByName("TestService"));
+ assertNull(file.findServiceByName("NoSuchType"));
+ assertNull(file.findServiceByName("protobuf_unittest.TestService"));
+ assertEquals(Collections.emptyList(),
+ UnittestImport.getDescriptor().getServices());
+ for (int i = 0; i < file.getServices().size(); i++) {
+ assertEquals(i, file.getServices().get(i).getIndex());
+ }
+
+ FieldDescriptor extension =
+ UnittestProto.optionalInt32Extension.getDescriptor();
+ assertEquals(extension, file.getExtensions().get(0));
+ assertEquals(extension,
+ file.findExtensionByName("optional_int32_extension"));
+ assertNull(file.findExtensionByName("no_such_ext"));
+ assertNull(file.findExtensionByName(
+ "protobuf_unittest.optional_int32_extension"));
+ assertEquals(Collections.emptyList(),
+ UnittestImport.getDescriptor().getExtensions());
+ for (int i = 0; i < file.getExtensions().size(); i++) {
+ assertEquals(i, file.getExtensions().get(i).getIndex());
+ }
+ }
+
+ public void testDescriptor() throws Exception {
+ Descriptor messageType = TestAllTypes.getDescriptor();
+ Descriptor nestedType = TestAllTypes.NestedMessage.getDescriptor();
+
+ assertEquals("TestAllTypes", messageType.getName());
+ assertEquals("protobuf_unittest.TestAllTypes", messageType.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), messageType.getFile());
+ assertNull(messageType.getContainingType());
+ assertEquals(DescriptorProtos.MessageOptions.getDefaultInstance(),
+ messageType.getOptions());
+ assertEquals("TestAllTypes", messageType.toProto().getName());
+
+ assertEquals("NestedMessage", nestedType.getName());
+ assertEquals("protobuf_unittest.TestAllTypes.NestedMessage",
+ nestedType.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), nestedType.getFile());
+ assertEquals(messageType, nestedType.getContainingType());
+
+ FieldDescriptor field = messageType.getFields().get(0);
+ assertEquals("optional_int32", field.getName());
+ assertEquals(field, messageType.findFieldByName("optional_int32"));
+ assertNull(messageType.findFieldByName("no_such_field"));
+ assertEquals(field, messageType.findFieldByNumber(1));
+ assertNull(messageType.findFieldByNumber(571283));
+ for (int i = 0; i < messageType.getFields().size(); i++) {
+ assertEquals(i, messageType.getFields().get(i).getIndex());
+ }
+
+ assertEquals(nestedType, messageType.getNestedTypes().get(0));
+ assertEquals(nestedType, messageType.findNestedTypeByName("NestedMessage"));
+ assertNull(messageType.findNestedTypeByName("NoSuchType"));
+ for (int i = 0; i < messageType.getNestedTypes().size(); i++) {
+ assertEquals(i, messageType.getNestedTypes().get(i).getIndex());
+ }
+
+ EnumDescriptor enumType = TestAllTypes.NestedEnum.getDescriptor();
+ assertEquals(enumType, messageType.getEnumTypes().get(0));
+ assertEquals(enumType, messageType.findEnumTypeByName("NestedEnum"));
+ assertNull(messageType.findEnumTypeByName("NoSuchType"));
+ for (int i = 0; i < messageType.getEnumTypes().size(); i++) {
+ assertEquals(i, messageType.getEnumTypes().get(i).getIndex());
+ }
+ }
+
+ public void testFieldDescriptor() throws Exception {
+ Descriptor messageType = TestAllTypes.getDescriptor();
+ FieldDescriptor primitiveField =
+ messageType.findFieldByName("optional_int32");
+ FieldDescriptor enumField =
+ messageType.findFieldByName("optional_nested_enum");
+ FieldDescriptor messageField =
+ messageType.findFieldByName("optional_foreign_message");
+ FieldDescriptor cordField =
+ messageType.findFieldByName("optional_cord");
+ FieldDescriptor extension =
+ UnittestProto.optionalInt32Extension.getDescriptor();
+ FieldDescriptor nestedExtension = TestRequired.single.getDescriptor();
+
+ assertEquals("optional_int32", primitiveField.getName());
+ assertEquals("protobuf_unittest.TestAllTypes.optional_int32",
+ primitiveField.getFullName());
+ assertEquals(1, primitiveField.getNumber());
+ assertEquals(messageType, primitiveField.getContainingType());
+ assertEquals(UnittestProto.getDescriptor(), primitiveField.getFile());
+ assertEquals(FieldDescriptor.Type.INT32, primitiveField.getType());
+ assertEquals(FieldDescriptor.JavaType.INT, primitiveField.getJavaType());
+ assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(),
+ primitiveField.getOptions());
+ assertFalse(primitiveField.isExtension());
+ assertEquals("optional_int32", primitiveField.toProto().getName());
+
+ assertEquals("optional_nested_enum", enumField.getName());
+ assertEquals(FieldDescriptor.Type.ENUM, enumField.getType());
+ assertEquals(FieldDescriptor.JavaType.ENUM, enumField.getJavaType());
+ assertEquals(TestAllTypes.NestedEnum.getDescriptor(),
+ enumField.getEnumType());
+
+ assertEquals("optional_foreign_message", messageField.getName());
+ assertEquals(FieldDescriptor.Type.MESSAGE, messageField.getType());
+ assertEquals(FieldDescriptor.JavaType.MESSAGE, messageField.getJavaType());
+ assertEquals(ForeignMessage.getDescriptor(), messageField.getMessageType());
+
+ assertEquals("optional_cord", cordField.getName());
+ assertEquals(FieldDescriptor.Type.STRING, cordField.getType());
+ assertEquals(FieldDescriptor.JavaType.STRING, cordField.getJavaType());
+ assertEquals(DescriptorProtos.FieldOptions.CType.CORD,
+ cordField.getOptions().getCtype());
+
+ assertEquals("optional_int32_extension", extension.getName());
+ assertEquals("protobuf_unittest.optional_int32_extension",
+ extension.getFullName());
+ assertEquals(1, extension.getNumber());
+ assertEquals(TestAllExtensions.getDescriptor(),
+ extension.getContainingType());
+ assertEquals(UnittestProto.getDescriptor(), extension.getFile());
+ assertEquals(FieldDescriptor.Type.INT32, extension.getType());
+ assertEquals(FieldDescriptor.JavaType.INT, extension.getJavaType());
+ assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(),
+ extension.getOptions());
+ assertTrue(extension.isExtension());
+ assertEquals(null, extension.getExtensionScope());
+ assertEquals("optional_int32_extension", extension.toProto().getName());
+
+ assertEquals("single", nestedExtension.getName());
+ assertEquals("protobuf_unittest.TestRequired.single",
+ nestedExtension.getFullName());
+ assertEquals(TestRequired.getDescriptor(),
+ nestedExtension.getExtensionScope());
+ }
+
+ public void testFieldDescriptorLabel() throws Exception {
+ FieldDescriptor requiredField =
+ TestRequired.getDescriptor().findFieldByName("a");
+ FieldDescriptor optionalField =
+ TestAllTypes.getDescriptor().findFieldByName("optional_int32");
+ FieldDescriptor repeatedField =
+ TestAllTypes.getDescriptor().findFieldByName("repeated_int32");
+
+ assertTrue(requiredField.isRequired());
+ assertFalse(requiredField.isRepeated());
+ assertFalse(optionalField.isRequired());
+ assertFalse(optionalField.isRepeated());
+ assertFalse(repeatedField.isRequired());
+ assertTrue(repeatedField.isRepeated());
+ }
+
+ public void testFieldDescriptorDefault() throws Exception {
+ Descriptor d = TestAllTypes.getDescriptor();
+ assertFalse(d.findFieldByName("optional_int32").hasDefaultValue());
+ assertEquals(0, d.findFieldByName("optional_int32").getDefaultValue());
+ assertTrue(d.findFieldByName("default_int32").hasDefaultValue());
+ assertEquals(41, d.findFieldByName("default_int32").getDefaultValue());
+
+ d = TestExtremeDefaultValues.getDescriptor();
+ assertEquals(
+ ByteString.copyFrom(
+ "\0\001\007\b\f\n\r\t\013\\\'\"\u00fe".getBytes("ISO-8859-1")),
+ d.findFieldByName("escaped_bytes").getDefaultValue());
+ assertEquals(-1, d.findFieldByName("large_uint32").getDefaultValue());
+ assertEquals(-1L, d.findFieldByName("large_uint64").getDefaultValue());
+ }
+
+ public void testEnumDescriptor() throws Exception {
+ EnumDescriptor enumType = ForeignEnum.getDescriptor();
+ EnumDescriptor nestedType = TestAllTypes.NestedEnum.getDescriptor();
+
+ assertEquals("ForeignEnum", enumType.getName());
+ assertEquals("protobuf_unittest.ForeignEnum", enumType.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), enumType.getFile());
+ assertNull(enumType.getContainingType());
+ assertEquals(DescriptorProtos.EnumOptions.getDefaultInstance(),
+ enumType.getOptions());
+
+ assertEquals("NestedEnum", nestedType.getName());
+ assertEquals("protobuf_unittest.TestAllTypes.NestedEnum",
+ nestedType.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), nestedType.getFile());
+ assertEquals(TestAllTypes.getDescriptor(), nestedType.getContainingType());
+
+ EnumValueDescriptor value = ForeignEnum.FOREIGN_FOO.getValueDescriptor();
+ assertEquals(value, enumType.getValues().get(0));
+ assertEquals("FOREIGN_FOO", value.getName());
+ assertEquals(4, value.getNumber());
+ assertEquals(value, enumType.findValueByName("FOREIGN_FOO"));
+ assertEquals(value, enumType.findValueByNumber(4));
+ assertNull(enumType.findValueByName("NO_SUCH_VALUE"));
+ for (int i = 0; i < enumType.getValues().size(); i++) {
+ assertEquals(i, enumType.getValues().get(i).getIndex());
+ }
+ }
+
+ public void testServiceDescriptor() throws Exception {
+ ServiceDescriptor service = TestService.getDescriptor();
+
+ assertEquals("TestService", service.getName());
+ assertEquals("protobuf_unittest.TestService", service.getFullName());
+ assertEquals(UnittestProto.getDescriptor(), service.getFile());
+
+ assertEquals(2, service.getMethods().size());
+
+ MethodDescriptor fooMethod = service.getMethods().get(0);
+ assertEquals("Foo", fooMethod.getName());
+ assertEquals(UnittestProto.FooRequest.getDescriptor(),
+ fooMethod.getInputType());
+ assertEquals(UnittestProto.FooResponse.getDescriptor(),
+ fooMethod.getOutputType());
+ assertEquals(fooMethod, service.findMethodByName("Foo"));
+
+ MethodDescriptor barMethod = service.getMethods().get(1);
+ assertEquals("Bar", barMethod.getName());
+ assertEquals(UnittestProto.BarRequest.getDescriptor(),
+ barMethod.getInputType());
+ assertEquals(UnittestProto.BarResponse.getDescriptor(),
+ barMethod.getOutputType());
+ assertEquals(barMethod, service.findMethodByName("Bar"));
+
+ assertNull(service.findMethodByName("NoSuchMethod"));
+
+ for (int i = 0; i < service.getMethods().size(); i++) {
+ assertEquals(i, service.getMethods().get(i).getIndex());
+ }
+ }
+
+
+ public void testCustomOptions() throws Exception {
+ Descriptor descriptor =
+ UnittestCustomOptions.TestMessageWithCustomOptions.getDescriptor();
+
+ assertTrue(
+ descriptor.getOptions().hasExtension(UnittestCustomOptions.messageOpt1));
+ assertEquals(Integer.valueOf(-56),
+ descriptor.getOptions().getExtension(UnittestCustomOptions.messageOpt1));
+
+ FieldDescriptor field = descriptor.findFieldByName("field1");
+ assertNotNull(field);
+
+ assertTrue(
+ field.getOptions().hasExtension(UnittestCustomOptions.fieldOpt1));
+ assertEquals(Long.valueOf(8765432109L),
+ field.getOptions().getExtension(UnittestCustomOptions.fieldOpt1));
+
+ EnumDescriptor enumType =
+ UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor();
+
+ assertTrue(
+ enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1));
+ assertEquals(Integer.valueOf(-789),
+ enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1));
+
+ ServiceDescriptor service =
+ UnittestCustomOptions.TestServiceWithCustomOptions.getDescriptor();
+
+ assertTrue(
+ service.getOptions().hasExtension(UnittestCustomOptions.serviceOpt1));
+ assertEquals(Long.valueOf(-9876543210L),
+ service.getOptions().getExtension(UnittestCustomOptions.serviceOpt1));
+
+ MethodDescriptor method = service.findMethodByName("Foo");
+ assertNotNull(method);
+
+ assertTrue(
+ method.getOptions().hasExtension(UnittestCustomOptions.methodOpt1));
+ assertEquals(UnittestCustomOptions.MethodOpt1.METHODOPT1_VAL2,
+ method.getOptions().getExtension(UnittestCustomOptions.methodOpt1));
+ }
+
+ /**
+ * Test that the FieldDescriptor.Type enum is the same as the
+ * WireFormat.FieldType enum.
+ */
+ public void testFieldTypeTablesMatch() throws Exception {
+ FieldDescriptor.Type[] values1 = FieldDescriptor.Type.values();
+ WireFormat.FieldType[] values2 = WireFormat.FieldType.values();
+
+ assertEquals(values1.length, values2.length);
+
+ for (int i = 0; i < values1.length; i++) {
+ assertEquals(values1[i].toString(), values2[i].toString());
+ }
+ }
+
+ /**
+ * Test that the FieldDescriptor.JavaType enum is the same as the
+ * WireFormat.JavaType enum.
+ */
+ public void testJavaTypeTablesMatch() throws Exception {
+ FieldDescriptor.JavaType[] values1 = FieldDescriptor.JavaType.values();
+ WireFormat.JavaType[] values2 = WireFormat.JavaType.values();
+
+ assertEquals(values1.length, values2.length);
+
+ for (int i = 0; i < values1.length; i++) {
+ assertEquals(values1[i].toString(), values2[i].toString());
+ }
+ }
+
+ public void testEnormousDescriptor() throws Exception {
+ // The descriptor for this file is larger than 64k, yet it did not cause
+ // a compiler error due to an over-long string literal.
+ assertTrue(
+ UnittestEnormousDescriptor.getDescriptor()
+ .toProto().getSerializedSize() > 65536);
+ }
+
+ /**
+ * Tests that the DescriptorValidationException works as intended.
+ */
+ public void testDescriptorValidatorException() throws Exception {
+ FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
+ .setName("foo.proto")
+ .addMessageType(DescriptorProto.newBuilder()
+ .setName("Foo")
+ .addField(FieldDescriptorProto.newBuilder()
+ .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+ .setType(FieldDescriptorProto.Type.TYPE_INT32)
+ .setName("foo")
+ .setNumber(1)
+ .setDefaultValue("invalid")
+ .build())
+ .build())
+ .build();
+ try {
+ Descriptors.FileDescriptor.buildFrom(fileDescriptorProto,
+ new FileDescriptor[0]);
+ fail("DescriptorValidationException expected");
+ } catch (DescriptorValidationException e) {
+ // Expected; check that the error message contains some useful hints
+ assertTrue(e.getMessage().indexOf("foo") != -1);
+ assertTrue(e.getMessage().indexOf("Foo") != -1);
+ assertTrue(e.getMessage().indexOf("invalid") != -1);
+ assertTrue(e.getCause() instanceof NumberFormatException);
+ assertTrue(e.getCause().getMessage().indexOf("invalid") != -1);
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DynamicMessageTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
new file mode 100644
index 0000000..aabccda
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
@@ -0,0 +1,226 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+
+import junit.framework.TestCase;
+import java.util.Arrays;
+
+/**
+ * Unit test for {@link DynamicMessage}. See also {@link MessageTest}, which
+ * tests some {@link DynamicMessage} functionality.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class DynamicMessageTest extends TestCase {
+ TestUtil.ReflectionTester reflectionTester =
+ new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+ TestUtil.ReflectionTester extensionsReflectionTester =
+ new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+ TestUtil.getExtensionRegistry());
+ TestUtil.ReflectionTester packedReflectionTester =
+ new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null);
+
+ public void testDynamicMessageAccessors() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ Message message = builder.build();
+ reflectionTester.assertAllFieldsSetViaReflection(message);
+ }
+
+ public void testDoubleBuildError() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ builder.build();
+ try {
+ builder.build();
+ fail("Should have thrown exception.");
+ } catch (IllegalStateException e) {
+ // Success.
+ }
+ }
+
+ public void testClearAfterBuildError() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ builder.build();
+ try {
+ builder.clear();
+ fail("Should have thrown exception.");
+ } catch (IllegalStateException e) {
+ // Success.
+ }
+ }
+
+ public void testDynamicMessageSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
+ public void testDynamicMessageExtensionAccessors() throws Exception {
+ // We don't need to extensively test DynamicMessage's handling of
+ // extensions because, frankly, it doesn't do anything special with them.
+ // It treats them just like any other fields.
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
+ extensionsReflectionTester.setAllFieldsViaReflection(builder);
+ Message message = builder.build();
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
+ }
+
+ public void testDynamicMessageExtensionSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
+ extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
+ public void testDynamicMessageRepeatedSetters() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ Message message = builder.build();
+ reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
+ }
+
+ public void testDynamicMessageRepeatedSettersRejectNull() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
+ }
+
+ public void testDynamicMessageDefaults() throws Exception {
+ reflectionTester.assertClearViaReflection(
+ DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor()));
+ reflectionTester.assertClearViaReflection(
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor()).build());
+ }
+
+ public void testDynamicMessageSerializedSize() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+
+ Message.Builder dynamicBuilder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(dynamicBuilder);
+ Message dynamicMessage = dynamicBuilder.build();
+
+ assertEquals(message.getSerializedSize(),
+ dynamicMessage.getSerializedSize());
+ }
+
+ public void testDynamicMessageSerialization() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ Message message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+ TestUtil.assertAllFieldsSet(message2);
+
+ // In fact, the serialized forms should be exactly the same, byte-for-byte.
+ assertEquals(TestUtil.getAllSet().toByteString(), rawBytes);
+ }
+
+ public void testDynamicMessageParsing() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+
+ Message message2 =
+ DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), rawBytes);
+ reflectionTester.assertAllFieldsSetViaReflection(message2);
+ }
+
+ public void testDynamicMessagePackedSerialization() throws Exception {
+ Message.Builder builder =
+ DynamicMessage.newBuilder(TestPackedTypes.getDescriptor());
+ packedReflectionTester.setPackedFieldsViaReflection(builder);
+ Message message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+ TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
+
+ TestUtil.assertPackedFieldsSet(message2);
+
+ // In fact, the serialized forms should be exactly the same, byte-for-byte.
+ assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes);
+ }
+
+ public void testDynamicMessagePackedParsing() throws Exception {
+ TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+ TestUtil.setPackedFields(builder);
+ TestPackedTypes message = builder.build();
+
+ ByteString rawBytes = message.toByteString();
+
+ Message message2 =
+ DynamicMessage.parseFrom(TestPackedTypes.getDescriptor(), rawBytes);
+ packedReflectionTester.assertPackedFieldsSetViaReflection(message2);
+ }
+
+ public void testDynamicMessageCopy() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+
+ DynamicMessage copy = DynamicMessage.newBuilder(message).build();
+ reflectionTester.assertAllFieldsSetViaReflection(copy);
+ }
+
+ public void testToBuilder() throws Exception {
+ DynamicMessage.Builder builder =
+ DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+ reflectionTester.setAllFieldsViaReflection(builder);
+ int unknownFieldNum = 9;
+ long unknownFieldVal = 90;
+ builder.setUnknownFields(UnknownFieldSet.newBuilder()
+ .addField(unknownFieldNum,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(unknownFieldVal).build())
+ .build());
+ DynamicMessage message = builder.build();
+
+ DynamicMessage derived = message.toBuilder().build();
+ reflectionTester.assertAllFieldsSetViaReflection(derived);
+ assertEquals(Arrays.asList(unknownFieldVal),
+ derived.getUnknownFields().getField(unknownFieldNum).getVarintList());
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
new file mode 100644
index 0000000..8b78893
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * A prerun for a test suite that allows running the full protocol buffer
+ * tests in a mode that disables the optimization for not using
+ * {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder} until they are
+ * requested. This allows us to run all the tests through both code paths
+ * and ensures that both code paths produce identical results.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class ForceFieldBuildersPreRun implements Runnable {
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void run() {
+ GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
new file mode 100644
index 0000000..acb2235
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -0,0 +1,980 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.test.UnittestImport;
+import protobuf_unittest.EnumWithNoOuter;
+import protobuf_unittest.MessageWithNoOuter;
+import protobuf_unittest.MultipleFilesTestProto;
+import protobuf_unittest.NestedExtension.MyNestedExtension;
+import protobuf_unittest.NestedExtensionLite.MyNestedExtensionLite;
+import protobuf_unittest.NonNestedExtension;
+import protobuf_unittest.NonNestedExtension.MessageToBeExtended;
+import protobuf_unittest.NonNestedExtension.MyNonNestedExtension;
+import protobuf_unittest.NonNestedExtensionLite;
+import protobuf_unittest.NonNestedExtensionLite.MessageLiteToBeExtended;
+import protobuf_unittest.NonNestedExtensionLite.MyNonNestedExtensionLite;
+import protobuf_unittest.ServiceWithNoOuter;
+import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor.TestOptionalOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Unit test for generated messages and generated code. See also
+ * {@link MessageTest}, which tests some generated message functionality.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class GeneratedMessageTest extends TestCase {
+ TestUtil.ReflectionTester reflectionTester =
+ new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+ public void testDefaultInstance() throws Exception {
+ assertSame(TestAllTypes.getDefaultInstance(),
+ TestAllTypes.getDefaultInstance().getDefaultInstanceForType());
+ assertSame(TestAllTypes.getDefaultInstance(),
+ TestAllTypes.newBuilder().getDefaultInstanceForType());
+ }
+
+ public void testMessageOrBuilder() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+ TestUtil.assertAllFieldsSet(message);
+ }
+
+ public void testUsingBuilderMultipleTimes() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ // primitive field scalar and repeated
+ builder.setOptionalSfixed64(100);
+ builder.addRepeatedInt32(100);
+ // enum field scalar and repeated
+ builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+ builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+ // proto field scalar and repeated
+ builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(1));
+ builder.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(1));
+
+ TestAllTypes value1 = builder.build();
+
+ assertEquals(100, value1.getOptionalSfixed64());
+ assertEquals(100, value1.getRepeatedInt32(0));
+ assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+ value1.getOptionalImportEnum());
+ assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+ value1.getRepeatedImportEnum(0));
+ assertEquals(1, value1.getOptionalForeignMessage().getC());
+ assertEquals(1, value1.getRepeatedForeignMessage(0).getC());
+
+ // Make sure that builder didn't update previously created values
+ builder.setOptionalSfixed64(200);
+ builder.setRepeatedInt32(0, 200);
+ builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_FOO);
+ builder.setRepeatedImportEnum(0, UnittestImport.ImportEnum.IMPORT_FOO);
+ builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(2));
+ builder.setRepeatedForeignMessage(0, ForeignMessage.newBuilder().setC(2));
+
+ TestAllTypes value2 = builder.build();
+
+ // Make sure value1 didn't change.
+ assertEquals(100, value1.getOptionalSfixed64());
+ assertEquals(100, value1.getRepeatedInt32(0));
+ assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+ value1.getOptionalImportEnum());
+ assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+ value1.getRepeatedImportEnum(0));
+ assertEquals(1, value1.getOptionalForeignMessage().getC());
+ assertEquals(1, value1.getRepeatedForeignMessage(0).getC());
+
+ // Make sure value2 is correct
+ assertEquals(200, value2.getOptionalSfixed64());
+ assertEquals(200, value2.getRepeatedInt32(0));
+ assertEquals(UnittestImport.ImportEnum.IMPORT_FOO,
+ value2.getOptionalImportEnum());
+ assertEquals(UnittestImport.ImportEnum.IMPORT_FOO,
+ value2.getRepeatedImportEnum(0));
+ assertEquals(2, value2.getOptionalForeignMessage().getC());
+ assertEquals(2, value2.getRepeatedForeignMessage(0).getC());
+ }
+
+ public void testProtosShareRepeatedArraysIfDidntChange() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ builder.addRepeatedInt32(100);
+ builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+ builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
+
+ TestAllTypes value1 = builder.build();
+ TestAllTypes value2 = value1.toBuilder().build();
+
+ assertSame(value1.getRepeatedInt32List(), value2.getRepeatedInt32List());
+ assertSame(value1.getRepeatedImportEnumList(),
+ value2.getRepeatedImportEnumList());
+ assertSame(value1.getRepeatedForeignMessageList(),
+ value2.getRepeatedForeignMessageList());
+ }
+
+ public void testRepeatedArraysAreImmutable() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ builder.addRepeatedInt32(100);
+ builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+ builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
+ assertIsUnmodifiable(builder.getRepeatedInt32List());
+ assertIsUnmodifiable(builder.getRepeatedImportEnumList());
+ assertIsUnmodifiable(builder.getRepeatedForeignMessageList());
+ assertIsUnmodifiable(builder.getRepeatedFloatList());
+
+
+ TestAllTypes value = builder.build();
+ assertIsUnmodifiable(value.getRepeatedInt32List());
+ assertIsUnmodifiable(value.getRepeatedImportEnumList());
+ assertIsUnmodifiable(value.getRepeatedForeignMessageList());
+ assertIsUnmodifiable(value.getRepeatedFloatList());
+ }
+
+ private void assertIsUnmodifiable(List<?> list) {
+ if (list == Collections.emptyList()) {
+ // OKAY -- Need to check this b/c EmptyList allows you to call clear.
+ } else {
+ try {
+ list.clear();
+ fail("List wasn't immutable");
+ } catch (UnsupportedOperationException e) {
+ // good
+ }
+ }
+ }
+
+ public void testSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ try {
+ builder.setOptionalString(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalBytes(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedMessage(
+ (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setOptionalNestedEnum(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedString(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedBytes(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedMessage(
+ (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedNestedEnum(null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ public void testRepeatedSetters() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestUtil.modifyRepeatedFields(builder);
+ TestAllTypes message = builder.build();
+ TestUtil.assertRepeatedFieldsModified(message);
+ }
+
+ public void testRepeatedSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ builder.addRepeatedString("one");
+ builder.addRepeatedString("two");
+ try {
+ builder.setRepeatedString(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedBytes(TestUtil.toBytes("one"));
+ builder.addRepeatedBytes(TestUtil.toBytes("two"));
+ try {
+ builder.setRepeatedBytes(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ builder.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(456).build());
+ try {
+ builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setRepeatedNestedMessage(
+ 1, (TestAllTypes.NestedMessage.Builder) null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO);
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
+ try {
+ builder.setRepeatedNestedEnum(1, null);
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ public void testRepeatedAppend() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ builder.addAllRepeatedInt32(Arrays.asList(1, 2, 3, 4));
+ builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ));
+
+ ForeignMessage foreignMessage =
+ ForeignMessage.newBuilder().setC(12).build();
+ builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage));
+
+ TestAllTypes message = builder.build();
+ assertEquals(message.getRepeatedInt32List(), Arrays.asList(1, 2, 3, 4));
+ assertEquals(message.getRepeatedForeignEnumList(),
+ Arrays.asList(ForeignEnum.FOREIGN_BAZ));
+ assertEquals(1, message.getRepeatedForeignMessageCount());
+ assertEquals(12, message.getRepeatedForeignMessage(0).getC());
+ }
+
+ public void testRepeatedAppendRejectsNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ ForeignMessage foreignMessage =
+ ForeignMessage.newBuilder().setC(12).build();
+ try {
+ builder.addAllRepeatedForeignMessage(
+ Arrays.asList(foreignMessage, (ForeignMessage) null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedForeignEnum(
+ Arrays.asList(ForeignEnum.FOREIGN_BAZ, null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedString(Arrays.asList("one", null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null));
+ fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ public void testSettingForeignMessageUsingBuilder() throws Exception {
+ TestAllTypes message = TestAllTypes.newBuilder()
+ // Pass builder for foreign message instance.
+ .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123))
+ .build();
+ TestAllTypes expectedMessage = TestAllTypes.newBuilder()
+ // Create expected version passing foreign message instance explicitly.
+ .setOptionalForeignMessage(
+ ForeignMessage.newBuilder().setC(123).build())
+ .build();
+ // TODO(ngd): Upgrade to using real #equals method once implemented
+ assertEquals(expectedMessage.toString(), message.toString());
+ }
+
+ public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception {
+ TestAllTypes message = TestAllTypes.newBuilder()
+ // Pass builder for foreign message instance.
+ .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456))
+ .build();
+ TestAllTypes expectedMessage = TestAllTypes.newBuilder()
+ // Create expected version passing foreign message instance explicitly.
+ .addRepeatedForeignMessage(
+ ForeignMessage.newBuilder().setC(456).build())
+ .build();
+ assertEquals(expectedMessage.toString(), message.toString());
+ }
+
+ public void testDefaults() throws Exception {
+ TestUtil.assertClear(TestAllTypes.getDefaultInstance());
+ TestUtil.assertClear(TestAllTypes.newBuilder().build());
+
+ TestExtremeDefaultValues message =
+ TestExtremeDefaultValues.getDefaultInstance();
+ assertEquals("\u1234", message.getUtf8String());
+ assertEquals(Double.POSITIVE_INFINITY, message.getInfDouble());
+ assertEquals(Double.NEGATIVE_INFINITY, message.getNegInfDouble());
+ assertTrue(Double.isNaN(message.getNanDouble()));
+ assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat());
+ assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat());
+ assertTrue(Float.isNaN(message.getNanFloat()));
+ assertEquals("? ? ?? ?? ??? ??/ ??-", message.getCppTrigraph());
+ }
+
+ public void testClear() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.assertClear(builder);
+ TestUtil.setAllFields(builder);
+ builder.clear();
+ TestUtil.assertClear(builder);
+ }
+
+ public void testReflectionGetters() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ reflectionTester.assertAllFieldsSetViaReflection(builder);
+
+ TestAllTypes message = builder.build();
+ reflectionTester.assertAllFieldsSetViaReflection(message);
+ }
+
+ public void testReflectionSetters() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.setAllFieldsViaReflection(builder);
+ TestUtil.assertAllFieldsSet(builder);
+
+ TestAllTypes message = builder.build();
+ TestUtil.assertAllFieldsSet(message);
+ }
+
+ public void testReflectionSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
+ public void testReflectionRepeatedSetters() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.setAllFieldsViaReflection(builder);
+ reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ TestUtil.assertRepeatedFieldsModified(builder);
+
+ TestAllTypes message = builder.build();
+ TestUtil.assertRepeatedFieldsModified(message);
+ }
+
+ public void testReflectionRepeatedSettersRejectNull() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
+ }
+
+ public void testReflectionDefaults() throws Exception {
+ reflectionTester.assertClearViaReflection(
+ TestAllTypes.getDefaultInstance());
+ reflectionTester.assertClearViaReflection(
+ TestAllTypes.newBuilder().build());
+ }
+
+ public void testEnumInterface() throws Exception {
+ assertTrue(TestAllTypes.getDefaultInstance().getDefaultNestedEnum()
+ instanceof ProtocolMessageEnum);
+ }
+
+ public void testEnumMap() throws Exception {
+ Internal.EnumLiteMap<ForeignEnum> map = ForeignEnum.internalGetValueMap();
+
+ for (ForeignEnum value : ForeignEnum.values()) {
+ assertEquals(value, map.findValueByNumber(value.getNumber()));
+ }
+
+ assertTrue(map.findValueByNumber(12345) == null);
+ }
+
+ public void testParsePackedToUnpacked() throws Exception {
+ TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder();
+ TestUnpackedTypes message =
+ builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+ TestUtil.assertUnpackedFieldsSet(message);
+ }
+
+ public void testParseUnpackedToPacked() throws Exception {
+ TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+ TestPackedTypes message =
+ builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+ TestUtil.assertPackedFieldsSet(message);
+ }
+
+ // =================================================================
+ // Extensions.
+
+ TestUtil.ReflectionTester extensionsReflectionTester =
+ new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+ TestUtil.getExtensionRegistry());
+
+ public void testExtensionMessageOrBuilder() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ TestUtil.setAllExtensions(builder);
+ TestAllExtensions message = builder.build();
+ TestUtil.assertAllExtensionsSet(message);
+ }
+
+ public void testExtensionRepeatedSetters() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ TestUtil.setAllExtensions(builder);
+ TestUtil.modifyRepeatedExtensions(builder);
+ TestAllExtensions message = builder.build();
+ TestUtil.assertRepeatedExtensionsModified(message);
+ }
+
+ public void testExtensionDefaults() throws Exception {
+ TestUtil.assertExtensionsClear(TestAllExtensions.getDefaultInstance());
+ TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build());
+ }
+
+ public void testExtensionReflectionGetters() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ TestUtil.setAllExtensions(builder);
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(builder);
+
+ TestAllExtensions message = builder.build();
+ extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
+ }
+
+ public void testExtensionReflectionSetters() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.setAllFieldsViaReflection(builder);
+ TestUtil.assertAllExtensionsSet(builder);
+
+ TestAllExtensions message = builder.build();
+ TestUtil.assertAllExtensionsSet(message);
+ }
+
+ public void testExtensionReflectionSettersRejectNull() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
+ }
+
+ public void testExtensionReflectionRepeatedSetters() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.setAllFieldsViaReflection(builder);
+ extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder);
+ TestUtil.assertRepeatedExtensionsModified(builder);
+
+ TestAllExtensions message = builder.build();
+ TestUtil.assertRepeatedExtensionsModified(message);
+ }
+
+ public void testExtensionReflectionRepeatedSettersRejectNull()
+ throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull(
+ builder);
+ }
+
+ public void testExtensionReflectionDefaults() throws Exception {
+ extensionsReflectionTester.assertClearViaReflection(
+ TestAllExtensions.getDefaultInstance());
+ extensionsReflectionTester.assertClearViaReflection(
+ TestAllExtensions.newBuilder().build());
+ }
+
+ public void testClearExtension() throws Exception {
+ // clearExtension() is not actually used in TestUtil, so try it manually.
+ assertFalse(
+ TestAllExtensions.newBuilder()
+ .setExtension(UnittestProto.optionalInt32Extension, 1)
+ .clearExtension(UnittestProto.optionalInt32Extension)
+ .hasExtension(UnittestProto.optionalInt32Extension));
+ assertEquals(0,
+ TestAllExtensions.newBuilder()
+ .addExtension(UnittestProto.repeatedInt32Extension, 1)
+ .clearExtension(UnittestProto.repeatedInt32Extension)
+ .getExtensionCount(UnittestProto.repeatedInt32Extension));
+ }
+
+ public void testExtensionCopy() throws Exception {
+ TestAllExtensions original = TestUtil.getAllExtensionsSet();
+ TestAllExtensions copy = TestAllExtensions.newBuilder(original).build();
+ TestUtil.assertAllExtensionsSet(copy);
+ }
+
+ public void testExtensionMergeFrom() throws Exception {
+ TestAllExtensions original =
+ TestAllExtensions.newBuilder()
+ .setExtension(UnittestProto.optionalInt32Extension, 1).build();
+ TestAllExtensions merged =
+ TestAllExtensions.newBuilder().mergeFrom(original).build();
+ assertTrue(merged.hasExtension(UnittestProto.optionalInt32Extension));
+ assertEquals(
+ 1, (int) merged.getExtension(UnittestProto.optionalInt32Extension));
+ }
+
+ // =================================================================
+ // Lite Extensions.
+
+ // We test lite extensions directly because they have a separate
+ // implementation from full extensions. In contrast, we do not test
+ // lite fields directly since they are implemented exactly the same as
+ // regular fields.
+
+ public void testLiteExtensionMessageOrBuilder() throws Exception {
+ TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
+ TestUtil.setAllExtensions(builder);
+ TestUtil.assertAllExtensionsSet(builder);
+
+ TestAllExtensionsLite message = builder.build();
+ TestUtil.assertAllExtensionsSet(message);
+ }
+
+ public void testLiteExtensionRepeatedSetters() throws Exception {
+ TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
+ TestUtil.setAllExtensions(builder);
+ TestUtil.modifyRepeatedExtensions(builder);
+ TestUtil.assertRepeatedExtensionsModified(builder);
+
+ TestAllExtensionsLite message = builder.build();
+ TestUtil.assertRepeatedExtensionsModified(message);
+ }
+
+ public void testLiteExtensionDefaults() throws Exception {
+ TestUtil.assertExtensionsClear(TestAllExtensionsLite.getDefaultInstance());
+ TestUtil.assertExtensionsClear(TestAllExtensionsLite.newBuilder().build());
+ }
+
+ public void testClearLiteExtension() throws Exception {
+ // clearExtension() is not actually used in TestUtil, so try it manually.
+ assertFalse(
+ TestAllExtensionsLite.newBuilder()
+ .setExtension(UnittestLite.optionalInt32ExtensionLite, 1)
+ .clearExtension(UnittestLite.optionalInt32ExtensionLite)
+ .hasExtension(UnittestLite.optionalInt32ExtensionLite));
+ assertEquals(0,
+ TestAllExtensionsLite.newBuilder()
+ .addExtension(UnittestLite.repeatedInt32ExtensionLite, 1)
+ .clearExtension(UnittestLite.repeatedInt32ExtensionLite)
+ .getExtensionCount(UnittestLite.repeatedInt32ExtensionLite));
+ }
+
+ public void testLiteExtensionCopy() throws Exception {
+ TestAllExtensionsLite original = TestUtil.getAllLiteExtensionsSet();
+ TestAllExtensionsLite copy =
+ TestAllExtensionsLite.newBuilder(original).build();
+ TestUtil.assertAllExtensionsSet(copy);
+ }
+
+ public void testLiteExtensionMergeFrom() throws Exception {
+ TestAllExtensionsLite original =
+ TestAllExtensionsLite.newBuilder()
+ .setExtension(UnittestLite.optionalInt32ExtensionLite, 1).build();
+ TestAllExtensionsLite merged =
+ TestAllExtensionsLite.newBuilder().mergeFrom(original).build();
+ assertTrue(merged.hasExtension(UnittestLite.optionalInt32ExtensionLite));
+ assertEquals(
+ 1, (int) merged.getExtension(UnittestLite.optionalInt32ExtensionLite));
+ }
+
+ // =================================================================
+ // multiple_files_test
+
+ public void testMultipleFilesOption() throws Exception {
+ // We mostly just want to check that things compile.
+ MessageWithNoOuter message =
+ MessageWithNoOuter.newBuilder()
+ .setNested(MessageWithNoOuter.NestedMessage.newBuilder().setI(1))
+ .addForeign(TestAllTypes.newBuilder().setOptionalInt32(1))
+ .setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ)
+ .setForeignEnum(EnumWithNoOuter.BAR)
+ .build();
+ assertEquals(message, MessageWithNoOuter.parseFrom(message.toByteString()));
+
+ assertEquals(MultipleFilesTestProto.getDescriptor(),
+ MessageWithNoOuter.getDescriptor().getFile());
+
+ Descriptors.FieldDescriptor field =
+ MessageWithNoOuter.getDescriptor().findFieldByName("foreign_enum");
+ assertEquals(EnumWithNoOuter.BAR.getValueDescriptor(),
+ message.getField(field));
+
+ assertEquals(MultipleFilesTestProto.getDescriptor(),
+ ServiceWithNoOuter.getDescriptor().getFile());
+
+ assertFalse(
+ TestAllExtensions.getDefaultInstance().hasExtension(
+ MultipleFilesTestProto.extensionWithOuter));
+ }
+
+ public void testOptionalFieldWithRequiredSubfieldsOptimizedForSize()
+ throws Exception {
+ TestOptionalOptimizedForSize message =
+ TestOptionalOptimizedForSize.getDefaultInstance();
+ assertTrue(message.isInitialized());
+
+ message = TestOptionalOptimizedForSize.newBuilder().setO(
+ TestRequiredOptimizedForSize.newBuilder().buildPartial()
+ ).buildPartial();
+ assertFalse(message.isInitialized());
+
+ message = TestOptionalOptimizedForSize.newBuilder().setO(
+ TestRequiredOptimizedForSize.newBuilder().setX(5).buildPartial()
+ ).buildPartial();
+ assertTrue(message.isInitialized());
+ }
+
+ public void testUninitializedExtensionInOptimizedForSize()
+ throws Exception {
+ TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
+ builder.setExtension(TestOptimizedForSize.testExtension2,
+ TestRequiredOptimizedForSize.newBuilder().buildPartial());
+ assertFalse(builder.isInitialized());
+ assertFalse(builder.buildPartial().isInitialized());
+
+ builder = TestOptimizedForSize.newBuilder();
+ builder.setExtension(TestOptimizedForSize.testExtension2,
+ TestRequiredOptimizedForSize.newBuilder().setX(10).buildPartial());
+ assertTrue(builder.isInitialized());
+ assertTrue(builder.buildPartial().isInitialized());
+ }
+
+ public void testToBuilder() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes message = builder.build();
+ TestUtil.assertAllFieldsSet(message);
+ TestUtil.assertAllFieldsSet(message.toBuilder().build());
+ }
+
+ public void testFieldConstantValues() throws Exception {
+ assertEquals(TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1);
+ assertEquals(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1);
+ assertEquals(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16);
+ assertEquals(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18);
+ assertEquals(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21);
+ assertEquals(TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31);
+ assertEquals(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46);
+ assertEquals(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48);
+ assertEquals(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51);
+ }
+
+ public void testExtensionConstantValues() throws Exception {
+ assertEquals(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER, 1000);
+ assertEquals(UnittestProto.TestRequired.MULTI_FIELD_NUMBER, 1001);
+ assertEquals(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1);
+ assertEquals(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16);
+ assertEquals(
+ UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18);
+ assertEquals(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 21);
+ assertEquals(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31);
+ assertEquals(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46);
+ assertEquals(
+ UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48);
+ assertEquals(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 51);
+ }
+
+ public void testRecursiveMessageDefaultInstance() throws Exception {
+ UnittestProto.TestRecursiveMessage message =
+ UnittestProto.TestRecursiveMessage.getDefaultInstance();
+ assertTrue(message != null);
+ assertTrue(message.getA() != null);
+ assertTrue(message.getA() == message);
+ }
+
+ public void testSerialize() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestUtil.setAllFields(builder);
+ TestAllTypes expected = builder.build();
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ try {
+ out.writeObject(expected);
+ } finally {
+ out.close();
+ }
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ TestAllTypes actual = (TestAllTypes) in.readObject();
+ assertEquals(expected, actual);
+ }
+
+ public void testSerializePartial() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestAllTypes expected = builder.buildPartial();
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ try {
+ out.writeObject(expected);
+ } finally {
+ out.close();
+ }
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ TestAllTypes actual = (TestAllTypes) in.readObject();
+ assertEquals(expected, actual);
+ }
+
+ public void testEnumValues() {
+ assertEquals(
+ TestAllTypes.NestedEnum.BAR.getNumber(),
+ TestAllTypes.NestedEnum.BAR_VALUE);
+ assertEquals(
+ TestAllTypes.NestedEnum.BAZ.getNumber(),
+ TestAllTypes.NestedEnum.BAZ_VALUE);
+ assertEquals(
+ TestAllTypes.NestedEnum.FOO.getNumber(),
+ TestAllTypes.NestedEnum.FOO_VALUE);
+ }
+
+ public void testNonNestedExtensionInitialization() {
+ assertTrue(NonNestedExtension.nonNestedExtension
+ .getMessageDefaultInstance() instanceof MyNonNestedExtension);
+ assertEquals("nonNestedExtension",
+ NonNestedExtension.nonNestedExtension.getDescriptor().getName());
+ }
+
+ public void testNestedExtensionInitialization() {
+ assertTrue(MyNestedExtension.recursiveExtension.getMessageDefaultInstance()
+ instanceof MessageToBeExtended);
+ assertEquals("recursiveExtension",
+ MyNestedExtension.recursiveExtension.getDescriptor().getName());
+ }
+
+ public void testNonNestedExtensionLiteInitialization() {
+ assertTrue(NonNestedExtensionLite.nonNestedExtensionLite
+ .getMessageDefaultInstance() instanceof MyNonNestedExtensionLite);
+ }
+
+ public void testNestedExtensionLiteInitialization() {
+ assertTrue(MyNestedExtensionLite.recursiveExtensionLite
+ .getMessageDefaultInstance() instanceof MessageLiteToBeExtended);
+ }
+
+ public void testInvalidations() throws Exception {
+ GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
+ TestAllTypes.NestedMessage nestedMessage1 =
+ TestAllTypes.NestedMessage.newBuilder().build();
+ TestAllTypes.NestedMessage nestedMessage2 =
+ TestAllTypes.NestedMessage.newBuilder().build();
+
+ // Set all three flavors (enum, primitive, message and singular/repeated)
+ // and verify no invalidations fired
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+
+ TestAllTypes.Builder builder = (TestAllTypes.Builder)
+ ((GeneratedMessage) TestAllTypes.getDefaultInstance()).
+ newBuilderForType(mockParent);
+ builder.setOptionalInt32(1);
+ builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
+ builder.setOptionalNestedMessage(nestedMessage1);
+ builder.addRepeatedInt32(1);
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
+ builder.addRepeatedNestedMessage(nestedMessage1);
+ assertEquals(0, mockParent.getInvalidationCount());
+
+ // Now tell it we want changes and make sure it's only fired once
+ // And do this for each flavor
+
+ // primitive single
+ builder.buildPartial();
+ builder.setOptionalInt32(2);
+ builder.setOptionalInt32(3);
+ assertEquals(1, mockParent.getInvalidationCount());
+
+ // enum single
+ builder.buildPartial();
+ builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ);
+ builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
+ assertEquals(2, mockParent.getInvalidationCount());
+
+ // message single
+ builder.buildPartial();
+ builder.setOptionalNestedMessage(nestedMessage2);
+ builder.setOptionalNestedMessage(nestedMessage1);
+ assertEquals(3, mockParent.getInvalidationCount());
+
+ // primitive repated
+ builder.buildPartial();
+ builder.addRepeatedInt32(2);
+ builder.addRepeatedInt32(3);
+ assertEquals(4, mockParent.getInvalidationCount());
+
+ // enum repeated
+ builder.buildPartial();
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
+ builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
+ assertEquals(5, mockParent.getInvalidationCount());
+
+ // message repeated
+ builder.buildPartial();
+ builder.addRepeatedNestedMessage(nestedMessage2);
+ builder.addRepeatedNestedMessage(nestedMessage1);
+ assertEquals(6, mockParent.getInvalidationCount());
+
+ }
+
+ public void testInvalidations_Extensions() throws Exception {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+
+ TestAllExtensions.Builder builder = (TestAllExtensions.Builder)
+ ((GeneratedMessage) TestAllExtensions.getDefaultInstance()).
+ newBuilderForType(mockParent);
+
+ builder.addExtension(UnittestProto.repeatedInt32Extension, 1);
+ builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2);
+ builder.clearExtension(UnittestProto.repeatedInt32Extension);
+ assertEquals(0, mockParent.getInvalidationCount());
+
+ // Now tell it we want changes and make sure it's only fired once
+ builder.buildPartial();
+ builder.addExtension(UnittestProto.repeatedInt32Extension, 2);
+ builder.addExtension(UnittestProto.repeatedInt32Extension, 3);
+ assertEquals(1, mockParent.getInvalidationCount());
+
+ builder.buildPartial();
+ builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4);
+ builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5);
+ assertEquals(2, mockParent.getInvalidationCount());
+
+ builder.buildPartial();
+ builder.clearExtension(UnittestProto.repeatedInt32Extension);
+ builder.clearExtension(UnittestProto.repeatedInt32Extension);
+ assertEquals(3, mockParent.getInvalidationCount());
+ }
+
+ public void testBaseMessageOrBuilder() {
+ // Mostly just makes sure the base interface exists and has some methods.
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TestAllTypes message = builder.buildPartial();
+ TestAllTypesOrBuilder builderAsInterface = (TestAllTypesOrBuilder) builder;
+ TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message;
+
+ assertEquals(
+ messageAsInterface.getDefaultBool(),
+ messageAsInterface.getDefaultBool());
+ assertEquals(
+ messageAsInterface.getOptionalDouble(),
+ messageAsInterface.getOptionalDouble());
+ }
+
+ public void testMessageOrBuilderGetters() {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+ // single fields
+ assertSame(ForeignMessage.getDefaultInstance(),
+ builder.getOptionalForeignMessageOrBuilder());
+ ForeignMessage.Builder subBuilder =
+ builder.getOptionalForeignMessageBuilder();
+ assertSame(subBuilder, builder.getOptionalForeignMessageOrBuilder());
+
+ // repeated fields
+ ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial();
+ ForeignMessage m1 = ForeignMessage.newBuilder().buildPartial();
+ ForeignMessage m2 = ForeignMessage.newBuilder().buildPartial();
+ builder.addRepeatedForeignMessage(m0);
+ builder.addRepeatedForeignMessage(m1);
+ builder.addRepeatedForeignMessage(m2);
+ assertSame(m0, builder.getRepeatedForeignMessageOrBuilder(0));
+ assertSame(m1, builder.getRepeatedForeignMessageOrBuilder(1));
+ assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2));
+ ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0);
+ ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1);
+ assertSame(b0, builder.getRepeatedForeignMessageOrBuilder(0));
+ assertSame(b1, builder.getRepeatedForeignMessageOrBuilder(1));
+ assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2));
+
+ List<? extends ForeignMessageOrBuilder> messageOrBuilderList =
+ builder.getRepeatedForeignMessageOrBuilderList();
+ assertSame(b0, messageOrBuilderList.get(0));
+ assertSame(b1, messageOrBuilderList.get(1));
+ assertSame(m2, messageOrBuilderList.get(2));
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
new file mode 100644
index 0000000..4dcdc74
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
@@ -0,0 +1,118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link LazyStringArrayList}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringArrayListTest extends TestCase {
+
+ private static String STRING_A = "A";
+ private static String STRING_B = "B";
+ private static String STRING_C = "C";
+
+ private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A");
+ private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B");
+ private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C");
+
+ public void testJustStrings() {
+ LazyStringArrayList list = new LazyStringArrayList();
+ list.add(STRING_A);
+ list.add(STRING_B);
+ list.add(STRING_C);
+
+ assertEquals(3, list.size());
+ assertSame(STRING_A, list.get(0));
+ assertSame(STRING_B, list.get(1));
+ assertSame(STRING_C, list.get(2));
+
+ list.set(1, STRING_C);
+ assertSame(STRING_C, list.get(1));
+
+ list.remove(1);
+ assertSame(STRING_A, list.get(0));
+ assertSame(STRING_C, list.get(1));
+ }
+
+ public void testJustByteString() {
+ LazyStringArrayList list = new LazyStringArrayList();
+ list.add(BYTE_STRING_A);
+ list.add(BYTE_STRING_B);
+ list.add(BYTE_STRING_C);
+
+ assertEquals(3, list.size());
+ assertSame(BYTE_STRING_A, list.getByteString(0));
+ assertSame(BYTE_STRING_B, list.getByteString(1));
+ assertSame(BYTE_STRING_C, list.getByteString(2));
+
+ list.remove(1);
+ assertSame(BYTE_STRING_A, list.getByteString(0));
+ assertSame(BYTE_STRING_C, list.getByteString(1));
+ }
+
+ public void testConversionBackAndForth() {
+ LazyStringArrayList list = new LazyStringArrayList();
+ list.add(STRING_A);
+ list.add(BYTE_STRING_B);
+ list.add(BYTE_STRING_C);
+
+ // String a should be the same because it was originally a string
+ assertSame(STRING_A, list.get(0));
+
+ // String b and c should be different because the string has to be computed
+ // from the ByteString
+ String bPrime = list.get(1);
+ assertNotSame(STRING_B, bPrime);
+ assertEquals(STRING_B, bPrime);
+ String cPrime = list.get(2);
+ assertNotSame(STRING_C, cPrime);
+ assertEquals(STRING_C, cPrime);
+
+ // String c and c should stay the same once cached.
+ assertSame(bPrime, list.get(1));
+ assertSame(cPrime, list.get(2));
+
+ // ByteString needs to be computed from string for both a and b
+ ByteString aPrimeByteString = list.getByteString(0);
+ assertEquals(BYTE_STRING_A, aPrimeByteString);
+ ByteString bPrimeByteString = list.getByteString(1);
+ assertNotSame(BYTE_STRING_B, bPrimeByteString);
+ assertEquals(BYTE_STRING_B, list.getByteString(1));
+
+ // Once cached, ByteString should stay cached.
+ assertSame(aPrimeByteString, list.getByteString(0));
+ assertSame(bPrimeByteString, list.getByteString(1));
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
new file mode 100644
index 0000000..e6870b5
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
@@ -0,0 +1,115 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+
+import protobuf_unittest.UnittestProto;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+
+/**
+ * Tests to make sure the lazy conversion of UTF8-encoded byte arrays to
+ * strings works correctly.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringEndToEndTest extends TestCase {
+
+ private static ByteString TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8 =
+ ByteString.copyFrom(new byte[] {
+ 114, 4, -1, 0, -1, 0, -30, 2, 4, -1,
+ 0, -1, 0, -30, 2, 4, -1, 0, -1, 0, });
+
+ /**
+ * Tests that an invalid UTF8 string will roundtrip through a parse
+ * and serialization.
+ */
+ public void testParseAndSerialize() throws InvalidProtocolBufferException {
+ UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom(
+ TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8);
+ ByteString bytes = tV2.toByteString();
+ assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes);
+
+ tV2.getOptionalString();
+ bytes = tV2.toByteString();
+ assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes);
+ }
+
+ public void testParseAndWrite() throws IOException {
+ UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom(
+ TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8);
+ byte[] sink = new byte[TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8.size()];
+ CodedOutputStream outputStream = CodedOutputStream.newInstance(sink);
+ tV2.writeTo(outputStream);
+ outputStream.flush();
+ assertEquals(
+ TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8,
+ ByteString.copyFrom(sink));
+ }
+
+ public void testCaching() {
+ String a = "a";
+ String b = "b";
+ String c = "c";
+ UnittestProto.TestAllTypes proto = UnittestProto.TestAllTypes.newBuilder()
+ .setOptionalString(a)
+ .addRepeatedString(b)
+ .addRepeatedString(c)
+ .build();
+
+ // String should be the one we passed it.
+ assertSame(a, proto.getOptionalString());
+ assertSame(b, proto.getRepeatedString(0));
+ assertSame(c, proto.getRepeatedString(1));
+
+
+ // There's no way to directly observe that the ByteString is cached
+ // correctly on serialization, but we can observe that it had to recompute
+ // the string after serialization.
+ proto.toByteString();
+ String aPrime = proto.getOptionalString();
+ assertNotSame(a, aPrime);
+ assertEquals(a, aPrime);
+ String bPrime = proto.getRepeatedString(0);
+ assertNotSame(b, bPrime);
+ assertEquals(b, bPrime);
+ String cPrime = proto.getRepeatedString(1);
+ assertNotSame(c, cPrime);
+ assertEquals(c, cPrime);
+
+ // And now the string should stay cached.
+ assertSame(aPrime, proto.getOptionalString());
+ assertSame(bPrime, proto.getRepeatedString(0));
+ assertSame(cPrime, proto.getRepeatedString(1));
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LiteTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LiteTest.java
new file mode 100644
index 0000000..839694d
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/LiteTest.java
@@ -0,0 +1,148 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.UnittestLite;
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestNestedExtensionLite;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * Test lite runtime.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class LiteTest extends TestCase {
+ public void setUp() throws Exception {
+ // Test that nested extensions are initialized correctly even if the outer
+ // class has not been accessed directly. This was once a bug with lite
+ // messages.
+ //
+ // We put this in setUp() rather than in its own test method because we
+ // need to make sure it runs before any actual tests.
+ assertTrue(TestNestedExtensionLite.nestedExtension != null);
+ }
+
+ public void testLite() throws Exception {
+ // Since lite messages are a subset of regular messages, we can mostly
+ // assume that the functionality of lite messages is already thoroughly
+ // tested by the regular tests. All this test really verifies is that
+ // a proto with optimize_for = LITE_RUNTIME compiles correctly when
+ // linked only against the lite library. That is all tested at compile
+ // time, leaving not much to do in this method. Let's just do some random
+ // stuff to make sure the lite message is actually here and usable.
+
+ TestAllTypesLite message =
+ TestAllTypesLite.newBuilder()
+ .setOptionalInt32(123)
+ .addRepeatedString("hello")
+ .setOptionalNestedMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(7))
+ .build();
+
+ ByteString data = message.toByteString();
+
+ TestAllTypesLite message2 = TestAllTypesLite.parseFrom(data);
+
+ assertEquals(123, message2.getOptionalInt32());
+ assertEquals(1, message2.getRepeatedStringCount());
+ assertEquals("hello", message2.getRepeatedString(0));
+ assertEquals(7, message2.getOptionalNestedMessage().getBb());
+ }
+
+ public void testLiteExtensions() throws Exception {
+ // TODO(kenton): Unlike other features of the lite library, extensions are
+ // implemented completely differently from the regular library. We
+ // should probably test them more thoroughly.
+
+ TestAllExtensionsLite message =
+ TestAllExtensionsLite.newBuilder()
+ .setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
+ .addExtension(UnittestLite.repeatedStringExtensionLite, "hello")
+ .setExtension(UnittestLite.optionalNestedEnumExtensionLite,
+ TestAllTypesLite.NestedEnum.BAZ)
+ .setExtension(UnittestLite.optionalNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(7).build())
+ .build();
+
+ // Test copying a message, since coping extensions actually does use a
+ // different code path between lite and regular libraries, and as of this
+ // writing, parsing hasn't been implemented yet.
+ TestAllExtensionsLite message2 = message.toBuilder().build();
+
+ assertEquals(123, (int) message2.getExtension(
+ UnittestLite.optionalInt32ExtensionLite));
+ assertEquals(1, message2.getExtensionCount(
+ UnittestLite.repeatedStringExtensionLite));
+ assertEquals(1, message2.getExtension(
+ UnittestLite.repeatedStringExtensionLite).size());
+ assertEquals("hello", message2.getExtension(
+ UnittestLite.repeatedStringExtensionLite, 0));
+ assertEquals(TestAllTypesLite.NestedEnum.BAZ, message2.getExtension(
+ UnittestLite.optionalNestedEnumExtensionLite));
+ assertEquals(7, message2.getExtension(
+ UnittestLite.optionalNestedMessageExtensionLite).getBb());
+ }
+
+ public void testSerialize() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ TestAllTypesLite expected =
+ TestAllTypesLite.newBuilder()
+ .setOptionalInt32(123)
+ .addRepeatedString("hello")
+ .setOptionalNestedMessage(
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(7))
+ .build();
+ ObjectOutputStream out = new ObjectOutputStream(baos);
+ try {
+ out.writeObject(expected);
+ } finally {
+ out.close();
+ }
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream in = new ObjectInputStream(bais);
+ TestAllTypesLite actual = (TestAllTypesLite) in.readObject();
+ assertEquals(expected.getOptionalInt32(), actual.getOptionalInt32());
+ assertEquals(expected.getRepeatedStringCount(),
+ actual.getRepeatedStringCount());
+ assertEquals(expected.getRepeatedString(0),
+ actual.getRepeatedString(0));
+ assertEquals(expected.getOptionalNestedMessage().getBb(),
+ actual.getOptionalNestedMessage().getBb());
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/MessageTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/MessageTest.java
new file mode 100644
index 0000000..c2f47eb
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/MessageTest.java
@@ -0,0 +1,313 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestRequiredForeign;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+
+import junit.framework.TestCase;
+
+/**
+ * Misc. unit tests for message operations that apply to both generated
+ * and dynamic messages.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class MessageTest extends TestCase {
+ // =================================================================
+ // Message-merging tests.
+
+ static final TestAllTypes MERGE_SOURCE =
+ TestAllTypes.newBuilder()
+ .setOptionalInt32(1)
+ .setOptionalString("foo")
+ .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
+ .addRepeatedString("bar")
+ .build();
+
+ static final TestAllTypes MERGE_DEST =
+ TestAllTypes.newBuilder()
+ .setOptionalInt64(2)
+ .setOptionalString("baz")
+ .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
+ .addRepeatedString("qux")
+ .build();
+
+ static final String MERGE_RESULT_TEXT =
+ "optional_int32: 1\n" +
+ "optional_int64: 2\n" +
+ "optional_string: \"foo\"\n" +
+ "optional_foreign_message {\n" +
+ " c: 3\n" +
+ "}\n" +
+ "repeated_string: \"qux\"\n" +
+ "repeated_string: \"bar\"\n";
+
+ public void testMergeFrom() throws Exception {
+ TestAllTypes result =
+ TestAllTypes.newBuilder(MERGE_DEST)
+ .mergeFrom(MERGE_SOURCE).build();
+
+ assertEquals(MERGE_RESULT_TEXT, result.toString());
+ }
+
+ /**
+ * Test merging a DynamicMessage into a GeneratedMessage. As long as they
+ * have the same descriptor, this should work, but it is an entirely different
+ * code path.
+ */
+ public void testMergeFromDynamic() throws Exception {
+ TestAllTypes result =
+ TestAllTypes.newBuilder(MERGE_DEST)
+ .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
+ .build();
+
+ assertEquals(MERGE_RESULT_TEXT, result.toString());
+ }
+
+ /** Test merging two DynamicMessages. */
+ public void testDynamicMergeFrom() throws Exception {
+ DynamicMessage result =
+ DynamicMessage.newBuilder(MERGE_DEST)
+ .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
+ .build();
+
+ assertEquals(MERGE_RESULT_TEXT, result.toString());
+ }
+
+ // =================================================================
+ // Required-field-related tests.
+
+ private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
+ TestRequired.getDefaultInstance();
+ private static final TestRequired TEST_REQUIRED_INITIALIZED =
+ TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
+
+ public void testRequired() throws Exception {
+ TestRequired.Builder builder = TestRequired.newBuilder();
+
+ assertFalse(builder.isInitialized());
+ builder.setA(1);
+ assertFalse(builder.isInitialized());
+ builder.setB(1);
+ assertFalse(builder.isInitialized());
+ builder.setC(1);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testRequiredForeign() throws Exception {
+ TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
+
+ assertTrue(builder.isInitialized());
+
+ builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+
+ builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testRequiredExtension() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+
+ assertTrue(builder.isInitialized());
+
+ builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+
+ builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testRequiredDynamic() throws Exception {
+ Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+ DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
+
+ assertFalse(builder.isInitialized());
+ builder.setField(descriptor.findFieldByName("a"), 1);
+ assertFalse(builder.isInitialized());
+ builder.setField(descriptor.findFieldByName("b"), 1);
+ assertFalse(builder.isInitialized());
+ builder.setField(descriptor.findFieldByName("c"), 1);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testRequiredDynamicForeign() throws Exception {
+ Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor();
+ DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
+
+ assertTrue(builder.isInitialized());
+
+ builder.setField(descriptor.findFieldByName("optional_message"),
+ TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setField(descriptor.findFieldByName("optional_message"),
+ TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+
+ builder.addRepeatedField(descriptor.findFieldByName("repeated_message"),
+ TEST_REQUIRED_UNINITIALIZED);
+ assertFalse(builder.isInitialized());
+
+ builder.setRepeatedField(descriptor.findFieldByName("repeated_message"), 0,
+ TEST_REQUIRED_INITIALIZED);
+ assertTrue(builder.isInitialized());
+ }
+
+ public void testUninitializedException() throws Exception {
+ try {
+ TestRequired.newBuilder().build();
+ fail("Should have thrown an exception.");
+ } catch (UninitializedMessageException e) {
+ assertEquals("Message missing required fields: a, b, c", e.getMessage());
+ }
+ }
+
+ public void testBuildPartial() throws Exception {
+ // We're mostly testing that no exception is thrown.
+ TestRequired message = TestRequired.newBuilder().buildPartial();
+ assertFalse(message.isInitialized());
+ }
+
+ public void testNestedUninitializedException() throws Exception {
+ try {
+ TestRequiredForeign.newBuilder()
+ .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .build();
+ fail("Should have thrown an exception.");
+ } catch (UninitializedMessageException e) {
+ assertEquals(
+ "Message missing required fields: " +
+ "optional_message.a, " +
+ "optional_message.b, " +
+ "optional_message.c, " +
+ "repeated_message[0].a, " +
+ "repeated_message[0].b, " +
+ "repeated_message[0].c, " +
+ "repeated_message[1].a, " +
+ "repeated_message[1].b, " +
+ "repeated_message[1].c",
+ e.getMessage());
+ }
+ }
+
+ public void testBuildNestedPartial() throws Exception {
+ // We're mostly testing that no exception is thrown.
+ TestRequiredForeign message =
+ TestRequiredForeign.newBuilder()
+ .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .buildPartial();
+ assertFalse(message.isInitialized());
+ }
+
+ public void testParseUnititialized() throws Exception {
+ try {
+ TestRequired.parseFrom(ByteString.EMPTY);
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals("Message missing required fields: a, b, c", e.getMessage());
+ }
+ }
+
+ public void testParseNestedUnititialized() throws Exception {
+ ByteString data =
+ TestRequiredForeign.newBuilder()
+ .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+ .buildPartial().toByteString();
+
+ try {
+ TestRequiredForeign.parseFrom(data);
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals(
+ "Message missing required fields: " +
+ "optional_message.a, " +
+ "optional_message.b, " +
+ "optional_message.c, " +
+ "repeated_message[0].a, " +
+ "repeated_message[0].b, " +
+ "repeated_message[0].c, " +
+ "repeated_message[1].a, " +
+ "repeated_message[1].b, " +
+ "repeated_message[1].c",
+ e.getMessage());
+ }
+ }
+
+ public void testDynamicUninitializedException() throws Exception {
+ try {
+ DynamicMessage.newBuilder(TestRequired.getDescriptor()).build();
+ fail("Should have thrown an exception.");
+ } catch (UninitializedMessageException e) {
+ assertEquals("Message missing required fields: a, b, c", e.getMessage());
+ }
+ }
+
+ public void testDynamicBuildPartial() throws Exception {
+ // We're mostly testing that no exception is thrown.
+ DynamicMessage message =
+ DynamicMessage.newBuilder(TestRequired.getDescriptor())
+ .buildPartial();
+ assertFalse(message.isInitialized());
+ }
+
+ public void testDynamicParseUnititialized() throws Exception {
+ try {
+ Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+ DynamicMessage.parseFrom(descriptor, ByteString.EMPTY);
+ fail("Should have thrown an exception.");
+ } catch (InvalidProtocolBufferException e) {
+ assertEquals("Message missing required fields: a, b, c", e.getMessage());
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/NestedBuildersTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/NestedBuildersTest.java
new file mode 100644
index 0000000..f537580
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/NestedBuildersTest.java
@@ -0,0 +1,185 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.Vehicle;
+import protobuf_unittest.Wheel;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Test cases that exercise end-to-end use cases involving
+ * {@link SingleFieldBuilder} and {@link RepeatedFieldBuilder}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class NestedBuildersTest extends TestCase {
+
+ public void testMessagesAndBuilders() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(4)
+ .setWidth(1);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(4)
+ .setWidth(2);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(4)
+ .setWidth(3);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(4)
+ .setWidth(4);
+ vehicleBuilder.getEngineBuilder()
+ .setLiters(10);
+
+ Vehicle vehicle = vehicleBuilder.build();
+ assertEquals(4, vehicle.getWheelCount());
+ for (int i = 0; i < 4; i++) {
+ Wheel wheel = vehicle.getWheel(i);
+ assertEquals(4, wheel.getRadius());
+ assertEquals(i + 1, wheel.getWidth());
+ }
+ assertEquals(10, vehicle.getEngine().getLiters());
+
+ for (int i = 0; i < 4; i++) {
+ vehicleBuilder.getWheelBuilder(i)
+ .setRadius(5)
+ .setWidth(i + 10);
+ }
+ vehicleBuilder.getEngineBuilder().setLiters(20);
+
+ vehicle = vehicleBuilder.build();
+ for (int i = 0; i < 4; i++) {
+ Wheel wheel = vehicle.getWheel(i);
+ assertEquals(5, wheel.getRadius());
+ assertEquals(i + 10, wheel.getWidth());
+ }
+ assertEquals(20, vehicle.getEngine().getLiters());
+ assertTrue(vehicle.hasEngine());
+ }
+
+ public void testMessagesAreCached() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(1)
+ .setWidth(2);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(3)
+ .setWidth(4);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(5)
+ .setWidth(6);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(7)
+ .setWidth(8);
+
+ // Make sure messages are cached.
+ List<Wheel> wheels = new ArrayList<Wheel>(vehicleBuilder.getWheelList());
+ for (int i = 0; i < wheels.size(); i++) {
+ assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+ }
+
+ // Now get builders and check they didn't change.
+ for (int i = 0; i < wheels.size(); i++) {
+ vehicleBuilder.getWheel(i);
+ }
+ for (int i = 0; i < wheels.size(); i++) {
+ assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+ }
+
+ // Change just one
+ vehicleBuilder.getWheelBuilder(3)
+ .setRadius(20).setWidth(20);
+
+ // Now get wheels and check that only that one changed
+ for (int i = 0; i < wheels.size(); i++) {
+ if (i < 3) {
+ assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+ } else {
+ assertNotSame(wheels.get(i), vehicleBuilder.getWheel(i));
+ }
+ }
+ }
+
+ public void testRemove_WithNestedBuilders() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(1)
+ .setWidth(1);
+ vehicleBuilder.addWheelBuilder()
+ .setRadius(2)
+ .setWidth(2);
+ vehicleBuilder.removeWheel(0);
+
+ assertEquals(1, vehicleBuilder.getWheelCount());
+ assertEquals(2, vehicleBuilder.getWheel(0).getRadius());
+ }
+
+ public void testRemove_WithNestedMessages() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.addWheel(Wheel.newBuilder()
+ .setRadius(1)
+ .setWidth(1));
+ vehicleBuilder.addWheel(Wheel.newBuilder()
+ .setRadius(2)
+ .setWidth(2));
+ vehicleBuilder.removeWheel(0);
+
+ assertEquals(1, vehicleBuilder.getWheelCount());
+ assertEquals(2, vehicleBuilder.getWheel(0).getRadius());
+ }
+
+ public void testMerge() {
+ Vehicle vehicle1 = Vehicle.newBuilder()
+ .addWheel(Wheel.newBuilder().setRadius(1).build())
+ .addWheel(Wheel.newBuilder().setRadius(2).build())
+ .build();
+
+ Vehicle vehicle2 = Vehicle.newBuilder()
+ .mergeFrom(vehicle1)
+ .build();
+ // List should be the same -- no allocation
+ assertSame(vehicle1.getWheelList(), vehicle2.getWheelList());
+
+ Vehicle vehicle3 = vehicle1.toBuilder().build();
+ assertSame(vehicle1.getWheelList(), vehicle3.getWheelList());
+ }
+
+ public void testGettingBuilderMarksFieldAsHaving() {
+ Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+ vehicleBuilder.getEngineBuilder();
+ Vehicle vehicle = vehicleBuilder.buildPartial();
+ assertTrue(vehicle.hasEngine());
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java
new file mode 100644
index 0000000..cdcdcb2
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java
@@ -0,0 +1,190 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+
+import junit.framework.TestCase;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests for {@link RepeatedFieldBuilder}. This tests basic functionality.
+ * More extensive testing is provided via other tests that exercise the
+ * builder.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class RepeatedFieldBuilderTest extends TestCase {
+
+ public void testBasicUse() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+ List<TestAllTypes> list = builder.build();
+ assertEquals(2, list.size());
+ assertEquals(0, list.get(0).getOptionalInt32());
+ assertEquals(1, list.get(1).getOptionalInt32());
+ assertIsUnmodifiable(list);
+
+ // Make sure it doesn't change.
+ List<TestAllTypes> list2 = builder.build();
+ assertSame(list, list2);
+ assertEquals(0, mockParent.getInvalidationCount());
+ }
+
+ public void testGoingBackAndForth() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+ // Convert to list
+ List<TestAllTypes> list = builder.build();
+ assertEquals(2, list.size());
+ assertEquals(0, list.get(0).getOptionalInt32());
+ assertEquals(1, list.get(1).getOptionalInt32());
+ assertIsUnmodifiable(list);
+
+ // Update 0th item
+ assertEquals(0, mockParent.getInvalidationCount());
+ builder.getBuilder(0).setOptionalString("foo");
+ assertEquals(1, mockParent.getInvalidationCount());
+ list = builder.build();
+ assertEquals(2, list.size());
+ assertEquals(0, list.get(0).getOptionalInt32());
+ assertEquals("foo", list.get(0).getOptionalString());
+ assertEquals(1, list.get(1).getOptionalInt32());
+ assertIsUnmodifiable(list);
+ assertEquals(1, mockParent.getInvalidationCount());
+ }
+
+ public void testVariousMethods() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(2).build());
+ builder.addBuilder(0, TestAllTypes.getDefaultInstance())
+ .setOptionalInt32(0);
+ builder.addBuilder(TestAllTypes.getDefaultInstance()).setOptionalInt32(3);
+
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+ assertEquals(2, builder.getMessage(2).getOptionalInt32());
+ assertEquals(3, builder.getMessage(3).getOptionalInt32());
+
+ assertEquals(0, mockParent.getInvalidationCount());
+ List<TestAllTypes> messages = builder.build();
+ assertEquals(4, messages.size());
+ assertSame(messages, builder.build()); // expect same list
+
+ // Remove a message.
+ builder.remove(2);
+ assertEquals(1, mockParent.getInvalidationCount());
+ assertEquals(3, builder.getCount());
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+ assertEquals(3, builder.getMessage(2).getOptionalInt32());
+
+ // Remove a builder.
+ builder.remove(0);
+ assertEquals(1, mockParent.getInvalidationCount());
+ assertEquals(2, builder.getCount());
+ assertEquals(1, builder.getMessage(0).getOptionalInt32());
+ assertEquals(3, builder.getMessage(1).getOptionalInt32());
+
+ // Test clear.
+ builder.clear();
+ assertEquals(1, mockParent.getInvalidationCount());
+ assertEquals(0, builder.getCount());
+ assertTrue(builder.isEmpty());
+ }
+
+ public void testLists() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+ builder.addMessage(0,
+ TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ assertEquals(0, builder.getMessage(0).getOptionalInt32());
+ assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+ // Use list of builders.
+ List<TestAllTypes.Builder> builders = builder.getBuilderList();
+ assertEquals(0, builders.get(0).getOptionalInt32());
+ assertEquals(1, builders.get(1).getOptionalInt32());
+ builders.get(0).setOptionalInt32(10);
+ builders.get(1).setOptionalInt32(11);
+
+ // Use list of protos
+ List<TestAllTypes> protos = builder.getMessageList();
+ assertEquals(10, protos.get(0).getOptionalInt32());
+ assertEquals(11, protos.get(1).getOptionalInt32());
+
+ // Add an item to the builders and verify it's updated in both
+ builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(12).build());
+ assertEquals(3, builders.size());
+ assertEquals(3, protos.size());
+ }
+
+ private void assertIsUnmodifiable(List<?> list) {
+ if (list == Collections.emptyList()) {
+ // OKAY -- Need to check this b/c EmptyList allows you to call clear.
+ } else {
+ try {
+ list.clear();
+ fail("List wasn't immutable");
+ } catch (UnsupportedOperationException e) {
+ // good
+ }
+ }
+ }
+
+ private RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>
+ newRepeatedFieldBuilder(GeneratedMessage.BuilderParent parent) {
+ return new RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(Collections.<TestAllTypes>emptyList(), false,
+ parent, false);
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/ServiceTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/ServiceTest.java
new file mode 100644
index 0000000..4be84f5
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/ServiceTest.java
@@ -0,0 +1,320 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.Descriptors.MethodDescriptor;
+import google.protobuf.no_generic_services_test.UnittestNoGenericServices;
+import protobuf_unittest.MessageWithNoOuter;
+import protobuf_unittest.ServiceWithNoOuter;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestService;
+import protobuf_unittest.UnittestProto.FooRequest;
+import protobuf_unittest.UnittestProto.FooResponse;
+import protobuf_unittest.UnittestProto.BarRequest;
+import protobuf_unittest.UnittestProto.BarResponse;
+
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.easymock.IArgumentMatcher;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests services and stubs.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class ServiceTest extends TestCase {
+ private IMocksControl control;
+ private RpcController mockController;
+
+ private final Descriptors.MethodDescriptor fooDescriptor =
+ TestService.getDescriptor().getMethods().get(0);
+ private final Descriptors.MethodDescriptor barDescriptor =
+ TestService.getDescriptor().getMethods().get(1);
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ control = EasyMock.createStrictControl();
+ mockController = control.createMock(RpcController.class);
+ }
+
+ // =================================================================
+
+ /** Tests Service.callMethod(). */
+ public void testCallMethod() throws Exception {
+ FooRequest fooRequest = FooRequest.newBuilder().build();
+ BarRequest barRequest = BarRequest.newBuilder().build();
+ MockCallback<Message> fooCallback = new MockCallback<Message>();
+ MockCallback<Message> barCallback = new MockCallback<Message>();
+ TestService mockService = control.createMock(TestService.class);
+
+ mockService.foo(EasyMock.same(mockController), EasyMock.same(fooRequest),
+ this.<FooResponse>wrapsCallback(fooCallback));
+ mockService.bar(EasyMock.same(mockController), EasyMock.same(barRequest),
+ this.<BarResponse>wrapsCallback(barCallback));
+ control.replay();
+
+ mockService.callMethod(fooDescriptor, mockController,
+ fooRequest, fooCallback);
+ mockService.callMethod(barDescriptor, mockController,
+ barRequest, barCallback);
+ control.verify();
+ }
+
+ /** Tests Service.get{Request,Response}Prototype(). */
+ public void testGetPrototype() throws Exception {
+ TestService mockService = control.createMock(TestService.class);
+
+ assertSame(mockService.getRequestPrototype(fooDescriptor),
+ FooRequest.getDefaultInstance());
+ assertSame(mockService.getResponsePrototype(fooDescriptor),
+ FooResponse.getDefaultInstance());
+ assertSame(mockService.getRequestPrototype(barDescriptor),
+ BarRequest.getDefaultInstance());
+ assertSame(mockService.getResponsePrototype(barDescriptor),
+ BarResponse.getDefaultInstance());
+ }
+
+ /** Tests generated stubs. */
+ public void testStub() throws Exception {
+ FooRequest fooRequest = FooRequest.newBuilder().build();
+ BarRequest barRequest = BarRequest.newBuilder().build();
+ MockCallback<FooResponse> fooCallback = new MockCallback<FooResponse>();
+ MockCallback<BarResponse> barCallback = new MockCallback<BarResponse>();
+ RpcChannel mockChannel = control.createMock(RpcChannel.class);
+ TestService stub = TestService.newStub(mockChannel);
+
+ mockChannel.callMethod(
+ EasyMock.same(fooDescriptor),
+ EasyMock.same(mockController),
+ EasyMock.same(fooRequest),
+ EasyMock.same(FooResponse.getDefaultInstance()),
+ this.<Message>wrapsCallback(fooCallback));
+ mockChannel.callMethod(
+ EasyMock.same(barDescriptor),
+ EasyMock.same(mockController),
+ EasyMock.same(barRequest),
+ EasyMock.same(BarResponse.getDefaultInstance()),
+ this.<Message>wrapsCallback(barCallback));
+ control.replay();
+
+ stub.foo(mockController, fooRequest, fooCallback);
+ stub.bar(mockController, barRequest, barCallback);
+ control.verify();
+ }
+
+ /** Tests generated blocking stubs. */
+ public void testBlockingStub() throws Exception {
+ FooRequest fooRequest = FooRequest.newBuilder().build();
+ BarRequest barRequest = BarRequest.newBuilder().build();
+ BlockingRpcChannel mockChannel =
+ control.createMock(BlockingRpcChannel.class);
+ TestService.BlockingInterface stub =
+ TestService.newBlockingStub(mockChannel);
+
+ FooResponse fooResponse = FooResponse.newBuilder().build();
+ BarResponse barResponse = BarResponse.newBuilder().build();
+
+ EasyMock.expect(mockChannel.callBlockingMethod(
+ EasyMock.same(fooDescriptor),
+ EasyMock.same(mockController),
+ EasyMock.same(fooRequest),
+ EasyMock.same(FooResponse.getDefaultInstance()))).andReturn(fooResponse);
+ EasyMock.expect(mockChannel.callBlockingMethod(
+ EasyMock.same(barDescriptor),
+ EasyMock.same(mockController),
+ EasyMock.same(barRequest),
+ EasyMock.same(BarResponse.getDefaultInstance()))).andReturn(barResponse);
+ control.replay();
+
+ assertSame(fooResponse, stub.foo(mockController, fooRequest));
+ assertSame(barResponse, stub.bar(mockController, barRequest));
+ control.verify();
+ }
+
+ public void testNewReflectiveService() {
+ ServiceWithNoOuter.Interface impl =
+ control.createMock(ServiceWithNoOuter.Interface.class);
+ RpcController controller = control.createMock(RpcController.class);
+ Service service = ServiceWithNoOuter.newReflectiveService(impl);
+
+ MethodDescriptor fooMethod =
+ ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
+ MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
+ RpcCallback<Message> callback = new RpcCallback<Message>() {
+ public void run(Message parameter) {
+ // No reason this should be run.
+ fail();
+ }
+ };
+ RpcCallback<TestAllTypes> specializedCallback =
+ RpcUtil.specializeCallback(callback);
+
+ impl.foo(EasyMock.same(controller), EasyMock.same(request),
+ EasyMock.same(specializedCallback));
+ EasyMock.expectLastCall();
+
+ control.replay();
+
+ service.callMethod(fooMethod, controller, request, callback);
+
+ control.verify();
+ }
+
+ public void testNewReflectiveBlockingService() throws ServiceException {
+ ServiceWithNoOuter.BlockingInterface impl =
+ control.createMock(ServiceWithNoOuter.BlockingInterface.class);
+ RpcController controller = control.createMock(RpcController.class);
+ BlockingService service =
+ ServiceWithNoOuter.newReflectiveBlockingService(impl);
+
+ MethodDescriptor fooMethod =
+ ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
+ MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
+
+ TestAllTypes expectedResponse = TestAllTypes.getDefaultInstance();
+ EasyMock.expect(impl.foo(EasyMock.same(controller), EasyMock.same(request)))
+ .andReturn(expectedResponse);
+
+ control.replay();
+
+ Message response =
+ service.callBlockingMethod(fooMethod, controller, request);
+ assertEquals(expectedResponse, response);
+
+ control.verify();
+ }
+
+ public void testNoGenericServices() throws Exception {
+ // Non-services should be usable.
+ UnittestNoGenericServices.TestMessage message =
+ UnittestNoGenericServices.TestMessage.newBuilder()
+ .setA(123)
+ .setExtension(UnittestNoGenericServices.testExtension, 456)
+ .build();
+ assertEquals(123, message.getA());
+ assertEquals(1, UnittestNoGenericServices.TestEnum.FOO.getNumber());
+
+ // Build a list of the class names nested in UnittestNoGenericServices.
+ String outerName = "google.protobuf.no_generic_services_test." +
+ "UnittestNoGenericServices";
+ Class<?> outerClass = Class.forName(outerName);
+
+ Set<String> innerClassNames = new HashSet<String>();
+ for (Class<?> innerClass : outerClass.getClasses()) {
+ String fullName = innerClass.getName();
+ // Figure out the unqualified name of the inner class.
+ // Note: Surprisingly, the full name of an inner class will be separated
+ // from the outer class name by a '$' rather than a '.'. This is not
+ // mentioned in the documentation for java.lang.Class. I don't want to
+ // make assumptions, so I'm just going to accept any character as the
+ // separator.
+ assertTrue(fullName.startsWith(outerName));
+
+ if (!Service.class.isAssignableFrom(innerClass) &&
+ !Message.class.isAssignableFrom(innerClass) &&
+ !ProtocolMessageEnum.class.isAssignableFrom(innerClass)) {
+ // Ignore any classes not generated by the base code generator.
+ continue;
+ }
+
+ innerClassNames.add(fullName.substring(outerName.length() + 1));
+ }
+
+ // No service class should have been generated.
+ assertTrue(innerClassNames.contains("TestMessage"));
+ assertTrue(innerClassNames.contains("TestEnum"));
+ assertFalse(innerClassNames.contains("TestService"));
+
+ // But descriptors are there.
+ FileDescriptor file = UnittestNoGenericServices.getDescriptor();
+ assertEquals(1, file.getServices().size());
+ assertEquals("TestService", file.getServices().get(0).getName());
+ assertEquals(1, file.getServices().get(0).getMethods().size());
+ assertEquals("Foo",
+ file.getServices().get(0).getMethods().get(0).getName());
+ }
+
+ // =================================================================
+
+ /**
+ * wrapsCallback() is an EasyMock argument predicate. wrapsCallback(c)
+ * matches a callback if calling that callback causes c to be called.
+ * In other words, c wraps the given callback.
+ */
+ private <Type extends Message> RpcCallback<Type> wrapsCallback(
+ MockCallback<?> callback) {
+ EasyMock.reportMatcher(new WrapsCallback(callback));
+ return null;
+ }
+
+ /** The parameter to wrapsCallback() must be a MockCallback. */
+ private static class MockCallback<Type extends Message>
+ implements RpcCallback<Type> {
+ private boolean called = false;
+
+ public boolean isCalled() { return called; }
+
+ public void reset() { called = false; }
+ public void run(Type message) { called = true; }
+ }
+
+ /** Implementation of the wrapsCallback() argument matcher. */
+ private static class WrapsCallback implements IArgumentMatcher {
+ private MockCallback<?> callback;
+
+ public WrapsCallback(MockCallback<?> callback) {
+ this.callback = callback;
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean matches(Object actual) {
+ if (!(actual instanceof RpcCallback)) {
+ return false;
+ }
+ RpcCallback actualCallback = (RpcCallback)actual;
+
+ callback.reset();
+ actualCallback.run(null);
+ return callback.isCalled();
+ }
+
+ public void appendTo(StringBuffer buffer) {
+ buffer.append("wrapsCallback(mockCallback)");
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java
new file mode 100644
index 0000000..5c2f7e7
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java
@@ -0,0 +1,155 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link SingleFieldBuilder}. This tests basic functionality.
+ * More extensive testing is provided via other tests that exercise the
+ * builder.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class SingleFieldBuilderTest extends TestCase {
+
+ public void testBasicUseAndInvalidations() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder =
+ new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(
+ TestAllTypes.getDefaultInstance(),
+ mockParent,
+ false);
+ assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+ assertEquals(TestAllTypes.getDefaultInstance(),
+ builder.getBuilder().buildPartial());
+ assertEquals(0, mockParent.getInvalidationCount());
+
+ builder.getBuilder().setOptionalInt32(10);
+ assertEquals(0, mockParent.getInvalidationCount());
+ TestAllTypes message = builder.build();
+ assertEquals(10, message.getOptionalInt32());
+
+ // Test that we receive invalidations now that build has been called.
+ assertEquals(0, mockParent.getInvalidationCount());
+ builder.getBuilder().setOptionalInt32(20);
+ assertEquals(1, mockParent.getInvalidationCount());
+
+ // Test that we don't keep getting invalidations on every change
+ builder.getBuilder().setOptionalInt32(30);
+ assertEquals(1, mockParent.getInvalidationCount());
+
+ }
+
+ public void testSetMessage() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder =
+ new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(
+ TestAllTypes.getDefaultInstance(),
+ mockParent,
+ false);
+ builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ assertEquals(0, builder.getMessage().getOptionalInt32());
+
+ // Update message using the builder
+ builder.getBuilder().setOptionalInt32(1);
+ assertEquals(0, mockParent.getInvalidationCount());
+ assertEquals(1, builder.getBuilder().getOptionalInt32());
+ assertEquals(1, builder.getMessage().getOptionalInt32());
+ builder.build();
+ builder.getBuilder().setOptionalInt32(2);
+ assertEquals(2, builder.getBuilder().getOptionalInt32());
+ assertEquals(2, builder.getMessage().getOptionalInt32());
+
+ // Make sure message stays cached
+ assertSame(builder.getMessage(), builder.getMessage());
+ }
+
+ public void testClear() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder =
+ new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(
+ TestAllTypes.getDefaultInstance(),
+ mockParent,
+ false);
+ builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+ assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+ builder.clear();
+ assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+
+ builder.getBuilder().setOptionalInt32(1);
+ assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+ builder.clear();
+ assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+ }
+
+ public void testMerge() {
+ TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+ SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder> builder =
+ new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+ TestAllTypesOrBuilder>(
+ TestAllTypes.getDefaultInstance(),
+ mockParent,
+ false);
+
+ // Merge into default field.
+ builder.mergeFrom(TestAllTypes.getDefaultInstance());
+ assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+
+ // Merge into non-default field on existing builder.
+ builder.getBuilder().setOptionalInt32(2);
+ builder.mergeFrom(TestAllTypes.newBuilder()
+ .setOptionalDouble(4.0)
+ .buildPartial());
+ assertEquals(2, builder.getMessage().getOptionalInt32());
+ assertEquals(4.0, builder.getMessage().getOptionalDouble());
+
+ // Merge into non-default field on existing message
+ builder.setMessage(TestAllTypes.newBuilder()
+ .setOptionalInt32(10)
+ .buildPartial());
+ builder.mergeFrom(TestAllTypes.newBuilder()
+ .setOptionalDouble(5.0)
+ .buildPartial());
+ assertEquals(10, builder.getMessage().getOptionalInt32());
+ assertEquals(5.0, builder.getMessage().getOptionalDouble());
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java
new file mode 100644
index 0000000..8f77a03
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java
@@ -0,0 +1,420 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author darick@google.com Darick Tong
+ */
+public class SmallSortedMapTest extends TestCase {
+ // java.util.AbstractMap.SimpleEntry is private in JDK 1.5. We re-implement it
+ // here for JDK 1.5 users.
+ private static class SimpleEntry<K, V> implements Map.Entry<K, V> {
+ private final K key;
+ private V value;
+
+ SimpleEntry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ public V setValue(V value) {
+ V oldValue = this.value;
+ this.value = value;
+ return oldValue;
+ }
+
+ private static boolean eq(Object o1, Object o2) {
+ return o1 == null ? o2 == null : o1.equals(o2);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof Map.Entry))
+ return false;
+ Map.Entry e = (Map.Entry) o;
+ return eq(key, e.getKey()) && eq(value, e.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+ return ((key == null) ? 0 : key.hashCode()) ^
+ ((value == null) ? 0 : value.hashCode());
+ }
+ }
+
+ public void testPutAndGetArrayEntriesOnly() {
+ runPutAndGetTest(3);
+ }
+
+ public void testPutAndGetOverflowEntries() {
+ runPutAndGetTest(6);
+ }
+
+ private void runPutAndGetTest(int numElements) {
+ // Test with even and odd arraySize
+ SmallSortedMap<Integer, Integer> map1 =
+ SmallSortedMap.newInstanceForTest(3);
+ SmallSortedMap<Integer, Integer> map2 =
+ SmallSortedMap.newInstanceForTest(4);
+ SmallSortedMap<Integer, Integer> map3 =
+ SmallSortedMap.newInstanceForTest(3);
+ SmallSortedMap<Integer, Integer> map4 =
+ SmallSortedMap.newInstanceForTest(4);
+
+ // Test with puts in ascending order.
+ for (int i = 0; i < numElements; i++) {
+ assertNull(map1.put(i, i + 1));
+ assertNull(map2.put(i, i + 1));
+ }
+ // Test with puts in descending order.
+ for (int i = numElements - 1; i >= 0; i--) {
+ assertNull(map3.put(i, i + 1));
+ assertNull(map4.put(i, i + 1));
+ }
+
+ assertEquals(Math.min(3, numElements), map1.getNumArrayEntries());
+ assertEquals(Math.min(4, numElements), map2.getNumArrayEntries());
+ assertEquals(Math.min(3, numElements), map3.getNumArrayEntries());
+ assertEquals(Math.min(4, numElements), map4.getNumArrayEntries());
+
+ List<SmallSortedMap<Integer, Integer>> allMaps =
+ new ArrayList<SmallSortedMap<Integer, Integer>>();
+ allMaps.add(map1);
+ allMaps.add(map2);
+ allMaps.add(map3);
+ allMaps.add(map4);
+
+ for (SmallSortedMap<Integer, Integer> map : allMaps) {
+ assertEquals(numElements, map.size());
+ for (int i = 0; i < numElements; i++) {
+ assertEquals(new Integer(i + 1), map.get(i));
+ }
+ }
+
+ assertEquals(map1, map2);
+ assertEquals(map2, map3);
+ assertEquals(map3, map4);
+ }
+
+ public void testReplacingPut() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ assertNull(map.remove(i + 1));
+ }
+ for (int i = 0; i < 6; i++) {
+ assertEquals(new Integer(i + 1), map.put(i, i + 2));
+ }
+ }
+
+ public void testRemove() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ assertNull(map.remove(i + 1));
+ }
+
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(3, map.getNumOverflowEntries());
+ assertEquals(6, map.size());
+ assertEquals(makeSortedKeySet(0, 1, 2, 3, 4, 5), map.keySet());
+
+ assertEquals(new Integer(2), map.remove(1));
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(2, map.getNumOverflowEntries());
+ assertEquals(5, map.size());
+ assertEquals(makeSortedKeySet(0, 2, 3, 4, 5), map.keySet());
+
+ assertEquals(new Integer(5), map.remove(4));
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(1, map.getNumOverflowEntries());
+ assertEquals(4, map.size());
+ assertEquals(makeSortedKeySet(0, 2, 3, 5), map.keySet());
+
+ assertEquals(new Integer(4), map.remove(3));
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(3, map.size());
+ assertEquals(makeSortedKeySet(0, 2, 5), map.keySet());
+
+ assertNull(map.remove(3));
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(3, map.size());
+
+ assertEquals(new Integer(1), map.remove(0));
+ assertEquals(2, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(2, map.size());
+ }
+
+ public void testClear() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ map.clear();
+ assertEquals(0, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(0, map.size());
+ }
+
+ public void testGetArrayEntryAndOverflowEntries() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ assertEquals(3, map.getNumArrayEntries());
+ for (int i = 0; i < 3; i++) {
+ Map.Entry<Integer, Integer> entry = map.getArrayEntryAt(i);
+ assertEquals(new Integer(i), entry.getKey());
+ assertEquals(new Integer(i + 1), entry.getValue());
+ }
+ Iterator<Map.Entry<Integer, Integer>> it =
+ map.getOverflowEntries().iterator();
+ for (int i = 3; i < 6; i++) {
+ assertTrue(it.hasNext());
+ Map.Entry<Integer, Integer> entry = it.next();
+ assertEquals(new Integer(i), entry.getKey());
+ assertEquals(new Integer(i + 1), entry.getValue());
+ }
+ assertFalse(it.hasNext());
+ }
+
+ public void testEntrySetContains() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+ for (int i = 0; i < 6; i++) {
+ assertTrue(
+ entrySet.contains(new SimpleEntry<Integer, Integer>(i, i + 1)));
+ assertFalse(
+ entrySet.contains(new SimpleEntry<Integer, Integer>(i, i)));
+ }
+ }
+
+ public void testEntrySetAdd() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+ for (int i = 0; i < 6; i++) {
+ Map.Entry<Integer, Integer> entry =
+ new SimpleEntry<Integer, Integer>(i, i + 1);
+ assertTrue(entrySet.add(entry));
+ assertFalse(entrySet.add(entry));
+ }
+ for (int i = 0; i < 6; i++) {
+ assertEquals(new Integer(i + 1), map.get(i));
+ }
+ assertEquals(3, map.getNumArrayEntries());
+ assertEquals(3, map.getNumOverflowEntries());
+ assertEquals(6, map.size());
+ }
+
+ public void testEntrySetRemove() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ for (int i = 0; i < 6; i++) {
+ Map.Entry<Integer, Integer> entry =
+ new SimpleEntry<Integer, Integer>(i, i + 1);
+ assertTrue(entrySet.remove(entry));
+ assertFalse(entrySet.remove(entry));
+ }
+ assertTrue(map.isEmpty());
+ assertEquals(0, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(0, map.size());
+ }
+
+ public void testEntrySetClear() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ map.entrySet().clear();
+ assertTrue(map.isEmpty());
+ assertEquals(0, map.getNumArrayEntries());
+ assertEquals(0, map.getNumOverflowEntries());
+ assertEquals(0, map.size());
+ }
+
+ public void testEntrySetIteratorNext() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+ for (int i = 0; i < 6; i++) {
+ assertTrue(it.hasNext());
+ Map.Entry<Integer, Integer> entry = it.next();
+ assertEquals(new Integer(i), entry.getKey());
+ assertEquals(new Integer(i + 1), entry.getValue());
+ }
+ assertFalse(it.hasNext());
+ }
+
+ public void testEntrySetIteratorRemove() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+ for (int i = 0; i < 6; i++) {
+ assertTrue(map.containsKey(i));
+ it.next();
+ it.remove();
+ assertFalse(map.containsKey(i));
+ assertEquals(6 - i - 1, map.size());
+ }
+ }
+
+ public void testMapEntryModification() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+ for (int i = 0; i < 6; i++) {
+ Map.Entry<Integer, Integer> entry = it.next();
+ entry.setValue(i + 23);
+ }
+ for (int i = 0; i < 6; i++) {
+ assertEquals(new Integer(i + 23), map.get(i));
+ }
+ }
+
+ public void testMakeImmutable() {
+ SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+ for (int i = 0; i < 6; i++) {
+ assertNull(map.put(i, i + 1));
+ }
+ map.makeImmutable();
+ assertEquals(new Integer(1), map.get(0));
+ assertEquals(6, map.size());
+
+ try {
+ map.put(23, 23);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ Map<Integer, Integer> other = new HashMap<Integer, Integer>();
+ other.put(23, 23);
+ try {
+ map.putAll(other);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ map.remove(0);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ map.clear();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+ try {
+ entrySet.clear();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ Iterator<Map.Entry<Integer, Integer>> it = entrySet.iterator();
+ while (it.hasNext()) {
+ Map.Entry<Integer, Integer> entry = it.next();
+ try {
+ entry.setValue(0);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ it.remove();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ Set<Integer> keySet = map.keySet();
+ try {
+ keySet.clear();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ Iterator<Integer> keys = keySet.iterator();
+ while (keys.hasNext()) {
+ Integer key = keys.next();
+ try {
+ keySet.remove(key);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ keys.remove();
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+ }
+
+ private Set<Integer> makeSortedKeySet(Integer... keys) {
+ return new TreeSet<Integer>(Arrays.<Integer>asList(keys));
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java
new file mode 100644
index 0000000..6feec4e
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests that proto2 api generation doesn't cause compile errors when
+ * compiling protocol buffers that have names that would otherwise conflict
+ * if not fully qualified (like @Deprecated and @Override).
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class TestBadIdentifiers extends TestCase {
+
+ public void testCompilation() {
+ // If this compiles, it means the generation was correct.
+ TestBadIdentifiersProto.Deprecated.newBuilder();
+ TestBadIdentifiersProto.Override.newBuilder();
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TestUtil.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TestUtil.java
new file mode 100644
index 0000000..9109f41
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TestUtil.java
@@ -0,0 +1,3811 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto;
+import com.google.protobuf.UnittestLite;
+
+// The static imports are to avoid 100+ char lines. The following is roughly equivalent to
+// import static protobuf_unittest.UnittestProto.*;
+import static protobuf_unittest.UnittestProto.defaultInt32Extension;
+import static protobuf_unittest.UnittestProto.defaultInt64Extension;
+import static protobuf_unittest.UnittestProto.defaultUint32Extension;
+import static protobuf_unittest.UnittestProto.defaultUint64Extension;
+import static protobuf_unittest.UnittestProto.defaultSint32Extension;
+import static protobuf_unittest.UnittestProto.defaultSint64Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultSfixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultSfixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultFloatExtension;
+import static protobuf_unittest.UnittestProto.defaultDoubleExtension;
+import static protobuf_unittest.UnittestProto.defaultBoolExtension;
+import static protobuf_unittest.UnittestProto.defaultStringExtension;
+import static protobuf_unittest.UnittestProto.defaultBytesExtension;
+import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultImportEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultStringPieceExtension;
+import static protobuf_unittest.UnittestProto.defaultCordExtension;
+
+import static protobuf_unittest.UnittestProto.optionalInt32Extension;
+import static protobuf_unittest.UnittestProto.optionalInt64Extension;
+import static protobuf_unittest.UnittestProto.optionalUint32Extension;
+import static protobuf_unittest.UnittestProto.optionalUint64Extension;
+import static protobuf_unittest.UnittestProto.optionalSint32Extension;
+import static protobuf_unittest.UnittestProto.optionalSint64Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalFloatExtension;
+import static protobuf_unittest.UnittestProto.optionalDoubleExtension;
+import static protobuf_unittest.UnittestProto.optionalBoolExtension;
+import static protobuf_unittest.UnittestProto.optionalStringExtension;
+import static protobuf_unittest.UnittestProto.optionalBytesExtension;
+import static protobuf_unittest.UnittestProto.optionalGroupExtension;
+import static protobuf_unittest.UnittestProto.optionalNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalImportMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalImportEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalStringPieceExtension;
+import static protobuf_unittest.UnittestProto.optionalCordExtension;
+
+import static protobuf_unittest.UnittestProto.repeatedInt32Extension;
+import static protobuf_unittest.UnittestProto.repeatedInt64Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedFixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedFixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedFloatExtension;
+import static protobuf_unittest.UnittestProto.repeatedDoubleExtension;
+import static protobuf_unittest.UnittestProto.repeatedBoolExtension;
+import static protobuf_unittest.UnittestProto.repeatedStringExtension;
+import static protobuf_unittest.UnittestProto.repeatedBytesExtension;
+import static protobuf_unittest.UnittestProto.repeatedGroupExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedStringPieceExtension;
+import static protobuf_unittest.UnittestProto.repeatedCordExtension;
+
+import static protobuf_unittest.UnittestProto.OptionalGroup_extension;
+import static protobuf_unittest.UnittestProto.RepeatedGroup_extension;
+
+import static protobuf_unittest.UnittestProto.packedInt32Extension;
+import static protobuf_unittest.UnittestProto.packedInt64Extension;
+import static protobuf_unittest.UnittestProto.packedUint32Extension;
+import static protobuf_unittest.UnittestProto.packedUint64Extension;
+import static protobuf_unittest.UnittestProto.packedSint32Extension;
+import static protobuf_unittest.UnittestProto.packedSint64Extension;
+import static protobuf_unittest.UnittestProto.packedFixed32Extension;
+import static protobuf_unittest.UnittestProto.packedFixed64Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.packedFloatExtension;
+import static protobuf_unittest.UnittestProto.packedDoubleExtension;
+import static protobuf_unittest.UnittestProto.packedBoolExtension;
+import static protobuf_unittest.UnittestProto.packedEnumExtension;
+
+import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
+
+import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalCordExtensionLite;
+
+import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite;
+
+import static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite;
+import static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite;
+
+import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
+
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+import com.google.protobuf.UnittestLite.ForeignMessageLite;
+import com.google.protobuf.UnittestLite.ForeignEnumLite;
+import com.google.protobuf.UnittestImportLite.ImportMessageLite;
+import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+
+import junit.framework.Assert;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * Contains methods for setting all fields of {@code TestAllTypes} to
+ * some vaules as well as checking that all the fields are set to those values.
+ * These are useful for testing various protocol message features, e.g.
+ * set all fields of a message, serialize it, parse it, and check that all
+ * fields are set.
+ *
+ * <p>This code is not to be used outside of {@code com.google.protobuf} and
+ * subpackages.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class TestUtil {
+ private TestUtil() {}
+
+ /** Helper to convert a String to ByteString. */
+ static ByteString toBytes(String str) {
+ try {
+ return ByteString.copyFrom(str.getBytes("UTF-8"));
+ } catch(java.io.UnsupportedEncodingException e) {
+ throw new RuntimeException("UTF-8 not supported.", e);
+ }
+ }
+
+ /**
+ * Get a {@code TestAllTypes} with all fields set as they would be by
+ * {@link #setAllFields(TestAllTypes.Builder)}.
+ */
+ public static TestAllTypes getAllSet() {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ setAllFields(builder);
+ return builder.build();
+ }
+
+ /**
+ * Get a {@code TestAllExtensions} with all fields set as they would be by
+ * {@link #setAllExtensions(TestAllExtensions.Builder)}.
+ */
+ public static TestAllExtensions getAllExtensionsSet() {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ setAllExtensions(builder);
+ return builder.build();
+ }
+
+ public static TestAllExtensionsLite getAllLiteExtensionsSet() {
+ TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
+ setAllExtensions(builder);
+ return builder.build();
+ }
+
+ public static TestPackedTypes getPackedSet() {
+ TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+ setPackedFields(builder);
+ return builder.build();
+ }
+
+ public static TestUnpackedTypes getUnpackedSet() {
+ TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder();
+ setUnpackedFields(builder);
+ return builder.build();
+ }
+
+ public static TestPackedExtensions getPackedExtensionsSet() {
+ TestPackedExtensions.Builder builder = TestPackedExtensions.newBuilder();
+ setPackedExtensions(builder);
+ return builder.build();
+ }
+
+ public static TestPackedExtensionsLite getLitePackedExtensionsSet() {
+ TestPackedExtensionsLite.Builder builder =
+ TestPackedExtensionsLite.newBuilder();
+ setPackedExtensions(builder);
+ return builder.build();
+ }
+
+ /**
+ * Set every field of {@code message} to the values expected by
+ * {@code assertAllFieldsSet()}.
+ */
+ public static void setAllFields(TestAllTypes.Builder message) {
+ message.setOptionalInt32 (101);
+ message.setOptionalInt64 (102);
+ message.setOptionalUint32 (103);
+ message.setOptionalUint64 (104);
+ message.setOptionalSint32 (105);
+ message.setOptionalSint64 (106);
+ message.setOptionalFixed32 (107);
+ message.setOptionalFixed64 (108);
+ message.setOptionalSfixed32(109);
+ message.setOptionalSfixed64(110);
+ message.setOptionalFloat (111);
+ message.setOptionalDouble (112);
+ message.setOptionalBool (true);
+ message.setOptionalString ("115");
+ message.setOptionalBytes (toBytes("116"));
+
+ message.setOptionalGroup(
+ TestAllTypes.OptionalGroup.newBuilder().setA(117).build());
+ message.setOptionalNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
+ message.setOptionalForeignMessage(
+ ForeignMessage.newBuilder().setC(119).build());
+ message.setOptionalImportMessage(
+ ImportMessage.newBuilder().setD(120).build());
+
+ message.setOptionalNestedEnum (TestAllTypes.NestedEnum.BAZ);
+ message.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ);
+ message.setOptionalImportEnum (ImportEnum.IMPORT_BAZ);
+
+ message.setOptionalStringPiece("124");
+ message.setOptionalCord("125");
+
+ // -----------------------------------------------------------------
+
+ message.addRepeatedInt32 (201);
+ message.addRepeatedInt64 (202);
+ message.addRepeatedUint32 (203);
+ message.addRepeatedUint64 (204);
+ message.addRepeatedSint32 (205);
+ message.addRepeatedSint64 (206);
+ message.addRepeatedFixed32 (207);
+ message.addRepeatedFixed64 (208);
+ message.addRepeatedSfixed32(209);
+ message.addRepeatedSfixed64(210);
+ message.addRepeatedFloat (211);
+ message.addRepeatedDouble (212);
+ message.addRepeatedBool (true);
+ message.addRepeatedString ("215");
+ message.addRepeatedBytes (toBytes("216"));
+
+ message.addRepeatedGroup(
+ TestAllTypes.RepeatedGroup.newBuilder().setA(217).build());
+ message.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ message.addRepeatedForeignMessage(
+ ForeignMessage.newBuilder().setC(219).build());
+ message.addRepeatedImportMessage(
+ ImportMessage.newBuilder().setD(220).build());
+
+ message.addRepeatedNestedEnum (TestAllTypes.NestedEnum.BAR);
+ message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR);
+ message.addRepeatedImportEnum (ImportEnum.IMPORT_BAR);
+
+ message.addRepeatedStringPiece("224");
+ message.addRepeatedCord("225");
+
+ // Add a second one of each field.
+ message.addRepeatedInt32 (301);
+ message.addRepeatedInt64 (302);
+ message.addRepeatedUint32 (303);
+ message.addRepeatedUint64 (304);
+ message.addRepeatedSint32 (305);
+ message.addRepeatedSint64 (306);
+ message.addRepeatedFixed32 (307);
+ message.addRepeatedFixed64 (308);
+ message.addRepeatedSfixed32(309);
+ message.addRepeatedSfixed64(310);
+ message.addRepeatedFloat (311);
+ message.addRepeatedDouble (312);
+ message.addRepeatedBool (false);
+ message.addRepeatedString ("315");
+ message.addRepeatedBytes (toBytes("316"));
+
+ message.addRepeatedGroup(
+ TestAllTypes.RepeatedGroup.newBuilder().setA(317).build());
+ message.addRepeatedNestedMessage(
+ TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
+ message.addRepeatedForeignMessage(
+ ForeignMessage.newBuilder().setC(319).build());
+ message.addRepeatedImportMessage(
+ ImportMessage.newBuilder().setD(320).build());
+
+ message.addRepeatedNestedEnum (TestAllTypes.NestedEnum.BAZ);
+ message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAZ);
+ message.addRepeatedImportEnum (ImportEnum.IMPORT_BAZ);
+
+ message.addRepeatedStringPiece("324");
+ message.addRepeatedCord("325");
+
+ // -----------------------------------------------------------------
+
+ message.setDefaultInt32 (401);
+ message.setDefaultInt64 (402);
+ message.setDefaultUint32 (403);
+ message.setDefaultUint64 (404);
+ message.setDefaultSint32 (405);
+ message.setDefaultSint64 (406);
+ message.setDefaultFixed32 (407);
+ message.setDefaultFixed64 (408);
+ message.setDefaultSfixed32(409);
+ message.setDefaultSfixed64(410);
+ message.setDefaultFloat (411);
+ message.setDefaultDouble (412);
+ message.setDefaultBool (false);
+ message.setDefaultString ("415");
+ message.setDefaultBytes (toBytes("416"));
+
+ message.setDefaultNestedEnum (TestAllTypes.NestedEnum.FOO);
+ message.setDefaultForeignEnum(ForeignEnum.FOREIGN_FOO);
+ message.setDefaultImportEnum (ImportEnum.IMPORT_FOO);
+
+ message.setDefaultStringPiece("424");
+ message.setDefaultCord("425");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Modify the repeated fields of {@code message} to contain the values
+ * expected by {@code assertRepeatedFieldsModified()}.
+ */
+ public static void modifyRepeatedFields(TestAllTypes.Builder message) {
+ message.setRepeatedInt32 (1, 501);
+ message.setRepeatedInt64 (1, 502);
+ message.setRepeatedUint32 (1, 503);
+ message.setRepeatedUint64 (1, 504);
+ message.setRepeatedSint32 (1, 505);
+ message.setRepeatedSint64 (1, 506);
+ message.setRepeatedFixed32 (1, 507);
+ message.setRepeatedFixed64 (1, 508);
+ message.setRepeatedSfixed32(1, 509);
+ message.setRepeatedSfixed64(1, 510);
+ message.setRepeatedFloat (1, 511);
+ message.setRepeatedDouble (1, 512);
+ message.setRepeatedBool (1, true);
+ message.setRepeatedString (1, "515");
+ message.setRepeatedBytes (1, toBytes("516"));
+
+ message.setRepeatedGroup(1,
+ TestAllTypes.RepeatedGroup.newBuilder().setA(517).build());
+ message.setRepeatedNestedMessage(1,
+ TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
+ message.setRepeatedForeignMessage(1,
+ ForeignMessage.newBuilder().setC(519).build());
+ message.setRepeatedImportMessage(1,
+ ImportMessage.newBuilder().setD(520).build());
+
+ message.setRepeatedNestedEnum (1, TestAllTypes.NestedEnum.FOO);
+ message.setRepeatedForeignEnum(1, ForeignEnum.FOREIGN_FOO);
+ message.setRepeatedImportEnum (1, ImportEnum.IMPORT_FOO);
+
+ message.setRepeatedStringPiece(1, "524");
+ message.setRepeatedCord(1, "525");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setAllFields}.
+ */
+ public static void assertAllFieldsSet(TestAllTypesOrBuilder message) {
+ Assert.assertTrue(message.hasOptionalInt32 ());
+ Assert.assertTrue(message.hasOptionalInt64 ());
+ Assert.assertTrue(message.hasOptionalUint32 ());
+ Assert.assertTrue(message.hasOptionalUint64 ());
+ Assert.assertTrue(message.hasOptionalSint32 ());
+ Assert.assertTrue(message.hasOptionalSint64 ());
+ Assert.assertTrue(message.hasOptionalFixed32 ());
+ Assert.assertTrue(message.hasOptionalFixed64 ());
+ Assert.assertTrue(message.hasOptionalSfixed32());
+ Assert.assertTrue(message.hasOptionalSfixed64());
+ Assert.assertTrue(message.hasOptionalFloat ());
+ Assert.assertTrue(message.hasOptionalDouble ());
+ Assert.assertTrue(message.hasOptionalBool ());
+ Assert.assertTrue(message.hasOptionalString ());
+ Assert.assertTrue(message.hasOptionalBytes ());
+
+ Assert.assertTrue(message.hasOptionalGroup ());
+ Assert.assertTrue(message.hasOptionalNestedMessage ());
+ Assert.assertTrue(message.hasOptionalForeignMessage());
+ Assert.assertTrue(message.hasOptionalImportMessage ());
+
+ Assert.assertTrue(message.getOptionalGroup ().hasA());
+ Assert.assertTrue(message.getOptionalNestedMessage ().hasBb());
+ Assert.assertTrue(message.getOptionalForeignMessage().hasC());
+ Assert.assertTrue(message.getOptionalImportMessage ().hasD());
+
+ Assert.assertTrue(message.hasOptionalNestedEnum ());
+ Assert.assertTrue(message.hasOptionalForeignEnum());
+ Assert.assertTrue(message.hasOptionalImportEnum ());
+
+ Assert.assertTrue(message.hasOptionalStringPiece());
+ Assert.assertTrue(message.hasOptionalCord());
+
+ Assert.assertEquals(101 , message.getOptionalInt32 ());
+ Assert.assertEquals(102 , message.getOptionalInt64 ());
+ Assert.assertEquals(103 , message.getOptionalUint32 ());
+ Assert.assertEquals(104 , message.getOptionalUint64 ());
+ Assert.assertEquals(105 , message.getOptionalSint32 ());
+ Assert.assertEquals(106 , message.getOptionalSint64 ());
+ Assert.assertEquals(107 , message.getOptionalFixed32 ());
+ Assert.assertEquals(108 , message.getOptionalFixed64 ());
+ Assert.assertEquals(109 , message.getOptionalSfixed32());
+ Assert.assertEquals(110 , message.getOptionalSfixed64());
+ Assert.assertEquals(111 , message.getOptionalFloat (), 0.0);
+ Assert.assertEquals(112 , message.getOptionalDouble (), 0.0);
+ Assert.assertEquals(true , message.getOptionalBool ());
+ Assert.assertEquals("115", message.getOptionalString ());
+ Assert.assertEquals(toBytes("116"), message.getOptionalBytes());
+
+ Assert.assertEquals(117, message.getOptionalGroup ().getA());
+ Assert.assertEquals(118, message.getOptionalNestedMessage ().getBb());
+ Assert.assertEquals(119, message.getOptionalForeignMessage().getC());
+ Assert.assertEquals(120, message.getOptionalImportMessage ().getD());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getOptionalNestedEnum());
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getOptionalForeignEnum());
+ Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getOptionalImportEnum());
+
+ Assert.assertEquals("124", message.getOptionalStringPiece());
+ Assert.assertEquals("125", message.getOptionalCord());
+
+ // -----------------------------------------------------------------
+
+ Assert.assertEquals(2, message.getRepeatedInt32Count ());
+ Assert.assertEquals(2, message.getRepeatedInt64Count ());
+ Assert.assertEquals(2, message.getRepeatedUint32Count ());
+ Assert.assertEquals(2, message.getRepeatedUint64Count ());
+ Assert.assertEquals(2, message.getRepeatedSint32Count ());
+ Assert.assertEquals(2, message.getRepeatedSint64Count ());
+ Assert.assertEquals(2, message.getRepeatedFixed32Count ());
+ Assert.assertEquals(2, message.getRepeatedFixed64Count ());
+ Assert.assertEquals(2, message.getRepeatedSfixed32Count());
+ Assert.assertEquals(2, message.getRepeatedSfixed64Count());
+ Assert.assertEquals(2, message.getRepeatedFloatCount ());
+ Assert.assertEquals(2, message.getRepeatedDoubleCount ());
+ Assert.assertEquals(2, message.getRepeatedBoolCount ());
+ Assert.assertEquals(2, message.getRepeatedStringCount ());
+ Assert.assertEquals(2, message.getRepeatedBytesCount ());
+
+ Assert.assertEquals(2, message.getRepeatedGroupCount ());
+ Assert.assertEquals(2, message.getRepeatedNestedMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedForeignMessageCount());
+ Assert.assertEquals(2, message.getRepeatedImportMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedNestedEnumCount ());
+ Assert.assertEquals(2, message.getRepeatedForeignEnumCount ());
+ Assert.assertEquals(2, message.getRepeatedImportEnumCount ());
+
+ Assert.assertEquals(2, message.getRepeatedStringPieceCount());
+ Assert.assertEquals(2, message.getRepeatedCordCount());
+
+ Assert.assertEquals(201 , message.getRepeatedInt32 (0));
+ Assert.assertEquals(202 , message.getRepeatedInt64 (0));
+ Assert.assertEquals(203 , message.getRepeatedUint32 (0));
+ Assert.assertEquals(204 , message.getRepeatedUint64 (0));
+ Assert.assertEquals(205 , message.getRepeatedSint32 (0));
+ Assert.assertEquals(206 , message.getRepeatedSint64 (0));
+ Assert.assertEquals(207 , message.getRepeatedFixed32 (0));
+ Assert.assertEquals(208 , message.getRepeatedFixed64 (0));
+ Assert.assertEquals(209 , message.getRepeatedSfixed32(0));
+ Assert.assertEquals(210 , message.getRepeatedSfixed64(0));
+ Assert.assertEquals(211 , message.getRepeatedFloat (0), 0.0);
+ Assert.assertEquals(212 , message.getRepeatedDouble (0), 0.0);
+ Assert.assertEquals(true , message.getRepeatedBool (0));
+ Assert.assertEquals("215", message.getRepeatedString (0));
+ Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0));
+
+ Assert.assertEquals(217, message.getRepeatedGroup (0).getA());
+ Assert.assertEquals(218, message.getRepeatedNestedMessage (0).getBb());
+ Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC());
+ Assert.assertEquals(220, message.getRepeatedImportMessage (0).getD());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0));
+ Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0));
+
+ Assert.assertEquals("224", message.getRepeatedStringPiece(0));
+ Assert.assertEquals("225", message.getRepeatedCord(0));
+
+ Assert.assertEquals(301 , message.getRepeatedInt32 (1));
+ Assert.assertEquals(302 , message.getRepeatedInt64 (1));
+ Assert.assertEquals(303 , message.getRepeatedUint32 (1));
+ Assert.assertEquals(304 , message.getRepeatedUint64 (1));
+ Assert.assertEquals(305 , message.getRepeatedSint32 (1));
+ Assert.assertEquals(306 , message.getRepeatedSint64 (1));
+ Assert.assertEquals(307 , message.getRepeatedFixed32 (1));
+ Assert.assertEquals(308 , message.getRepeatedFixed64 (1));
+ Assert.assertEquals(309 , message.getRepeatedSfixed32(1));
+ Assert.assertEquals(310 , message.getRepeatedSfixed64(1));
+ Assert.assertEquals(311 , message.getRepeatedFloat (1), 0.0);
+ Assert.assertEquals(312 , message.getRepeatedDouble (1), 0.0);
+ Assert.assertEquals(false, message.getRepeatedBool (1));
+ Assert.assertEquals("315", message.getRepeatedString (1));
+ Assert.assertEquals(toBytes("316"), message.getRepeatedBytes(1));
+
+ Assert.assertEquals(317, message.getRepeatedGroup (1).getA());
+ Assert.assertEquals(318, message.getRepeatedNestedMessage (1).getBb());
+ Assert.assertEquals(319, message.getRepeatedForeignMessage(1).getC());
+ Assert.assertEquals(320, message.getRepeatedImportMessage (1).getD());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getRepeatedNestedEnum (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getRepeatedForeignEnum(1));
+ Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getRepeatedImportEnum(1));
+
+ Assert.assertEquals("324", message.getRepeatedStringPiece(1));
+ Assert.assertEquals("325", message.getRepeatedCord(1));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertTrue(message.hasDefaultInt32 ());
+ Assert.assertTrue(message.hasDefaultInt64 ());
+ Assert.assertTrue(message.hasDefaultUint32 ());
+ Assert.assertTrue(message.hasDefaultUint64 ());
+ Assert.assertTrue(message.hasDefaultSint32 ());
+ Assert.assertTrue(message.hasDefaultSint64 ());
+ Assert.assertTrue(message.hasDefaultFixed32 ());
+ Assert.assertTrue(message.hasDefaultFixed64 ());
+ Assert.assertTrue(message.hasDefaultSfixed32());
+ Assert.assertTrue(message.hasDefaultSfixed64());
+ Assert.assertTrue(message.hasDefaultFloat ());
+ Assert.assertTrue(message.hasDefaultDouble ());
+ Assert.assertTrue(message.hasDefaultBool ());
+ Assert.assertTrue(message.hasDefaultString ());
+ Assert.assertTrue(message.hasDefaultBytes ());
+
+ Assert.assertTrue(message.hasDefaultNestedEnum ());
+ Assert.assertTrue(message.hasDefaultForeignEnum());
+ Assert.assertTrue(message.hasDefaultImportEnum ());
+
+ Assert.assertTrue(message.hasDefaultStringPiece());
+ Assert.assertTrue(message.hasDefaultCord());
+
+ Assert.assertEquals(401 , message.getDefaultInt32 ());
+ Assert.assertEquals(402 , message.getDefaultInt64 ());
+ Assert.assertEquals(403 , message.getDefaultUint32 ());
+ Assert.assertEquals(404 , message.getDefaultUint64 ());
+ Assert.assertEquals(405 , message.getDefaultSint32 ());
+ Assert.assertEquals(406 , message.getDefaultSint64 ());
+ Assert.assertEquals(407 , message.getDefaultFixed32 ());
+ Assert.assertEquals(408 , message.getDefaultFixed64 ());
+ Assert.assertEquals(409 , message.getDefaultSfixed32());
+ Assert.assertEquals(410 , message.getDefaultSfixed64());
+ Assert.assertEquals(411 , message.getDefaultFloat (), 0.0);
+ Assert.assertEquals(412 , message.getDefaultDouble (), 0.0);
+ Assert.assertEquals(false, message.getDefaultBool ());
+ Assert.assertEquals("415", message.getDefaultString ());
+ Assert.assertEquals(toBytes("416"), message.getDefaultBytes());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getDefaultNestedEnum ());
+ Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getDefaultForeignEnum());
+ Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getDefaultImportEnum());
+
+ Assert.assertEquals("424", message.getDefaultStringPiece());
+ Assert.assertEquals("425", message.getDefaultCord());
+ }
+
+ // -------------------------------------------------------------------
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are cleared, and that getting the fields returns their
+ * default values.
+ */
+ public static void assertClear(TestAllTypesOrBuilder message) {
+ // hasBlah() should initially be false for all optional fields.
+ Assert.assertFalse(message.hasOptionalInt32 ());
+ Assert.assertFalse(message.hasOptionalInt64 ());
+ Assert.assertFalse(message.hasOptionalUint32 ());
+ Assert.assertFalse(message.hasOptionalUint64 ());
+ Assert.assertFalse(message.hasOptionalSint32 ());
+ Assert.assertFalse(message.hasOptionalSint64 ());
+ Assert.assertFalse(message.hasOptionalFixed32 ());
+ Assert.assertFalse(message.hasOptionalFixed64 ());
+ Assert.assertFalse(message.hasOptionalSfixed32());
+ Assert.assertFalse(message.hasOptionalSfixed64());
+ Assert.assertFalse(message.hasOptionalFloat ());
+ Assert.assertFalse(message.hasOptionalDouble ());
+ Assert.assertFalse(message.hasOptionalBool ());
+ Assert.assertFalse(message.hasOptionalString ());
+ Assert.assertFalse(message.hasOptionalBytes ());
+
+ Assert.assertFalse(message.hasOptionalGroup ());
+ Assert.assertFalse(message.hasOptionalNestedMessage ());
+ Assert.assertFalse(message.hasOptionalForeignMessage());
+ Assert.assertFalse(message.hasOptionalImportMessage ());
+
+ Assert.assertFalse(message.hasOptionalNestedEnum ());
+ Assert.assertFalse(message.hasOptionalForeignEnum());
+ Assert.assertFalse(message.hasOptionalImportEnum ());
+
+ Assert.assertFalse(message.hasOptionalStringPiece());
+ Assert.assertFalse(message.hasOptionalCord());
+
+ // Optional fields without defaults are set to zero or something like it.
+ Assert.assertEquals(0 , message.getOptionalInt32 ());
+ Assert.assertEquals(0 , message.getOptionalInt64 ());
+ Assert.assertEquals(0 , message.getOptionalUint32 ());
+ Assert.assertEquals(0 , message.getOptionalUint64 ());
+ Assert.assertEquals(0 , message.getOptionalSint32 ());
+ Assert.assertEquals(0 , message.getOptionalSint64 ());
+ Assert.assertEquals(0 , message.getOptionalFixed32 ());
+ Assert.assertEquals(0 , message.getOptionalFixed64 ());
+ Assert.assertEquals(0 , message.getOptionalSfixed32());
+ Assert.assertEquals(0 , message.getOptionalSfixed64());
+ Assert.assertEquals(0 , message.getOptionalFloat (), 0.0);
+ Assert.assertEquals(0 , message.getOptionalDouble (), 0.0);
+ Assert.assertEquals(false, message.getOptionalBool ());
+ Assert.assertEquals("" , message.getOptionalString ());
+ Assert.assertEquals(ByteString.EMPTY, message.getOptionalBytes());
+
+ // Embedded messages should also be clear.
+ Assert.assertFalse(message.getOptionalGroup ().hasA());
+ Assert.assertFalse(message.getOptionalNestedMessage ().hasBb());
+ Assert.assertFalse(message.getOptionalForeignMessage().hasC());
+ Assert.assertFalse(message.getOptionalImportMessage ().hasD());
+
+ Assert.assertEquals(0, message.getOptionalGroup ().getA());
+ Assert.assertEquals(0, message.getOptionalNestedMessage ().getBb());
+ Assert.assertEquals(0, message.getOptionalForeignMessage().getC());
+ Assert.assertEquals(0, message.getOptionalImportMessage ().getD());
+
+ // Enums without defaults are set to the first value in the enum.
+ Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getOptionalNestedEnum ());
+ Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getOptionalForeignEnum());
+ Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getOptionalImportEnum());
+
+ Assert.assertEquals("", message.getOptionalStringPiece());
+ Assert.assertEquals("", message.getOptionalCord());
+
+ // Repeated fields are empty.
+ Assert.assertEquals(0, message.getRepeatedInt32Count ());
+ Assert.assertEquals(0, message.getRepeatedInt64Count ());
+ Assert.assertEquals(0, message.getRepeatedUint32Count ());
+ Assert.assertEquals(0, message.getRepeatedUint64Count ());
+ Assert.assertEquals(0, message.getRepeatedSint32Count ());
+ Assert.assertEquals(0, message.getRepeatedSint64Count ());
+ Assert.assertEquals(0, message.getRepeatedFixed32Count ());
+ Assert.assertEquals(0, message.getRepeatedFixed64Count ());
+ Assert.assertEquals(0, message.getRepeatedSfixed32Count());
+ Assert.assertEquals(0, message.getRepeatedSfixed64Count());
+ Assert.assertEquals(0, message.getRepeatedFloatCount ());
+ Assert.assertEquals(0, message.getRepeatedDoubleCount ());
+ Assert.assertEquals(0, message.getRepeatedBoolCount ());
+ Assert.assertEquals(0, message.getRepeatedStringCount ());
+ Assert.assertEquals(0, message.getRepeatedBytesCount ());
+
+ Assert.assertEquals(0, message.getRepeatedGroupCount ());
+ Assert.assertEquals(0, message.getRepeatedNestedMessageCount ());
+ Assert.assertEquals(0, message.getRepeatedForeignMessageCount());
+ Assert.assertEquals(0, message.getRepeatedImportMessageCount ());
+ Assert.assertEquals(0, message.getRepeatedNestedEnumCount ());
+ Assert.assertEquals(0, message.getRepeatedForeignEnumCount ());
+ Assert.assertEquals(0, message.getRepeatedImportEnumCount ());
+
+ Assert.assertEquals(0, message.getRepeatedStringPieceCount());
+ Assert.assertEquals(0, message.getRepeatedCordCount());
+
+ // hasBlah() should also be false for all default fields.
+ Assert.assertFalse(message.hasDefaultInt32 ());
+ Assert.assertFalse(message.hasDefaultInt64 ());
+ Assert.assertFalse(message.hasDefaultUint32 ());
+ Assert.assertFalse(message.hasDefaultUint64 ());
+ Assert.assertFalse(message.hasDefaultSint32 ());
+ Assert.assertFalse(message.hasDefaultSint64 ());
+ Assert.assertFalse(message.hasDefaultFixed32 ());
+ Assert.assertFalse(message.hasDefaultFixed64 ());
+ Assert.assertFalse(message.hasDefaultSfixed32());
+ Assert.assertFalse(message.hasDefaultSfixed64());
+ Assert.assertFalse(message.hasDefaultFloat ());
+ Assert.assertFalse(message.hasDefaultDouble ());
+ Assert.assertFalse(message.hasDefaultBool ());
+ Assert.assertFalse(message.hasDefaultString ());
+ Assert.assertFalse(message.hasDefaultBytes ());
+
+ Assert.assertFalse(message.hasDefaultNestedEnum ());
+ Assert.assertFalse(message.hasDefaultForeignEnum());
+ Assert.assertFalse(message.hasDefaultImportEnum ());
+
+ Assert.assertFalse(message.hasDefaultStringPiece());
+ Assert.assertFalse(message.hasDefaultCord());
+
+ // Fields with defaults have their default values (duh).
+ Assert.assertEquals( 41 , message.getDefaultInt32 ());
+ Assert.assertEquals( 42 , message.getDefaultInt64 ());
+ Assert.assertEquals( 43 , message.getDefaultUint32 ());
+ Assert.assertEquals( 44 , message.getDefaultUint64 ());
+ Assert.assertEquals(-45 , message.getDefaultSint32 ());
+ Assert.assertEquals( 46 , message.getDefaultSint64 ());
+ Assert.assertEquals( 47 , message.getDefaultFixed32 ());
+ Assert.assertEquals( 48 , message.getDefaultFixed64 ());
+ Assert.assertEquals( 49 , message.getDefaultSfixed32());
+ Assert.assertEquals(-50 , message.getDefaultSfixed64());
+ Assert.assertEquals( 51.5 , message.getDefaultFloat (), 0.0);
+ Assert.assertEquals( 52e3 , message.getDefaultDouble (), 0.0);
+ Assert.assertEquals(true , message.getDefaultBool ());
+ Assert.assertEquals("hello", message.getDefaultString ());
+ Assert.assertEquals(toBytes("world"), message.getDefaultBytes());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getDefaultNestedEnum ());
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getDefaultForeignEnum());
+ Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getDefaultImportEnum());
+
+ Assert.assertEquals("abc", message.getDefaultStringPiece());
+ Assert.assertEquals("123", message.getDefaultCord());
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setAllFields}
+ * followed by {@code modifyRepeatedFields}.
+ */
+ public static void assertRepeatedFieldsModified(
+ TestAllTypesOrBuilder message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ Assert.assertEquals(2, message.getRepeatedInt32Count ());
+ Assert.assertEquals(2, message.getRepeatedInt64Count ());
+ Assert.assertEquals(2, message.getRepeatedUint32Count ());
+ Assert.assertEquals(2, message.getRepeatedUint64Count ());
+ Assert.assertEquals(2, message.getRepeatedSint32Count ());
+ Assert.assertEquals(2, message.getRepeatedSint64Count ());
+ Assert.assertEquals(2, message.getRepeatedFixed32Count ());
+ Assert.assertEquals(2, message.getRepeatedFixed64Count ());
+ Assert.assertEquals(2, message.getRepeatedSfixed32Count());
+ Assert.assertEquals(2, message.getRepeatedSfixed64Count());
+ Assert.assertEquals(2, message.getRepeatedFloatCount ());
+ Assert.assertEquals(2, message.getRepeatedDoubleCount ());
+ Assert.assertEquals(2, message.getRepeatedBoolCount ());
+ Assert.assertEquals(2, message.getRepeatedStringCount ());
+ Assert.assertEquals(2, message.getRepeatedBytesCount ());
+
+ Assert.assertEquals(2, message.getRepeatedGroupCount ());
+ Assert.assertEquals(2, message.getRepeatedNestedMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedForeignMessageCount());
+ Assert.assertEquals(2, message.getRepeatedImportMessageCount ());
+ Assert.assertEquals(2, message.getRepeatedNestedEnumCount ());
+ Assert.assertEquals(2, message.getRepeatedForeignEnumCount ());
+ Assert.assertEquals(2, message.getRepeatedImportEnumCount ());
+
+ Assert.assertEquals(2, message.getRepeatedStringPieceCount());
+ Assert.assertEquals(2, message.getRepeatedCordCount());
+
+ Assert.assertEquals(201 , message.getRepeatedInt32 (0));
+ Assert.assertEquals(202L , message.getRepeatedInt64 (0));
+ Assert.assertEquals(203 , message.getRepeatedUint32 (0));
+ Assert.assertEquals(204L , message.getRepeatedUint64 (0));
+ Assert.assertEquals(205 , message.getRepeatedSint32 (0));
+ Assert.assertEquals(206L , message.getRepeatedSint64 (0));
+ Assert.assertEquals(207 , message.getRepeatedFixed32 (0));
+ Assert.assertEquals(208L , message.getRepeatedFixed64 (0));
+ Assert.assertEquals(209 , message.getRepeatedSfixed32(0));
+ Assert.assertEquals(210L , message.getRepeatedSfixed64(0));
+ Assert.assertEquals(211F , message.getRepeatedFloat (0));
+ Assert.assertEquals(212D , message.getRepeatedDouble (0));
+ Assert.assertEquals(true , message.getRepeatedBool (0));
+ Assert.assertEquals("215", message.getRepeatedString (0));
+ Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0));
+
+ Assert.assertEquals(217, message.getRepeatedGroup (0).getA());
+ Assert.assertEquals(218, message.getRepeatedNestedMessage (0).getBb());
+ Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC());
+ Assert.assertEquals(220, message.getRepeatedImportMessage (0).getD());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0));
+ Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0));
+
+ Assert.assertEquals("224", message.getRepeatedStringPiece(0));
+ Assert.assertEquals("225", message.getRepeatedCord(0));
+
+ // Actually verify the second (modified) elements now.
+ Assert.assertEquals(501 , message.getRepeatedInt32 (1));
+ Assert.assertEquals(502L , message.getRepeatedInt64 (1));
+ Assert.assertEquals(503 , message.getRepeatedUint32 (1));
+ Assert.assertEquals(504L , message.getRepeatedUint64 (1));
+ Assert.assertEquals(505 , message.getRepeatedSint32 (1));
+ Assert.assertEquals(506L , message.getRepeatedSint64 (1));
+ Assert.assertEquals(507 , message.getRepeatedFixed32 (1));
+ Assert.assertEquals(508L , message.getRepeatedFixed64 (1));
+ Assert.assertEquals(509 , message.getRepeatedSfixed32(1));
+ Assert.assertEquals(510L , message.getRepeatedSfixed64(1));
+ Assert.assertEquals(511F , message.getRepeatedFloat (1));
+ Assert.assertEquals(512D , message.getRepeatedDouble (1));
+ Assert.assertEquals(true , message.getRepeatedBool (1));
+ Assert.assertEquals("515", message.getRepeatedString (1));
+ Assert.assertEquals(toBytes("516"), message.getRepeatedBytes(1));
+
+ Assert.assertEquals(517, message.getRepeatedGroup (1).getA());
+ Assert.assertEquals(518, message.getRepeatedNestedMessage (1).getBb());
+ Assert.assertEquals(519, message.getRepeatedForeignMessage(1).getC());
+ Assert.assertEquals(520, message.getRepeatedImportMessage (1).getD());
+
+ Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getRepeatedNestedEnum (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getRepeatedForeignEnum(1));
+ Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getRepeatedImportEnum(1));
+
+ Assert.assertEquals("524", message.getRepeatedStringPiece(1));
+ Assert.assertEquals("525", message.getRepeatedCord(1));
+ }
+
+ /**
+ * Set every field of {@code message} to a unique value.
+ */
+ public static void setPackedFields(TestPackedTypes.Builder message) {
+ message.addPackedInt32 (601);
+ message.addPackedInt64 (602);
+ message.addPackedUint32 (603);
+ message.addPackedUint64 (604);
+ message.addPackedSint32 (605);
+ message.addPackedSint64 (606);
+ message.addPackedFixed32 (607);
+ message.addPackedFixed64 (608);
+ message.addPackedSfixed32(609);
+ message.addPackedSfixed64(610);
+ message.addPackedFloat (611);
+ message.addPackedDouble (612);
+ message.addPackedBool (true);
+ message.addPackedEnum (ForeignEnum.FOREIGN_BAR);
+ // Add a second one of each field.
+ message.addPackedInt32 (701);
+ message.addPackedInt64 (702);
+ message.addPackedUint32 (703);
+ message.addPackedUint64 (704);
+ message.addPackedSint32 (705);
+ message.addPackedSint64 (706);
+ message.addPackedFixed32 (707);
+ message.addPackedFixed64 (708);
+ message.addPackedSfixed32(709);
+ message.addPackedSfixed64(710);
+ message.addPackedFloat (711);
+ message.addPackedDouble (712);
+ message.addPackedBool (false);
+ message.addPackedEnum (ForeignEnum.FOREIGN_BAZ);
+ }
+
+ /**
+ * Set every field of {@code message} to a unique value. Must correspond with
+ * the values applied by {@code setPackedFields}.
+ */
+ public static void setUnpackedFields(TestUnpackedTypes.Builder message) {
+ message.addUnpackedInt32 (601);
+ message.addUnpackedInt64 (602);
+ message.addUnpackedUint32 (603);
+ message.addUnpackedUint64 (604);
+ message.addUnpackedSint32 (605);
+ message.addUnpackedSint64 (606);
+ message.addUnpackedFixed32 (607);
+ message.addUnpackedFixed64 (608);
+ message.addUnpackedSfixed32(609);
+ message.addUnpackedSfixed64(610);
+ message.addUnpackedFloat (611);
+ message.addUnpackedDouble (612);
+ message.addUnpackedBool (true);
+ message.addUnpackedEnum (ForeignEnum.FOREIGN_BAR);
+ // Add a second one of each field.
+ message.addUnpackedInt32 (701);
+ message.addUnpackedInt64 (702);
+ message.addUnpackedUint32 (703);
+ message.addUnpackedUint64 (704);
+ message.addUnpackedSint32 (705);
+ message.addUnpackedSint64 (706);
+ message.addUnpackedFixed32 (707);
+ message.addUnpackedFixed64 (708);
+ message.addUnpackedSfixed32(709);
+ message.addUnpackedSfixed64(710);
+ message.addUnpackedFloat (711);
+ message.addUnpackedDouble (712);
+ message.addUnpackedBool (false);
+ message.addUnpackedEnum (ForeignEnum.FOREIGN_BAZ);
+ }
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setPackedFields}.
+ */
+ public static void assertPackedFieldsSet(TestPackedTypes message) {
+ Assert.assertEquals(2, message.getPackedInt32Count ());
+ Assert.assertEquals(2, message.getPackedInt64Count ());
+ Assert.assertEquals(2, message.getPackedUint32Count ());
+ Assert.assertEquals(2, message.getPackedUint64Count ());
+ Assert.assertEquals(2, message.getPackedSint32Count ());
+ Assert.assertEquals(2, message.getPackedSint64Count ());
+ Assert.assertEquals(2, message.getPackedFixed32Count ());
+ Assert.assertEquals(2, message.getPackedFixed64Count ());
+ Assert.assertEquals(2, message.getPackedSfixed32Count());
+ Assert.assertEquals(2, message.getPackedSfixed64Count());
+ Assert.assertEquals(2, message.getPackedFloatCount ());
+ Assert.assertEquals(2, message.getPackedDoubleCount ());
+ Assert.assertEquals(2, message.getPackedBoolCount ());
+ Assert.assertEquals(2, message.getPackedEnumCount ());
+ Assert.assertEquals(601 , message.getPackedInt32 (0));
+ Assert.assertEquals(602 , message.getPackedInt64 (0));
+ Assert.assertEquals(603 , message.getPackedUint32 (0));
+ Assert.assertEquals(604 , message.getPackedUint64 (0));
+ Assert.assertEquals(605 , message.getPackedSint32 (0));
+ Assert.assertEquals(606 , message.getPackedSint64 (0));
+ Assert.assertEquals(607 , message.getPackedFixed32 (0));
+ Assert.assertEquals(608 , message.getPackedFixed64 (0));
+ Assert.assertEquals(609 , message.getPackedSfixed32(0));
+ Assert.assertEquals(610 , message.getPackedSfixed64(0));
+ Assert.assertEquals(611 , message.getPackedFloat (0), 0.0);
+ Assert.assertEquals(612 , message.getPackedDouble (0), 0.0);
+ Assert.assertEquals(true , message.getPackedBool (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getPackedEnum(0));
+ Assert.assertEquals(701 , message.getPackedInt32 (1));
+ Assert.assertEquals(702 , message.getPackedInt64 (1));
+ Assert.assertEquals(703 , message.getPackedUint32 (1));
+ Assert.assertEquals(704 , message.getPackedUint64 (1));
+ Assert.assertEquals(705 , message.getPackedSint32 (1));
+ Assert.assertEquals(706 , message.getPackedSint64 (1));
+ Assert.assertEquals(707 , message.getPackedFixed32 (1));
+ Assert.assertEquals(708 , message.getPackedFixed64 (1));
+ Assert.assertEquals(709 , message.getPackedSfixed32(1));
+ Assert.assertEquals(710 , message.getPackedSfixed64(1));
+ Assert.assertEquals(711 , message.getPackedFloat (1), 0.0);
+ Assert.assertEquals(712 , message.getPackedDouble (1), 0.0);
+ Assert.assertEquals(false, message.getPackedBool (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getPackedEnum(1));
+ }
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setUnpackedFields}.
+ */
+ public static void assertUnpackedFieldsSet(TestUnpackedTypes message) {
+ Assert.assertEquals(2, message.getUnpackedInt32Count ());
+ Assert.assertEquals(2, message.getUnpackedInt64Count ());
+ Assert.assertEquals(2, message.getUnpackedUint32Count ());
+ Assert.assertEquals(2, message.getUnpackedUint64Count ());
+ Assert.assertEquals(2, message.getUnpackedSint32Count ());
+ Assert.assertEquals(2, message.getUnpackedSint64Count ());
+ Assert.assertEquals(2, message.getUnpackedFixed32Count ());
+ Assert.assertEquals(2, message.getUnpackedFixed64Count ());
+ Assert.assertEquals(2, message.getUnpackedSfixed32Count());
+ Assert.assertEquals(2, message.getUnpackedSfixed64Count());
+ Assert.assertEquals(2, message.getUnpackedFloatCount ());
+ Assert.assertEquals(2, message.getUnpackedDoubleCount ());
+ Assert.assertEquals(2, message.getUnpackedBoolCount ());
+ Assert.assertEquals(2, message.getUnpackedEnumCount ());
+ Assert.assertEquals(601 , message.getUnpackedInt32 (0));
+ Assert.assertEquals(602 , message.getUnpackedInt64 (0));
+ Assert.assertEquals(603 , message.getUnpackedUint32 (0));
+ Assert.assertEquals(604 , message.getUnpackedUint64 (0));
+ Assert.assertEquals(605 , message.getUnpackedSint32 (0));
+ Assert.assertEquals(606 , message.getUnpackedSint64 (0));
+ Assert.assertEquals(607 , message.getUnpackedFixed32 (0));
+ Assert.assertEquals(608 , message.getUnpackedFixed64 (0));
+ Assert.assertEquals(609 , message.getUnpackedSfixed32(0));
+ Assert.assertEquals(610 , message.getUnpackedSfixed64(0));
+ Assert.assertEquals(611 , message.getUnpackedFloat (0), 0.0);
+ Assert.assertEquals(612 , message.getUnpackedDouble (0), 0.0);
+ Assert.assertEquals(true , message.getUnpackedBool (0));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getUnpackedEnum(0));
+ Assert.assertEquals(701 , message.getUnpackedInt32 (1));
+ Assert.assertEquals(702 , message.getUnpackedInt64 (1));
+ Assert.assertEquals(703 , message.getUnpackedUint32 (1));
+ Assert.assertEquals(704 , message.getUnpackedUint64 (1));
+ Assert.assertEquals(705 , message.getUnpackedSint32 (1));
+ Assert.assertEquals(706 , message.getUnpackedSint64 (1));
+ Assert.assertEquals(707 , message.getUnpackedFixed32 (1));
+ Assert.assertEquals(708 , message.getUnpackedFixed64 (1));
+ Assert.assertEquals(709 , message.getUnpackedSfixed32(1));
+ Assert.assertEquals(710 , message.getUnpackedSfixed64(1));
+ Assert.assertEquals(711 , message.getUnpackedFloat (1), 0.0);
+ Assert.assertEquals(712 , message.getUnpackedDouble (1), 0.0);
+ Assert.assertEquals(false, message.getUnpackedBool (1));
+ Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getUnpackedEnum(1));
+ }
+
+ // ===================================================================
+ // Like above, but for extensions
+
+ // Java gets confused with things like assertEquals(int, Integer): it can't
+ // decide whether to call assertEquals(int, int) or assertEquals(Object,
+ // Object). So we define these methods to help it.
+ private static void assertEqualsExactType(int a, int b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(long a, long b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(float a, float b) {
+ Assert.assertEquals(a, b, 0.0);
+ }
+ private static void assertEqualsExactType(double a, double b) {
+ Assert.assertEquals(a, b, 0.0);
+ }
+ private static void assertEqualsExactType(boolean a, boolean b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(String a, String b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(ByteString a, ByteString b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(TestAllTypes.NestedEnum a,
+ TestAllTypes.NestedEnum b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(ForeignEnum a, ForeignEnum b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(ImportEnum a, ImportEnum b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(TestAllTypesLite.NestedEnum a,
+ TestAllTypesLite.NestedEnum b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(ForeignEnumLite a,
+ ForeignEnumLite b) {
+ Assert.assertEquals(a, b);
+ }
+ private static void assertEqualsExactType(ImportEnumLite a,
+ ImportEnumLite b) {
+ Assert.assertEquals(a, b);
+ }
+
+ /**
+ * Get an unmodifiable {@link ExtensionRegistry} containing all the
+ * extensions of {@code TestAllExtensions}.
+ */
+ public static ExtensionRegistry getExtensionRegistry() {
+ ExtensionRegistry registry = ExtensionRegistry.newInstance();
+ registerAllExtensions(registry);
+ return registry.getUnmodifiable();
+ }
+
+ public static ExtensionRegistryLite getExtensionRegistryLite() {
+ ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+ registerAllExtensionsLite(registry);
+ return registry.getUnmodifiable();
+ }
+
+ /**
+ * Register all of {@code TestAllExtensions}'s extensions with the
+ * given {@link ExtensionRegistry}.
+ */
+ public static void registerAllExtensions(ExtensionRegistry registry) {
+ UnittestProto.registerAllExtensions(registry);
+ registerAllExtensionsLite(registry);
+ }
+
+ public static void registerAllExtensionsLite(ExtensionRegistryLite registry) {
+ UnittestLite.registerAllExtensions(registry);
+ }
+
+ /**
+ * Set every field of {@code message} to the values expected by
+ * {@code assertAllExtensionsSet()}.
+ */
+ public static void setAllExtensions(TestAllExtensions.Builder message) {
+ message.setExtension(optionalInt32Extension , 101);
+ message.setExtension(optionalInt64Extension , 102L);
+ message.setExtension(optionalUint32Extension , 103);
+ message.setExtension(optionalUint64Extension , 104L);
+ message.setExtension(optionalSint32Extension , 105);
+ message.setExtension(optionalSint64Extension , 106L);
+ message.setExtension(optionalFixed32Extension , 107);
+ message.setExtension(optionalFixed64Extension , 108L);
+ message.setExtension(optionalSfixed32Extension, 109);
+ message.setExtension(optionalSfixed64Extension, 110L);
+ message.setExtension(optionalFloatExtension , 111F);
+ message.setExtension(optionalDoubleExtension , 112D);
+ message.setExtension(optionalBoolExtension , true);
+ message.setExtension(optionalStringExtension , "115");
+ message.setExtension(optionalBytesExtension , toBytes("116"));
+
+ message.setExtension(optionalGroupExtension,
+ OptionalGroup_extension.newBuilder().setA(117).build());
+ message.setExtension(optionalNestedMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
+ message.setExtension(optionalForeignMessageExtension,
+ ForeignMessage.newBuilder().setC(119).build());
+ message.setExtension(optionalImportMessageExtension,
+ ImportMessage.newBuilder().setD(120).build());
+
+ message.setExtension(optionalNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
+ message.setExtension(optionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ message.setExtension(optionalImportEnumExtension, ImportEnum.IMPORT_BAZ);
+
+ message.setExtension(optionalStringPieceExtension, "124");
+ message.setExtension(optionalCordExtension, "125");
+
+ // -----------------------------------------------------------------
+
+ message.addExtension(repeatedInt32Extension , 201);
+ message.addExtension(repeatedInt64Extension , 202L);
+ message.addExtension(repeatedUint32Extension , 203);
+ message.addExtension(repeatedUint64Extension , 204L);
+ message.addExtension(repeatedSint32Extension , 205);
+ message.addExtension(repeatedSint64Extension , 206L);
+ message.addExtension(repeatedFixed32Extension , 207);
+ message.addExtension(repeatedFixed64Extension , 208L);
+ message.addExtension(repeatedSfixed32Extension, 209);
+ message.addExtension(repeatedSfixed64Extension, 210L);
+ message.addExtension(repeatedFloatExtension , 211F);
+ message.addExtension(repeatedDoubleExtension , 212D);
+ message.addExtension(repeatedBoolExtension , true);
+ message.addExtension(repeatedStringExtension , "215");
+ message.addExtension(repeatedBytesExtension , toBytes("216"));
+
+ message.addExtension(repeatedGroupExtension,
+ RepeatedGroup_extension.newBuilder().setA(217).build());
+ message.addExtension(repeatedNestedMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ message.addExtension(repeatedForeignMessageExtension,
+ ForeignMessage.newBuilder().setC(219).build());
+ message.addExtension(repeatedImportMessageExtension,
+ ImportMessage.newBuilder().setD(220).build());
+
+ message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAR);
+ message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAR);
+ message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAR);
+
+ message.addExtension(repeatedStringPieceExtension, "224");
+ message.addExtension(repeatedCordExtension, "225");
+
+ // Add a second one of each field.
+ message.addExtension(repeatedInt32Extension , 301);
+ message.addExtension(repeatedInt64Extension , 302L);
+ message.addExtension(repeatedUint32Extension , 303);
+ message.addExtension(repeatedUint64Extension , 304L);
+ message.addExtension(repeatedSint32Extension , 305);
+ message.addExtension(repeatedSint64Extension , 306L);
+ message.addExtension(repeatedFixed32Extension , 307);
+ message.addExtension(repeatedFixed64Extension , 308L);
+ message.addExtension(repeatedSfixed32Extension, 309);
+ message.addExtension(repeatedSfixed64Extension, 310L);
+ message.addExtension(repeatedFloatExtension , 311F);
+ message.addExtension(repeatedDoubleExtension , 312D);
+ message.addExtension(repeatedBoolExtension , false);
+ message.addExtension(repeatedStringExtension , "315");
+ message.addExtension(repeatedBytesExtension , toBytes("316"));
+
+ message.addExtension(repeatedGroupExtension,
+ RepeatedGroup_extension.newBuilder().setA(317).build());
+ message.addExtension(repeatedNestedMessageExtension,
+ TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
+ message.addExtension(repeatedForeignMessageExtension,
+ ForeignMessage.newBuilder().setC(319).build());
+ message.addExtension(repeatedImportMessageExtension,
+ ImportMessage.newBuilder().setD(320).build());
+
+ message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
+ message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAZ);
+
+ message.addExtension(repeatedStringPieceExtension, "324");
+ message.addExtension(repeatedCordExtension, "325");
+
+ // -----------------------------------------------------------------
+
+ message.setExtension(defaultInt32Extension , 401);
+ message.setExtension(defaultInt64Extension , 402L);
+ message.setExtension(defaultUint32Extension , 403);
+ message.setExtension(defaultUint64Extension , 404L);
+ message.setExtension(defaultSint32Extension , 405);
+ message.setExtension(defaultSint64Extension , 406L);
+ message.setExtension(defaultFixed32Extension , 407);
+ message.setExtension(defaultFixed64Extension , 408L);
+ message.setExtension(defaultSfixed32Extension, 409);
+ message.setExtension(defaultSfixed64Extension, 410L);
+ message.setExtension(defaultFloatExtension , 411F);
+ message.setExtension(defaultDoubleExtension , 412D);
+ message.setExtension(defaultBoolExtension , false);
+ message.setExtension(defaultStringExtension , "415");
+ message.setExtension(defaultBytesExtension , toBytes("416"));
+
+ message.setExtension(defaultNestedEnumExtension, TestAllTypes.NestedEnum.FOO);
+ message.setExtension(defaultForeignEnumExtension, ForeignEnum.FOREIGN_FOO);
+ message.setExtension(defaultImportEnumExtension, ImportEnum.IMPORT_FOO);
+
+ message.setExtension(defaultStringPieceExtension, "424");
+ message.setExtension(defaultCordExtension, "425");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Modify the repeated extensions of {@code message} to contain the values
+ * expected by {@code assertRepeatedExtensionsModified()}.
+ */
+ public static void modifyRepeatedExtensions(
+ TestAllExtensions.Builder message) {
+ message.setExtension(repeatedInt32Extension , 1, 501);
+ message.setExtension(repeatedInt64Extension , 1, 502L);
+ message.setExtension(repeatedUint32Extension , 1, 503);
+ message.setExtension(repeatedUint64Extension , 1, 504L);
+ message.setExtension(repeatedSint32Extension , 1, 505);
+ message.setExtension(repeatedSint64Extension , 1, 506L);
+ message.setExtension(repeatedFixed32Extension , 1, 507);
+ message.setExtension(repeatedFixed64Extension , 1, 508L);
+ message.setExtension(repeatedSfixed32Extension, 1, 509);
+ message.setExtension(repeatedSfixed64Extension, 1, 510L);
+ message.setExtension(repeatedFloatExtension , 1, 511F);
+ message.setExtension(repeatedDoubleExtension , 1, 512D);
+ message.setExtension(repeatedBoolExtension , 1, true);
+ message.setExtension(repeatedStringExtension , 1, "515");
+ message.setExtension(repeatedBytesExtension , 1, toBytes("516"));
+
+ message.setExtension(repeatedGroupExtension, 1,
+ RepeatedGroup_extension.newBuilder().setA(517).build());
+ message.setExtension(repeatedNestedMessageExtension, 1,
+ TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
+ message.setExtension(repeatedForeignMessageExtension, 1,
+ ForeignMessage.newBuilder().setC(519).build());
+ message.setExtension(repeatedImportMessageExtension, 1,
+ ImportMessage.newBuilder().setD(520).build());
+
+ message.setExtension(repeatedNestedEnumExtension , 1, TestAllTypes.NestedEnum.FOO);
+ message.setExtension(repeatedForeignEnumExtension, 1, ForeignEnum.FOREIGN_FOO);
+ message.setExtension(repeatedImportEnumExtension , 1, ImportEnum.IMPORT_FOO);
+
+ message.setExtension(repeatedStringPieceExtension, 1, "524");
+ message.setExtension(repeatedCordExtension, 1, "525");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are set to the values assigned by {@code setAllExtensions}.
+ */
+ public static void assertAllExtensionsSet(
+ TestAllExtensionsOrBuilder message) {
+ Assert.assertTrue(message.hasExtension(optionalInt32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalInt64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalUint32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalUint64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSint32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSint64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalFixed32Extension ));
+ Assert.assertTrue(message.hasExtension(optionalFixed64Extension ));
+ Assert.assertTrue(message.hasExtension(optionalSfixed32Extension));
+ Assert.assertTrue(message.hasExtension(optionalSfixed64Extension));
+ Assert.assertTrue(message.hasExtension(optionalFloatExtension ));
+ Assert.assertTrue(message.hasExtension(optionalDoubleExtension ));
+ Assert.assertTrue(message.hasExtension(optionalBoolExtension ));
+ Assert.assertTrue(message.hasExtension(optionalStringExtension ));
+ Assert.assertTrue(message.hasExtension(optionalBytesExtension ));
+
+ Assert.assertTrue(message.hasExtension(optionalGroupExtension ));
+ Assert.assertTrue(message.hasExtension(optionalNestedMessageExtension ));
+ Assert.assertTrue(message.hasExtension(optionalForeignMessageExtension));
+ Assert.assertTrue(message.hasExtension(optionalImportMessageExtension ));
+
+ Assert.assertTrue(message.getExtension(optionalGroupExtension ).hasA());
+ Assert.assertTrue(message.getExtension(optionalNestedMessageExtension ).hasBb());
+ Assert.assertTrue(message.getExtension(optionalForeignMessageExtension).hasC());
+ Assert.assertTrue(message.getExtension(optionalImportMessageExtension ).hasD());
+
+ Assert.assertTrue(message.hasExtension(optionalNestedEnumExtension ));
+ Assert.assertTrue(message.hasExtension(optionalForeignEnumExtension));
+ Assert.assertTrue(message.hasExtension(optionalImportEnumExtension ));
+
+ Assert.assertTrue(message.hasExtension(optionalStringPieceExtension));
+ Assert.assertTrue(message.hasExtension(optionalCordExtension));
+
+ assertEqualsExactType(101 , message.getExtension(optionalInt32Extension ));
+ assertEqualsExactType(102L , message.getExtension(optionalInt64Extension ));
+ assertEqualsExactType(103 , message.getExtension(optionalUint32Extension ));
+ assertEqualsExactType(104L , message.getExtension(optionalUint64Extension ));
+ assertEqualsExactType(105 , message.getExtension(optionalSint32Extension ));
+ assertEqualsExactType(106L , message.getExtension(optionalSint64Extension ));
+ assertEqualsExactType(107 , message.getExtension(optionalFixed32Extension ));
+ assertEqualsExactType(108L , message.getExtension(optionalFixed64Extension ));
+ assertEqualsExactType(109 , message.getExtension(optionalSfixed32Extension));
+ assertEqualsExactType(110L , message.getExtension(optionalSfixed64Extension));
+ assertEqualsExactType(111F , message.getExtension(optionalFloatExtension ));
+ assertEqualsExactType(112D , message.getExtension(optionalDoubleExtension ));
+ assertEqualsExactType(true , message.getExtension(optionalBoolExtension ));
+ assertEqualsExactType("115", message.getExtension(optionalStringExtension ));
+ assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtension));
+
+ assertEqualsExactType(117, message.getExtension(optionalGroupExtension ).getA());
+ assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtension ).getBb());
+ assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtension).getC());
+ assertEqualsExactType(120, message.getExtension(optionalImportMessageExtension ).getD());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAZ,
+ message.getExtension(optionalNestedEnumExtension));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+ message.getExtension(optionalForeignEnumExtension));
+ assertEqualsExactType(ImportEnum.IMPORT_BAZ,
+ message.getExtension(optionalImportEnumExtension));
+
+ assertEqualsExactType("124", message.getExtension(optionalStringPieceExtension));
+ assertEqualsExactType("125", message.getExtension(optionalCordExtension));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
+
+ assertEqualsExactType(201 , message.getExtension(repeatedInt32Extension , 0));
+ assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension , 0));
+ assertEqualsExactType(203 , message.getExtension(repeatedUint32Extension , 0));
+ assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension , 0));
+ assertEqualsExactType(205 , message.getExtension(repeatedSint32Extension , 0));
+ assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension , 0));
+ assertEqualsExactType(207 , message.getExtension(repeatedFixed32Extension , 0));
+ assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0));
+ assertEqualsExactType(209 , message.getExtension(repeatedSfixed32Extension, 0));
+ assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0));
+ assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension , 0));
+ assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 0));
+ assertEqualsExactType("215", message.getExtension(repeatedStringExtension , 0));
+ assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
+
+ assertEqualsExactType(217, message.getExtension(repeatedGroupExtension , 0).getA());
+ assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb());
+ assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
+ assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+ message.getExtension(repeatedNestedEnumExtension, 0));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(repeatedForeignEnumExtension, 0));
+ assertEqualsExactType(ImportEnum.IMPORT_BAR,
+ message.getExtension(repeatedImportEnumExtension, 0));
+
+ assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
+ assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
+
+ assertEqualsExactType(301 , message.getExtension(repeatedInt32Extension , 1));
+ assertEqualsExactType(302L , message.getExtension(repeatedInt64Extension , 1));
+ assertEqualsExactType(303 , message.getExtension(repeatedUint32Extension , 1));
+ assertEqualsExactType(304L , message.getExtension(repeatedUint64Extension , 1));
+ assertEqualsExactType(305 , message.getExtension(repeatedSint32Extension , 1));
+ assertEqualsExactType(306L , message.getExtension(repeatedSint64Extension , 1));
+ assertEqualsExactType(307 , message.getExtension(repeatedFixed32Extension , 1));
+ assertEqualsExactType(308L , message.getExtension(repeatedFixed64Extension , 1));
+ assertEqualsExactType(309 , message.getExtension(repeatedSfixed32Extension, 1));
+ assertEqualsExactType(310L , message.getExtension(repeatedSfixed64Extension, 1));
+ assertEqualsExactType(311F , message.getExtension(repeatedFloatExtension , 1));
+ assertEqualsExactType(312D , message.getExtension(repeatedDoubleExtension , 1));
+ assertEqualsExactType(false, message.getExtension(repeatedBoolExtension , 1));
+ assertEqualsExactType("315", message.getExtension(repeatedStringExtension , 1));
+ assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtension, 1));
+
+ assertEqualsExactType(317, message.getExtension(repeatedGroupExtension , 1).getA());
+ assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtension , 1).getBb());
+ assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtension, 1).getC());
+ assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtension , 1).getD());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAZ,
+ message.getExtension(repeatedNestedEnumExtension, 1));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+ message.getExtension(repeatedForeignEnumExtension, 1));
+ assertEqualsExactType(ImportEnum.IMPORT_BAZ,
+ message.getExtension(repeatedImportEnumExtension, 1));
+
+ assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtension, 1));
+ assertEqualsExactType("325", message.getExtension(repeatedCordExtension, 1));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertTrue(message.hasExtension(defaultInt32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultInt64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultUint32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultUint64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSint32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSint64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultFixed32Extension ));
+ Assert.assertTrue(message.hasExtension(defaultFixed64Extension ));
+ Assert.assertTrue(message.hasExtension(defaultSfixed32Extension));
+ Assert.assertTrue(message.hasExtension(defaultSfixed64Extension));
+ Assert.assertTrue(message.hasExtension(defaultFloatExtension ));
+ Assert.assertTrue(message.hasExtension(defaultDoubleExtension ));
+ Assert.assertTrue(message.hasExtension(defaultBoolExtension ));
+ Assert.assertTrue(message.hasExtension(defaultStringExtension ));
+ Assert.assertTrue(message.hasExtension(defaultBytesExtension ));
+
+ Assert.assertTrue(message.hasExtension(defaultNestedEnumExtension ));
+ Assert.assertTrue(message.hasExtension(defaultForeignEnumExtension));
+ Assert.assertTrue(message.hasExtension(defaultImportEnumExtension ));
+
+ Assert.assertTrue(message.hasExtension(defaultStringPieceExtension));
+ Assert.assertTrue(message.hasExtension(defaultCordExtension));
+
+ assertEqualsExactType(401 , message.getExtension(defaultInt32Extension ));
+ assertEqualsExactType(402L , message.getExtension(defaultInt64Extension ));
+ assertEqualsExactType(403 , message.getExtension(defaultUint32Extension ));
+ assertEqualsExactType(404L , message.getExtension(defaultUint64Extension ));
+ assertEqualsExactType(405 , message.getExtension(defaultSint32Extension ));
+ assertEqualsExactType(406L , message.getExtension(defaultSint64Extension ));
+ assertEqualsExactType(407 , message.getExtension(defaultFixed32Extension ));
+ assertEqualsExactType(408L , message.getExtension(defaultFixed64Extension ));
+ assertEqualsExactType(409 , message.getExtension(defaultSfixed32Extension));
+ assertEqualsExactType(410L , message.getExtension(defaultSfixed64Extension));
+ assertEqualsExactType(411F , message.getExtension(defaultFloatExtension ));
+ assertEqualsExactType(412D , message.getExtension(defaultDoubleExtension ));
+ assertEqualsExactType(false, message.getExtension(defaultBoolExtension ));
+ assertEqualsExactType("415", message.getExtension(defaultStringExtension ));
+ assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtension));
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+ message.getExtension(defaultNestedEnumExtension ));
+ assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+ message.getExtension(defaultForeignEnumExtension));
+ assertEqualsExactType(ImportEnum.IMPORT_FOO,
+ message.getExtension(defaultImportEnumExtension));
+
+ assertEqualsExactType("424", message.getExtension(defaultStringPieceExtension));
+ assertEqualsExactType("425", message.getExtension(defaultCordExtension));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are cleared, and that getting the extensions returns their
+ * default values.
+ */
+ public static void assertExtensionsClear(TestAllExtensionsOrBuilder message) {
+ // hasBlah() should initially be false for all optional fields.
+ Assert.assertFalse(message.hasExtension(optionalInt32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalInt64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalUint32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalUint64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSint32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSint64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalFixed32Extension ));
+ Assert.assertFalse(message.hasExtension(optionalFixed64Extension ));
+ Assert.assertFalse(message.hasExtension(optionalSfixed32Extension));
+ Assert.assertFalse(message.hasExtension(optionalSfixed64Extension));
+ Assert.assertFalse(message.hasExtension(optionalFloatExtension ));
+ Assert.assertFalse(message.hasExtension(optionalDoubleExtension ));
+ Assert.assertFalse(message.hasExtension(optionalBoolExtension ));
+ Assert.assertFalse(message.hasExtension(optionalStringExtension ));
+ Assert.assertFalse(message.hasExtension(optionalBytesExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalGroupExtension ));
+ Assert.assertFalse(message.hasExtension(optionalNestedMessageExtension ));
+ Assert.assertFalse(message.hasExtension(optionalForeignMessageExtension));
+ Assert.assertFalse(message.hasExtension(optionalImportMessageExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalNestedEnumExtension ));
+ Assert.assertFalse(message.hasExtension(optionalForeignEnumExtension));
+ Assert.assertFalse(message.hasExtension(optionalImportEnumExtension ));
+
+ Assert.assertFalse(message.hasExtension(optionalStringPieceExtension));
+ Assert.assertFalse(message.hasExtension(optionalCordExtension));
+
+ // Optional fields without defaults are set to zero or something like it.
+ assertEqualsExactType(0 , message.getExtension(optionalInt32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalInt64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalUint32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalUint64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalSint32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalSint64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalFixed32Extension ));
+ assertEqualsExactType(0L , message.getExtension(optionalFixed64Extension ));
+ assertEqualsExactType(0 , message.getExtension(optionalSfixed32Extension));
+ assertEqualsExactType(0L , message.getExtension(optionalSfixed64Extension));
+ assertEqualsExactType(0F , message.getExtension(optionalFloatExtension ));
+ assertEqualsExactType(0D , message.getExtension(optionalDoubleExtension ));
+ assertEqualsExactType(false, message.getExtension(optionalBoolExtension ));
+ assertEqualsExactType("" , message.getExtension(optionalStringExtension ));
+ assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtension));
+
+ // Embedded messages should also be clear.
+ Assert.assertFalse(message.getExtension(optionalGroupExtension ).hasA());
+ Assert.assertFalse(message.getExtension(optionalNestedMessageExtension ).hasBb());
+ Assert.assertFalse(message.getExtension(optionalForeignMessageExtension).hasC());
+ Assert.assertFalse(message.getExtension(optionalImportMessageExtension ).hasD());
+
+ assertEqualsExactType(0, message.getExtension(optionalGroupExtension ).getA());
+ assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtension ).getBb());
+ assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtension).getC());
+ assertEqualsExactType(0, message.getExtension(optionalImportMessageExtension ).getD());
+
+ // Enums without defaults are set to the first value in the enum.
+ assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+ message.getExtension(optionalNestedEnumExtension ));
+ assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+ message.getExtension(optionalForeignEnumExtension));
+ assertEqualsExactType(ImportEnum.IMPORT_FOO,
+ message.getExtension(optionalImportEnumExtension));
+
+ assertEqualsExactType("", message.getExtension(optionalStringPieceExtension));
+ assertEqualsExactType("", message.getExtension(optionalCordExtension));
+
+ // Repeated fields are empty.
+ Assert.assertEquals(0, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtension));
+
+ // Repeated fields are empty via getExtension().size().
+ Assert.assertEquals(0, message.getExtension(repeatedInt32Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedInt64Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedUint32Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedUint64Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedSint32Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedSint64Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedFixed32Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedFixed64Extension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedSfixed32Extension).size());
+ Assert.assertEquals(0, message.getExtension(repeatedSfixed64Extension).size());
+ Assert.assertEquals(0, message.getExtension(repeatedFloatExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedDoubleExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedBoolExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedStringExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedBytesExtension ).size());
+
+ Assert.assertEquals(0, message.getExtension(repeatedGroupExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedNestedMessageExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedForeignMessageExtension).size());
+ Assert.assertEquals(0, message.getExtension(repeatedImportMessageExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedNestedEnumExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedForeignEnumExtension ).size());
+ Assert.assertEquals(0, message.getExtension(repeatedImportEnumExtension ).size());
+
+ Assert.assertEquals(0, message.getExtension(repeatedStringPieceExtension).size());
+ Assert.assertEquals(0, message.getExtension(repeatedCordExtension).size());
+
+ // hasBlah() should also be false for all default fields.
+ Assert.assertFalse(message.hasExtension(defaultInt32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultInt64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultUint32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultUint64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSint32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSint64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultFixed32Extension ));
+ Assert.assertFalse(message.hasExtension(defaultFixed64Extension ));
+ Assert.assertFalse(message.hasExtension(defaultSfixed32Extension));
+ Assert.assertFalse(message.hasExtension(defaultSfixed64Extension));
+ Assert.assertFalse(message.hasExtension(defaultFloatExtension ));
+ Assert.assertFalse(message.hasExtension(defaultDoubleExtension ));
+ Assert.assertFalse(message.hasExtension(defaultBoolExtension ));
+ Assert.assertFalse(message.hasExtension(defaultStringExtension ));
+ Assert.assertFalse(message.hasExtension(defaultBytesExtension ));
+
+ Assert.assertFalse(message.hasExtension(defaultNestedEnumExtension ));
+ Assert.assertFalse(message.hasExtension(defaultForeignEnumExtension));
+ Assert.assertFalse(message.hasExtension(defaultImportEnumExtension ));
+
+ Assert.assertFalse(message.hasExtension(defaultStringPieceExtension));
+ Assert.assertFalse(message.hasExtension(defaultCordExtension));
+
+ // Fields with defaults have their default values (duh).
+ assertEqualsExactType( 41 , message.getExtension(defaultInt32Extension ));
+ assertEqualsExactType( 42L , message.getExtension(defaultInt64Extension ));
+ assertEqualsExactType( 43 , message.getExtension(defaultUint32Extension ));
+ assertEqualsExactType( 44L , message.getExtension(defaultUint64Extension ));
+ assertEqualsExactType(-45 , message.getExtension(defaultSint32Extension ));
+ assertEqualsExactType( 46L , message.getExtension(defaultSint64Extension ));
+ assertEqualsExactType( 47 , message.getExtension(defaultFixed32Extension ));
+ assertEqualsExactType( 48L , message.getExtension(defaultFixed64Extension ));
+ assertEqualsExactType( 49 , message.getExtension(defaultSfixed32Extension));
+ assertEqualsExactType(-50L , message.getExtension(defaultSfixed64Extension));
+ assertEqualsExactType( 51.5F , message.getExtension(defaultFloatExtension ));
+ assertEqualsExactType( 52e3D , message.getExtension(defaultDoubleExtension ));
+ assertEqualsExactType(true , message.getExtension(defaultBoolExtension ));
+ assertEqualsExactType("hello", message.getExtension(defaultStringExtension ));
+ assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtension));
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+ message.getExtension(defaultNestedEnumExtension ));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(defaultForeignEnumExtension));
+ assertEqualsExactType(ImportEnum.IMPORT_BAR,
+ message.getExtension(defaultImportEnumExtension));
+
+ assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtension));
+ assertEqualsExactType("123", message.getExtension(defaultCordExtension));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are set to the values assigned by {@code setAllExtensions}
+ * followed by {@code modifyRepeatedExtensions}.
+ */
+ public static void assertRepeatedExtensionsModified(
+ TestAllExtensionsOrBuilder message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
+
+ assertEqualsExactType(201 , message.getExtension(repeatedInt32Extension , 0));
+ assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension , 0));
+ assertEqualsExactType(203 , message.getExtension(repeatedUint32Extension , 0));
+ assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension , 0));
+ assertEqualsExactType(205 , message.getExtension(repeatedSint32Extension , 0));
+ assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension , 0));
+ assertEqualsExactType(207 , message.getExtension(repeatedFixed32Extension , 0));
+ assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0));
+ assertEqualsExactType(209 , message.getExtension(repeatedSfixed32Extension, 0));
+ assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0));
+ assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension , 0));
+ assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 0));
+ assertEqualsExactType("215", message.getExtension(repeatedStringExtension , 0));
+ assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
+
+ assertEqualsExactType(217, message.getExtension(repeatedGroupExtension , 0).getA());
+ assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb());
+ assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
+ assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+ message.getExtension(repeatedNestedEnumExtension, 0));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(repeatedForeignEnumExtension, 0));
+ assertEqualsExactType(ImportEnum.IMPORT_BAR,
+ message.getExtension(repeatedImportEnumExtension, 0));
+
+ assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
+ assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
+
+ // Actually verify the second (modified) elements now.
+ assertEqualsExactType(501 , message.getExtension(repeatedInt32Extension , 1));
+ assertEqualsExactType(502L , message.getExtension(repeatedInt64Extension , 1));
+ assertEqualsExactType(503 , message.getExtension(repeatedUint32Extension , 1));
+ assertEqualsExactType(504L , message.getExtension(repeatedUint64Extension , 1));
+ assertEqualsExactType(505 , message.getExtension(repeatedSint32Extension , 1));
+ assertEqualsExactType(506L , message.getExtension(repeatedSint64Extension , 1));
+ assertEqualsExactType(507 , message.getExtension(repeatedFixed32Extension , 1));
+ assertEqualsExactType(508L , message.getExtension(repeatedFixed64Extension , 1));
+ assertEqualsExactType(509 , message.getExtension(repeatedSfixed32Extension, 1));
+ assertEqualsExactType(510L , message.getExtension(repeatedSfixed64Extension, 1));
+ assertEqualsExactType(511F , message.getExtension(repeatedFloatExtension , 1));
+ assertEqualsExactType(512D , message.getExtension(repeatedDoubleExtension , 1));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtension , 1));
+ assertEqualsExactType("515", message.getExtension(repeatedStringExtension , 1));
+ assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtension, 1));
+
+ assertEqualsExactType(517, message.getExtension(repeatedGroupExtension , 1).getA());
+ assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtension , 1).getBb());
+ assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtension, 1).getC());
+ assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtension , 1).getD());
+
+ assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+ message.getExtension(repeatedNestedEnumExtension, 1));
+ assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+ message.getExtension(repeatedForeignEnumExtension, 1));
+ assertEqualsExactType(ImportEnum.IMPORT_FOO,
+ message.getExtension(repeatedImportEnumExtension, 1));
+
+ assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtension, 1));
+ assertEqualsExactType("525", message.getExtension(repeatedCordExtension, 1));
+ }
+
+ public static void setPackedExtensions(TestPackedExtensions.Builder message) {
+ message.addExtension(packedInt32Extension , 601);
+ message.addExtension(packedInt64Extension , 602L);
+ message.addExtension(packedUint32Extension , 603);
+ message.addExtension(packedUint64Extension , 604L);
+ message.addExtension(packedSint32Extension , 605);
+ message.addExtension(packedSint64Extension , 606L);
+ message.addExtension(packedFixed32Extension , 607);
+ message.addExtension(packedFixed64Extension , 608L);
+ message.addExtension(packedSfixed32Extension, 609);
+ message.addExtension(packedSfixed64Extension, 610L);
+ message.addExtension(packedFloatExtension , 611F);
+ message.addExtension(packedDoubleExtension , 612D);
+ message.addExtension(packedBoolExtension , true);
+ message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAR);
+ // Add a second one of each field.
+ message.addExtension(packedInt32Extension , 701);
+ message.addExtension(packedInt64Extension , 702L);
+ message.addExtension(packedUint32Extension , 703);
+ message.addExtension(packedUint64Extension , 704L);
+ message.addExtension(packedSint32Extension , 705);
+ message.addExtension(packedSint64Extension , 706L);
+ message.addExtension(packedFixed32Extension , 707);
+ message.addExtension(packedFixed64Extension , 708L);
+ message.addExtension(packedSfixed32Extension, 709);
+ message.addExtension(packedSfixed64Extension, 710L);
+ message.addExtension(packedFloatExtension , 711F);
+ message.addExtension(packedDoubleExtension , 712D);
+ message.addExtension(packedBoolExtension , false);
+ message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAZ);
+ }
+
+ public static void assertPackedExtensionsSet(TestPackedExtensions message) {
+ Assert.assertEquals(2, message.getExtensionCount(packedInt32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedInt64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedUint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedUint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSint32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSint64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedFixed32Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedFixed64Extension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSfixed32Extension));
+ Assert.assertEquals(2, message.getExtensionCount(packedSfixed64Extension));
+ Assert.assertEquals(2, message.getExtensionCount(packedFloatExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedBoolExtension ));
+ Assert.assertEquals(2, message.getExtensionCount(packedEnumExtension));
+ assertEqualsExactType(601 , message.getExtension(packedInt32Extension , 0));
+ assertEqualsExactType(602L , message.getExtension(packedInt64Extension , 0));
+ assertEqualsExactType(603 , message.getExtension(packedUint32Extension , 0));
+ assertEqualsExactType(604L , message.getExtension(packedUint64Extension , 0));
+ assertEqualsExactType(605 , message.getExtension(packedSint32Extension , 0));
+ assertEqualsExactType(606L , message.getExtension(packedSint64Extension , 0));
+ assertEqualsExactType(607 , message.getExtension(packedFixed32Extension , 0));
+ assertEqualsExactType(608L , message.getExtension(packedFixed64Extension , 0));
+ assertEqualsExactType(609 , message.getExtension(packedSfixed32Extension, 0));
+ assertEqualsExactType(610L , message.getExtension(packedSfixed64Extension, 0));
+ assertEqualsExactType(611F , message.getExtension(packedFloatExtension , 0));
+ assertEqualsExactType(612D , message.getExtension(packedDoubleExtension , 0));
+ assertEqualsExactType(true , message.getExtension(packedBoolExtension , 0));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+ message.getExtension(packedEnumExtension, 0));
+ assertEqualsExactType(701 , message.getExtension(packedInt32Extension , 1));
+ assertEqualsExactType(702L , message.getExtension(packedInt64Extension , 1));
+ assertEqualsExactType(703 , message.getExtension(packedUint32Extension , 1));
+ assertEqualsExactType(704L , message.getExtension(packedUint64Extension , 1));
+ assertEqualsExactType(705 , message.getExtension(packedSint32Extension , 1));
+ assertEqualsExactType(706L , message.getExtension(packedSint64Extension , 1));
+ assertEqualsExactType(707 , message.getExtension(packedFixed32Extension , 1));
+ assertEqualsExactType(708L , message.getExtension(packedFixed64Extension , 1));
+ assertEqualsExactType(709 , message.getExtension(packedSfixed32Extension, 1));
+ assertEqualsExactType(710L , message.getExtension(packedSfixed64Extension, 1));
+ assertEqualsExactType(711F , message.getExtension(packedFloatExtension , 1));
+ assertEqualsExactType(712D , message.getExtension(packedDoubleExtension , 1));
+ assertEqualsExactType(false, message.getExtension(packedBoolExtension , 1));
+ assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+ message.getExtension(packedEnumExtension, 1));
+ }
+
+ // ===================================================================
+ // Lite extensions
+
+ /**
+ * Set every field of {@code message} to the values expected by
+ * {@code assertAllExtensionsSet()}.
+ */
+ public static void setAllExtensions(TestAllExtensionsLite.Builder message) {
+ message.setExtension(optionalInt32ExtensionLite , 101);
+ message.setExtension(optionalInt64ExtensionLite , 102L);
+ message.setExtension(optionalUint32ExtensionLite , 103);
+ message.setExtension(optionalUint64ExtensionLite , 104L);
+ message.setExtension(optionalSint32ExtensionLite , 105);
+ message.setExtension(optionalSint64ExtensionLite , 106L);
+ message.setExtension(optionalFixed32ExtensionLite , 107);
+ message.setExtension(optionalFixed64ExtensionLite , 108L);
+ message.setExtension(optionalSfixed32ExtensionLite, 109);
+ message.setExtension(optionalSfixed64ExtensionLite, 110L);
+ message.setExtension(optionalFloatExtensionLite , 111F);
+ message.setExtension(optionalDoubleExtensionLite , 112D);
+ message.setExtension(optionalBoolExtensionLite , true);
+ message.setExtension(optionalStringExtensionLite , "115");
+ message.setExtension(optionalBytesExtensionLite , toBytes("116"));
+
+ message.setExtension(optionalGroupExtensionLite,
+ OptionalGroup_extension_lite.newBuilder().setA(117).build());
+ message.setExtension(optionalNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
+ message.setExtension(optionalForeignMessageExtensionLite,
+ ForeignMessageLite.newBuilder().setC(119).build());
+ message.setExtension(optionalImportMessageExtensionLite,
+ ImportMessageLite.newBuilder().setD(120).build());
+
+ message.setExtension(optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
+ message.setExtension(optionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+ message.setExtension(optionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
+
+ message.setExtension(optionalStringPieceExtensionLite, "124");
+ message.setExtension(optionalCordExtensionLite, "125");
+
+ // -----------------------------------------------------------------
+
+ message.addExtension(repeatedInt32ExtensionLite , 201);
+ message.addExtension(repeatedInt64ExtensionLite , 202L);
+ message.addExtension(repeatedUint32ExtensionLite , 203);
+ message.addExtension(repeatedUint64ExtensionLite , 204L);
+ message.addExtension(repeatedSint32ExtensionLite , 205);
+ message.addExtension(repeatedSint64ExtensionLite , 206L);
+ message.addExtension(repeatedFixed32ExtensionLite , 207);
+ message.addExtension(repeatedFixed64ExtensionLite , 208L);
+ message.addExtension(repeatedSfixed32ExtensionLite, 209);
+ message.addExtension(repeatedSfixed64ExtensionLite, 210L);
+ message.addExtension(repeatedFloatExtensionLite , 211F);
+ message.addExtension(repeatedDoubleExtensionLite , 212D);
+ message.addExtension(repeatedBoolExtensionLite , true);
+ message.addExtension(repeatedStringExtensionLite , "215");
+ message.addExtension(repeatedBytesExtensionLite , toBytes("216"));
+
+ message.addExtension(repeatedGroupExtensionLite,
+ RepeatedGroup_extension_lite.newBuilder().setA(217).build());
+ message.addExtension(repeatedNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
+ message.addExtension(repeatedForeignMessageExtensionLite,
+ ForeignMessageLite.newBuilder().setC(219).build());
+ message.addExtension(repeatedImportMessageExtensionLite,
+ ImportMessageLite.newBuilder().setD(220).build());
+
+ message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAR);
+ message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
+ message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAR);
+
+ message.addExtension(repeatedStringPieceExtensionLite, "224");
+ message.addExtension(repeatedCordExtensionLite, "225");
+
+ // Add a second one of each field.
+ message.addExtension(repeatedInt32ExtensionLite , 301);
+ message.addExtension(repeatedInt64ExtensionLite , 302L);
+ message.addExtension(repeatedUint32ExtensionLite , 303);
+ message.addExtension(repeatedUint64ExtensionLite , 304L);
+ message.addExtension(repeatedSint32ExtensionLite , 305);
+ message.addExtension(repeatedSint64ExtensionLite , 306L);
+ message.addExtension(repeatedFixed32ExtensionLite , 307);
+ message.addExtension(repeatedFixed64ExtensionLite , 308L);
+ message.addExtension(repeatedSfixed32ExtensionLite, 309);
+ message.addExtension(repeatedSfixed64ExtensionLite, 310L);
+ message.addExtension(repeatedFloatExtensionLite , 311F);
+ message.addExtension(repeatedDoubleExtensionLite , 312D);
+ message.addExtension(repeatedBoolExtensionLite , false);
+ message.addExtension(repeatedStringExtensionLite , "315");
+ message.addExtension(repeatedBytesExtensionLite , toBytes("316"));
+
+ message.addExtension(repeatedGroupExtensionLite,
+ RepeatedGroup_extension_lite.newBuilder().setA(317).build());
+ message.addExtension(repeatedNestedMessageExtensionLite,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
+ message.addExtension(repeatedForeignMessageExtensionLite,
+ ForeignMessageLite.newBuilder().setC(319).build());
+ message.addExtension(repeatedImportMessageExtensionLite,
+ ImportMessageLite.newBuilder().setD(320).build());
+
+ message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
+ message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+ message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
+
+ message.addExtension(repeatedStringPieceExtensionLite, "324");
+ message.addExtension(repeatedCordExtensionLite, "325");
+
+ // -----------------------------------------------------------------
+
+ message.setExtension(defaultInt32ExtensionLite , 401);
+ message.setExtension(defaultInt64ExtensionLite , 402L);
+ message.setExtension(defaultUint32ExtensionLite , 403);
+ message.setExtension(defaultUint64ExtensionLite , 404L);
+ message.setExtension(defaultSint32ExtensionLite , 405);
+ message.setExtension(defaultSint64ExtensionLite , 406L);
+ message.setExtension(defaultFixed32ExtensionLite , 407);
+ message.setExtension(defaultFixed64ExtensionLite , 408L);
+ message.setExtension(defaultSfixed32ExtensionLite, 409);
+ message.setExtension(defaultSfixed64ExtensionLite, 410L);
+ message.setExtension(defaultFloatExtensionLite , 411F);
+ message.setExtension(defaultDoubleExtensionLite , 412D);
+ message.setExtension(defaultBoolExtensionLite , false);
+ message.setExtension(defaultStringExtensionLite , "415");
+ message.setExtension(defaultBytesExtensionLite , toBytes("416"));
+
+ message.setExtension(defaultNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.FOO);
+ message.setExtension(defaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_FOO);
+ message.setExtension(defaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_FOO);
+
+ message.setExtension(defaultStringPieceExtensionLite, "424");
+ message.setExtension(defaultCordExtensionLite, "425");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Modify the repeated extensions of {@code message} to contain the values
+ * expected by {@code assertRepeatedExtensionsModified()}.
+ */
+ public static void modifyRepeatedExtensions(
+ TestAllExtensionsLite.Builder message) {
+ message.setExtension(repeatedInt32ExtensionLite , 1, 501);
+ message.setExtension(repeatedInt64ExtensionLite , 1, 502L);
+ message.setExtension(repeatedUint32ExtensionLite , 1, 503);
+ message.setExtension(repeatedUint64ExtensionLite , 1, 504L);
+ message.setExtension(repeatedSint32ExtensionLite , 1, 505);
+ message.setExtension(repeatedSint64ExtensionLite , 1, 506L);
+ message.setExtension(repeatedFixed32ExtensionLite , 1, 507);
+ message.setExtension(repeatedFixed64ExtensionLite , 1, 508L);
+ message.setExtension(repeatedSfixed32ExtensionLite, 1, 509);
+ message.setExtension(repeatedSfixed64ExtensionLite, 1, 510L);
+ message.setExtension(repeatedFloatExtensionLite , 1, 511F);
+ message.setExtension(repeatedDoubleExtensionLite , 1, 512D);
+ message.setExtension(repeatedBoolExtensionLite , 1, true);
+ message.setExtension(repeatedStringExtensionLite , 1, "515");
+ message.setExtension(repeatedBytesExtensionLite , 1, toBytes("516"));
+
+ message.setExtension(repeatedGroupExtensionLite, 1,
+ RepeatedGroup_extension_lite.newBuilder().setA(517).build());
+ message.setExtension(repeatedNestedMessageExtensionLite, 1,
+ TestAllTypesLite.NestedMessage.newBuilder().setBb(518).build());
+ message.setExtension(repeatedForeignMessageExtensionLite, 1,
+ ForeignMessageLite.newBuilder().setC(519).build());
+ message.setExtension(repeatedImportMessageExtensionLite, 1,
+ ImportMessageLite.newBuilder().setD(520).build());
+
+ message.setExtension(repeatedNestedEnumExtensionLite , 1, TestAllTypesLite.NestedEnum.FOO);
+ message.setExtension(repeatedForeignEnumExtensionLite, 1, ForeignEnumLite.FOREIGN_LITE_FOO);
+ message.setExtension(repeatedImportEnumExtensionLite , 1, ImportEnumLite.IMPORT_LITE_FOO);
+
+ message.setExtension(repeatedStringPieceExtensionLite, 1, "524");
+ message.setExtension(repeatedCordExtensionLite, 1, "525");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are set to the values assigned by {@code setAllExtensions}.
+ */
+ public static void assertAllExtensionsSet(
+ TestAllExtensionsLiteOrBuilder message) {
+ Assert.assertTrue(message.hasExtension(optionalInt32ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalInt64ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalUint32ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalUint64ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalSint32ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalSint64ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalFixed32ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalFixed64ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalSfixed32ExtensionLite));
+ Assert.assertTrue(message.hasExtension(optionalSfixed64ExtensionLite));
+ Assert.assertTrue(message.hasExtension(optionalFloatExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalDoubleExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalBoolExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalStringExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalBytesExtensionLite ));
+
+ Assert.assertTrue(message.hasExtension(optionalGroupExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalNestedMessageExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalForeignMessageExtensionLite));
+ Assert.assertTrue(message.hasExtension(optionalImportMessageExtensionLite ));
+
+ Assert.assertTrue(message.getExtension(optionalGroupExtensionLite ).hasA());
+ Assert.assertTrue(message.getExtension(optionalNestedMessageExtensionLite ).hasBb());
+ Assert.assertTrue(message.getExtension(optionalForeignMessageExtensionLite).hasC());
+ Assert.assertTrue(message.getExtension(optionalImportMessageExtensionLite ).hasD());
+
+ Assert.assertTrue(message.hasExtension(optionalNestedEnumExtensionLite ));
+ Assert.assertTrue(message.hasExtension(optionalForeignEnumExtensionLite));
+ Assert.assertTrue(message.hasExtension(optionalImportEnumExtensionLite ));
+
+ Assert.assertTrue(message.hasExtension(optionalStringPieceExtensionLite));
+ Assert.assertTrue(message.hasExtension(optionalCordExtensionLite));
+
+ assertEqualsExactType(101 , message.getExtension(optionalInt32ExtensionLite ));
+ assertEqualsExactType(102L , message.getExtension(optionalInt64ExtensionLite ));
+ assertEqualsExactType(103 , message.getExtension(optionalUint32ExtensionLite ));
+ assertEqualsExactType(104L , message.getExtension(optionalUint64ExtensionLite ));
+ assertEqualsExactType(105 , message.getExtension(optionalSint32ExtensionLite ));
+ assertEqualsExactType(106L , message.getExtension(optionalSint64ExtensionLite ));
+ assertEqualsExactType(107 , message.getExtension(optionalFixed32ExtensionLite ));
+ assertEqualsExactType(108L , message.getExtension(optionalFixed64ExtensionLite ));
+ assertEqualsExactType(109 , message.getExtension(optionalSfixed32ExtensionLite));
+ assertEqualsExactType(110L , message.getExtension(optionalSfixed64ExtensionLite));
+ assertEqualsExactType(111F , message.getExtension(optionalFloatExtensionLite ));
+ assertEqualsExactType(112D , message.getExtension(optionalDoubleExtensionLite ));
+ assertEqualsExactType(true , message.getExtension(optionalBoolExtensionLite ));
+ assertEqualsExactType("115", message.getExtension(optionalStringExtensionLite ));
+ assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtensionLite));
+
+ assertEqualsExactType(117, message.getExtension(optionalGroupExtensionLite ).getA());
+ assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtensionLite ).getBb());
+ assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtensionLite).getC());
+ assertEqualsExactType(120, message.getExtension(optionalImportMessageExtensionLite ).getD());
+
+ assertEqualsExactType(TestAllTypesLite.NestedEnum.BAZ,
+ message.getExtension(optionalNestedEnumExtensionLite));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ,
+ message.getExtension(optionalForeignEnumExtensionLite));
+ assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAZ,
+ message.getExtension(optionalImportEnumExtensionLite));
+
+ assertEqualsExactType("124", message.getExtension(optionalStringPieceExtensionLite));
+ assertEqualsExactType("125", message.getExtension(optionalCordExtensionLite));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32ExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64ExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtensionLite ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtensionLite));
+
+ assertEqualsExactType(201 , message.getExtension(repeatedInt32ExtensionLite , 0));
+ assertEqualsExactType(202L , message.getExtension(repeatedInt64ExtensionLite , 0));
+ assertEqualsExactType(203 , message.getExtension(repeatedUint32ExtensionLite , 0));
+ assertEqualsExactType(204L , message.getExtension(repeatedUint64ExtensionLite , 0));
+ assertEqualsExactType(205 , message.getExtension(repeatedSint32ExtensionLite , 0));
+ assertEqualsExactType(206L , message.getExtension(repeatedSint64ExtensionLite , 0));
+ assertEqualsExactType(207 , message.getExtension(repeatedFixed32ExtensionLite , 0));
+ assertEqualsExactType(208L , message.getExtension(repeatedFixed64ExtensionLite , 0));
+ assertEqualsExactType(209 , message.getExtension(repeatedSfixed32ExtensionLite, 0));
+ assertEqualsExactType(210L , message.getExtension(repeatedSfixed64ExtensionLite, 0));
+ assertEqualsExactType(211F , message.getExtension(repeatedFloatExtensionLite , 0));
+ assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtensionLite , 0));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite , 0));
+ assertEqualsExactType("215", message.getExtension(repeatedStringExtensionLite , 0));
+ assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtensionLite, 0));
+
+ assertEqualsExactType(217, message.getExtension(repeatedGroupExtensionLite ,0).getA());
+ assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite ,0).getBb());
+ assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite,0).getC());
+ assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite ,0).getD());
+
+ assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR,
+ message.getExtension(repeatedNestedEnumExtensionLite, 0));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR,
+ message.getExtension(repeatedForeignEnumExtensionLite, 0));
+ assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR,
+ message.getExtension(repeatedImportEnumExtensionLite, 0));
+
+ assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtensionLite, 0));
+ assertEqualsExactType("225", message.getExtension(repeatedCordExtensionLite, 0));
+
+ assertEqualsExactType(301 , message.getExtension(repeatedInt32ExtensionLite , 1));
+ assertEqualsExactType(302L , message.getExtension(repeatedInt64ExtensionLite , 1));
+ assertEqualsExactType(303 , message.getExtension(repeatedUint32ExtensionLite , 1));
+ assertEqualsExactType(304L , message.getExtension(repeatedUint64ExtensionLite , 1));
+ assertEqualsExactType(305 , message.getExtension(repeatedSint32ExtensionLite , 1));
+ assertEqualsExactType(306L , message.getExtension(repeatedSint64ExtensionLite , 1));
+ assertEqualsExactType(307 , message.getExtension(repeatedFixed32ExtensionLite , 1));
+ assertEqualsExactType(308L , message.getExtension(repeatedFixed64ExtensionLite , 1));
+ assertEqualsExactType(309 , message.getExtension(repeatedSfixed32ExtensionLite, 1));
+ assertEqualsExactType(310L , message.getExtension(repeatedSfixed64ExtensionLite, 1));
+ assertEqualsExactType(311F , message.getExtension(repeatedFloatExtensionLite , 1));
+ assertEqualsExactType(312D , message.getExtension(repeatedDoubleExtensionLite , 1));
+ assertEqualsExactType(false, message.getExtension(repeatedBoolExtensionLite , 1));
+ assertEqualsExactType("315", message.getExtension(repeatedStringExtensionLite , 1));
+ assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtensionLite, 1));
+
+ assertEqualsExactType(317, message.getExtension(repeatedGroupExtensionLite ,1).getA());
+ assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtensionLite ,1).getBb());
+ assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtensionLite,1).getC());
+ assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtensionLite ,1).getD());
+
+ assertEqualsExactType(TestAllTypesLite.NestedEnum.BAZ,
+ message.getExtension(repeatedNestedEnumExtensionLite, 1));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ,
+ message.getExtension(repeatedForeignEnumExtensionLite, 1));
+ assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAZ,
+ message.getExtension(repeatedImportEnumExtensionLite, 1));
+
+ assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtensionLite, 1));
+ assertEqualsExactType("325", message.getExtension(repeatedCordExtensionLite, 1));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertTrue(message.hasExtension(defaultInt32ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultInt64ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultUint32ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultUint64ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultSint32ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultSint64ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultFixed32ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultFixed64ExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultSfixed32ExtensionLite));
+ Assert.assertTrue(message.hasExtension(defaultSfixed64ExtensionLite));
+ Assert.assertTrue(message.hasExtension(defaultFloatExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultDoubleExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultBoolExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultStringExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultBytesExtensionLite ));
+
+ Assert.assertTrue(message.hasExtension(defaultNestedEnumExtensionLite ));
+ Assert.assertTrue(message.hasExtension(defaultForeignEnumExtensionLite));
+ Assert.assertTrue(message.hasExtension(defaultImportEnumExtensionLite ));
+
+ Assert.assertTrue(message.hasExtension(defaultStringPieceExtensionLite));
+ Assert.assertTrue(message.hasExtension(defaultCordExtensionLite));
+
+ assertEqualsExactType(401 , message.getExtension(defaultInt32ExtensionLite ));
+ assertEqualsExactType(402L , message.getExtension(defaultInt64ExtensionLite ));
+ assertEqualsExactType(403 , message.getExtension(defaultUint32ExtensionLite ));
+ assertEqualsExactType(404L , message.getExtension(defaultUint64ExtensionLite ));
+ assertEqualsExactType(405 , message.getExtension(defaultSint32ExtensionLite ));
+ assertEqualsExactType(406L , message.getExtension(defaultSint64ExtensionLite ));
+ assertEqualsExactType(407 , message.getExtension(defaultFixed32ExtensionLite ));
+ assertEqualsExactType(408L , message.getExtension(defaultFixed64ExtensionLite ));
+ assertEqualsExactType(409 , message.getExtension(defaultSfixed32ExtensionLite));
+ assertEqualsExactType(410L , message.getExtension(defaultSfixed64ExtensionLite));
+ assertEqualsExactType(411F , message.getExtension(defaultFloatExtensionLite ));
+ assertEqualsExactType(412D , message.getExtension(defaultDoubleExtensionLite ));
+ assertEqualsExactType(false, message.getExtension(defaultBoolExtensionLite ));
+ assertEqualsExactType("415", message.getExtension(defaultStringExtensionLite ));
+ assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtensionLite));
+
+ assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO,
+ message.getExtension(defaultNestedEnumExtensionLite ));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO,
+ message.getExtension(defaultForeignEnumExtensionLite));
+ assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO,
+ message.getExtension(defaultImportEnumExtensionLite));
+
+ assertEqualsExactType("424", message.getExtension(defaultStringPieceExtensionLite));
+ assertEqualsExactType("425", message.getExtension(defaultCordExtensionLite));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are cleared, and that getting the extensions returns their
+ * default values.
+ */
+ public static void assertExtensionsClear(
+ TestAllExtensionsLiteOrBuilder message) {
+ // hasBlah() should initially be false for all optional fields.
+ Assert.assertFalse(message.hasExtension(optionalInt32ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalInt64ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalUint32ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalUint64ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalSint32ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalSint64ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalFixed32ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalFixed64ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalSfixed32ExtensionLite));
+ Assert.assertFalse(message.hasExtension(optionalSfixed64ExtensionLite));
+ Assert.assertFalse(message.hasExtension(optionalFloatExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalDoubleExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalBoolExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalStringExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalBytesExtensionLite ));
+
+ Assert.assertFalse(message.hasExtension(optionalGroupExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalNestedMessageExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalForeignMessageExtensionLite));
+ Assert.assertFalse(message.hasExtension(optionalImportMessageExtensionLite ));
+
+ Assert.assertFalse(message.hasExtension(optionalNestedEnumExtensionLite ));
+ Assert.assertFalse(message.hasExtension(optionalForeignEnumExtensionLite));
+ Assert.assertFalse(message.hasExtension(optionalImportEnumExtensionLite ));
+
+ Assert.assertFalse(message.hasExtension(optionalStringPieceExtensionLite));
+ Assert.assertFalse(message.hasExtension(optionalCordExtensionLite));
+
+ // Optional fields without defaults are set to zero or something like it.
+ assertEqualsExactType(0 , message.getExtension(optionalInt32ExtensionLite ));
+ assertEqualsExactType(0L , message.getExtension(optionalInt64ExtensionLite ));
+ assertEqualsExactType(0 , message.getExtension(optionalUint32ExtensionLite ));
+ assertEqualsExactType(0L , message.getExtension(optionalUint64ExtensionLite ));
+ assertEqualsExactType(0 , message.getExtension(optionalSint32ExtensionLite ));
+ assertEqualsExactType(0L , message.getExtension(optionalSint64ExtensionLite ));
+ assertEqualsExactType(0 , message.getExtension(optionalFixed32ExtensionLite ));
+ assertEqualsExactType(0L , message.getExtension(optionalFixed64ExtensionLite ));
+ assertEqualsExactType(0 , message.getExtension(optionalSfixed32ExtensionLite));
+ assertEqualsExactType(0L , message.getExtension(optionalSfixed64ExtensionLite));
+ assertEqualsExactType(0F , message.getExtension(optionalFloatExtensionLite ));
+ assertEqualsExactType(0D , message.getExtension(optionalDoubleExtensionLite ));
+ assertEqualsExactType(false, message.getExtension(optionalBoolExtensionLite ));
+ assertEqualsExactType("" , message.getExtension(optionalStringExtensionLite ));
+ assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtensionLite));
+
+ // Embedded messages should also be clear.
+ Assert.assertFalse(message.getExtension(optionalGroupExtensionLite ).hasA());
+ Assert.assertFalse(message.getExtension(optionalNestedMessageExtensionLite ).hasBb());
+ Assert.assertFalse(message.getExtension(optionalForeignMessageExtensionLite).hasC());
+ Assert.assertFalse(message.getExtension(optionalImportMessageExtensionLite ).hasD());
+
+ assertEqualsExactType(0, message.getExtension(optionalGroupExtensionLite ).getA());
+ assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtensionLite ).getBb());
+ assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtensionLite).getC());
+ assertEqualsExactType(0, message.getExtension(optionalImportMessageExtensionLite ).getD());
+
+ // Enums without defaults are set to the first value in the enum.
+ assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO,
+ message.getExtension(optionalNestedEnumExtensionLite ));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO,
+ message.getExtension(optionalForeignEnumExtensionLite));
+ assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO,
+ message.getExtension(optionalImportEnumExtensionLite));
+
+ assertEqualsExactType("", message.getExtension(optionalStringPieceExtensionLite));
+ assertEqualsExactType("", message.getExtension(optionalCordExtensionLite));
+
+ // Repeated fields are empty.
+ Assert.assertEquals(0, message.getExtensionCount(repeatedInt32ExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedInt64ExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedUint32ExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedUint64ExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSint32ExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSint64ExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32ExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64ExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32ExtensionLite));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64ExtensionLite));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtensionLite ));
+
+ Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtensionLite));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtensionLite ));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtensionLite ));
+
+ Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtensionLite));
+ Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtensionLite));
+
+ // hasBlah() should also be false for all default fields.
+ Assert.assertFalse(message.hasExtension(defaultInt32ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultInt64ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultUint32ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultUint64ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultSint32ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultSint64ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultFixed32ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultFixed64ExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultSfixed32ExtensionLite));
+ Assert.assertFalse(message.hasExtension(defaultSfixed64ExtensionLite));
+ Assert.assertFalse(message.hasExtension(defaultFloatExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultDoubleExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultBoolExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultStringExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultBytesExtensionLite ));
+
+ Assert.assertFalse(message.hasExtension(defaultNestedEnumExtensionLite ));
+ Assert.assertFalse(message.hasExtension(defaultForeignEnumExtensionLite));
+ Assert.assertFalse(message.hasExtension(defaultImportEnumExtensionLite ));
+
+ Assert.assertFalse(message.hasExtension(defaultStringPieceExtensionLite));
+ Assert.assertFalse(message.hasExtension(defaultCordExtensionLite));
+
+ // Fields with defaults have their default values (duh).
+ assertEqualsExactType( 41 , message.getExtension(defaultInt32ExtensionLite ));
+ assertEqualsExactType( 42L , message.getExtension(defaultInt64ExtensionLite ));
+ assertEqualsExactType( 43 , message.getExtension(defaultUint32ExtensionLite ));
+ assertEqualsExactType( 44L , message.getExtension(defaultUint64ExtensionLite ));
+ assertEqualsExactType(-45 , message.getExtension(defaultSint32ExtensionLite ));
+ assertEqualsExactType( 46L , message.getExtension(defaultSint64ExtensionLite ));
+ assertEqualsExactType( 47 , message.getExtension(defaultFixed32ExtensionLite ));
+ assertEqualsExactType( 48L , message.getExtension(defaultFixed64ExtensionLite ));
+ assertEqualsExactType( 49 , message.getExtension(defaultSfixed32ExtensionLite));
+ assertEqualsExactType(-50L , message.getExtension(defaultSfixed64ExtensionLite));
+ assertEqualsExactType( 51.5F , message.getExtension(defaultFloatExtensionLite ));
+ assertEqualsExactType( 52e3D , message.getExtension(defaultDoubleExtensionLite ));
+ assertEqualsExactType(true , message.getExtension(defaultBoolExtensionLite ));
+ assertEqualsExactType("hello", message.getExtension(defaultStringExtensionLite ));
+ assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtensionLite));
+
+ assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR,
+ message.getExtension(defaultNestedEnumExtensionLite ));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR,
+ message.getExtension(defaultForeignEnumExtensionLite));
+ assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR,
+ message.getExtension(defaultImportEnumExtensionLite));
+
+ assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtensionLite));
+ assertEqualsExactType("123", message.getExtension(defaultCordExtensionLite));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all extensions of
+ * {@code message} are set to the values assigned by {@code setAllExtensions}
+ * followed by {@code modifyRepeatedExtensions}.
+ */
+ public static void assertRepeatedExtensionsModified(
+ TestAllExtensionsLiteOrBuilder message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedInt64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedUint64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSint64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32ExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64ExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtensionLite ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite ));
+
+ Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtensionLite));
+
+ assertEqualsExactType(201 , message.getExtension(repeatedInt32ExtensionLite , 0));
+ assertEqualsExactType(202L , message.getExtension(repeatedInt64ExtensionLite , 0));
+ assertEqualsExactType(203 , message.getExtension(repeatedUint32ExtensionLite , 0));
+ assertEqualsExactType(204L , message.getExtension(repeatedUint64ExtensionLite , 0));
+ assertEqualsExactType(205 , message.getExtension(repeatedSint32ExtensionLite , 0));
+ assertEqualsExactType(206L , message.getExtension(repeatedSint64ExtensionLite , 0));
+ assertEqualsExactType(207 , message.getExtension(repeatedFixed32ExtensionLite , 0));
+ assertEqualsExactType(208L , message.getExtension(repeatedFixed64ExtensionLite , 0));
+ assertEqualsExactType(209 , message.getExtension(repeatedSfixed32ExtensionLite, 0));
+ assertEqualsExactType(210L , message.getExtension(repeatedSfixed64ExtensionLite, 0));
+ assertEqualsExactType(211F , message.getExtension(repeatedFloatExtensionLite , 0));
+ assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtensionLite , 0));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite , 0));
+ assertEqualsExactType("215", message.getExtension(repeatedStringExtensionLite , 0));
+ assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtensionLite, 0));
+
+ assertEqualsExactType(217, message.getExtension(repeatedGroupExtensionLite ,0).getA());
+ assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite ,0).getBb());
+ assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite,0).getC());
+ assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite ,0).getD());
+
+ assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR,
+ message.getExtension(repeatedNestedEnumExtensionLite, 0));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR,
+ message.getExtension(repeatedForeignEnumExtensionLite, 0));
+ assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR,
+ message.getExtension(repeatedImportEnumExtensionLite, 0));
+
+ assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtensionLite, 0));
+ assertEqualsExactType("225", message.getExtension(repeatedCordExtensionLite, 0));
+
+ // Actually verify the second (modified) elements now.
+ assertEqualsExactType(501 , message.getExtension(repeatedInt32ExtensionLite , 1));
+ assertEqualsExactType(502L , message.getExtension(repeatedInt64ExtensionLite , 1));
+ assertEqualsExactType(503 , message.getExtension(repeatedUint32ExtensionLite , 1));
+ assertEqualsExactType(504L , message.getExtension(repeatedUint64ExtensionLite , 1));
+ assertEqualsExactType(505 , message.getExtension(repeatedSint32ExtensionLite , 1));
+ assertEqualsExactType(506L , message.getExtension(repeatedSint64ExtensionLite , 1));
+ assertEqualsExactType(507 , message.getExtension(repeatedFixed32ExtensionLite , 1));
+ assertEqualsExactType(508L , message.getExtension(repeatedFixed64ExtensionLite , 1));
+ assertEqualsExactType(509 , message.getExtension(repeatedSfixed32ExtensionLite, 1));
+ assertEqualsExactType(510L , message.getExtension(repeatedSfixed64ExtensionLite, 1));
+ assertEqualsExactType(511F , message.getExtension(repeatedFloatExtensionLite , 1));
+ assertEqualsExactType(512D , message.getExtension(repeatedDoubleExtensionLite , 1));
+ assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite , 1));
+ assertEqualsExactType("515", message.getExtension(repeatedStringExtensionLite , 1));
+ assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtensionLite, 1));
+
+ assertEqualsExactType(517, message.getExtension(repeatedGroupExtensionLite ,1).getA());
+ assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtensionLite ,1).getBb());
+ assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtensionLite,1).getC());
+ assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtensionLite ,1).getD());
+
+ assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO,
+ message.getExtension(repeatedNestedEnumExtensionLite, 1));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO,
+ message.getExtension(repeatedForeignEnumExtensionLite, 1));
+ assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO,
+ message.getExtension(repeatedImportEnumExtensionLite, 1));
+
+ assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtensionLite, 1));
+ assertEqualsExactType("525", message.getExtension(repeatedCordExtensionLite, 1));
+ }
+
+ public static void setPackedExtensions(TestPackedExtensionsLite.Builder message) {
+ message.addExtension(packedInt32ExtensionLite , 601);
+ message.addExtension(packedInt64ExtensionLite , 602L);
+ message.addExtension(packedUint32ExtensionLite , 603);
+ message.addExtension(packedUint64ExtensionLite , 604L);
+ message.addExtension(packedSint32ExtensionLite , 605);
+ message.addExtension(packedSint64ExtensionLite , 606L);
+ message.addExtension(packedFixed32ExtensionLite , 607);
+ message.addExtension(packedFixed64ExtensionLite , 608L);
+ message.addExtension(packedSfixed32ExtensionLite, 609);
+ message.addExtension(packedSfixed64ExtensionLite, 610L);
+ message.addExtension(packedFloatExtensionLite , 611F);
+ message.addExtension(packedDoubleExtensionLite , 612D);
+ message.addExtension(packedBoolExtensionLite , true);
+ message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
+ // Add a second one of each field.
+ message.addExtension(packedInt32ExtensionLite , 701);
+ message.addExtension(packedInt64ExtensionLite , 702L);
+ message.addExtension(packedUint32ExtensionLite , 703);
+ message.addExtension(packedUint64ExtensionLite , 704L);
+ message.addExtension(packedSint32ExtensionLite , 705);
+ message.addExtension(packedSint64ExtensionLite , 706L);
+ message.addExtension(packedFixed32ExtensionLite , 707);
+ message.addExtension(packedFixed64ExtensionLite , 708L);
+ message.addExtension(packedSfixed32ExtensionLite, 709);
+ message.addExtension(packedSfixed64ExtensionLite, 710L);
+ message.addExtension(packedFloatExtensionLite , 711F);
+ message.addExtension(packedDoubleExtensionLite , 712D);
+ message.addExtension(packedBoolExtensionLite , false);
+ message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+ }
+
+ public static void assertPackedExtensionsSet(TestPackedExtensionsLite message) {
+ Assert.assertEquals(2, message.getExtensionCount(packedInt32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedInt64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedUint32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedUint64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSint32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSint64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedFixed32ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedFixed64ExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedSfixed32ExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(packedSfixed64ExtensionLite));
+ Assert.assertEquals(2, message.getExtensionCount(packedFloatExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedBoolExtensionLite ));
+ Assert.assertEquals(2, message.getExtensionCount(packedEnumExtensionLite));
+ assertEqualsExactType(601 , message.getExtension(packedInt32ExtensionLite , 0));
+ assertEqualsExactType(602L , message.getExtension(packedInt64ExtensionLite , 0));
+ assertEqualsExactType(603 , message.getExtension(packedUint32ExtensionLite , 0));
+ assertEqualsExactType(604L , message.getExtension(packedUint64ExtensionLite , 0));
+ assertEqualsExactType(605 , message.getExtension(packedSint32ExtensionLite , 0));
+ assertEqualsExactType(606L , message.getExtension(packedSint64ExtensionLite , 0));
+ assertEqualsExactType(607 , message.getExtension(packedFixed32ExtensionLite , 0));
+ assertEqualsExactType(608L , message.getExtension(packedFixed64ExtensionLite , 0));
+ assertEqualsExactType(609 , message.getExtension(packedSfixed32ExtensionLite, 0));
+ assertEqualsExactType(610L , message.getExtension(packedSfixed64ExtensionLite, 0));
+ assertEqualsExactType(611F , message.getExtension(packedFloatExtensionLite , 0));
+ assertEqualsExactType(612D , message.getExtension(packedDoubleExtensionLite , 0));
+ assertEqualsExactType(true , message.getExtension(packedBoolExtensionLite , 0));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR,
+ message.getExtension(packedEnumExtensionLite, 0));
+ assertEqualsExactType(701 , message.getExtension(packedInt32ExtensionLite , 1));
+ assertEqualsExactType(702L , message.getExtension(packedInt64ExtensionLite , 1));
+ assertEqualsExactType(703 , message.getExtension(packedUint32ExtensionLite , 1));
+ assertEqualsExactType(704L , message.getExtension(packedUint64ExtensionLite , 1));
+ assertEqualsExactType(705 , message.getExtension(packedSint32ExtensionLite , 1));
+ assertEqualsExactType(706L , message.getExtension(packedSint64ExtensionLite , 1));
+ assertEqualsExactType(707 , message.getExtension(packedFixed32ExtensionLite , 1));
+ assertEqualsExactType(708L , message.getExtension(packedFixed64ExtensionLite , 1));
+ assertEqualsExactType(709 , message.getExtension(packedSfixed32ExtensionLite, 1));
+ assertEqualsExactType(710L , message.getExtension(packedSfixed64ExtensionLite, 1));
+ assertEqualsExactType(711F , message.getExtension(packedFloatExtensionLite , 1));
+ assertEqualsExactType(712D , message.getExtension(packedDoubleExtensionLite , 1));
+ assertEqualsExactType(false, message.getExtension(packedBoolExtensionLite , 1));
+ assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ,
+ message.getExtension(packedEnumExtensionLite, 1));
+ }
+
+ // =================================================================
+
+ /**
+ * Performs the same things that the methods of {@code TestUtil} do, but
+ * via the reflection interface. This is its own class because it needs
+ * to know what descriptor to use.
+ */
+ public static class ReflectionTester {
+ private final Descriptors.Descriptor baseDescriptor;
+ private final ExtensionRegistry extensionRegistry;
+
+ private final Descriptors.FileDescriptor file;
+ private final Descriptors.FileDescriptor importFile;
+
+ private final Descriptors.Descriptor optionalGroup;
+ private final Descriptors.Descriptor repeatedGroup;
+ private final Descriptors.Descriptor nestedMessage;
+ private final Descriptors.Descriptor foreignMessage;
+ private final Descriptors.Descriptor importMessage;
+
+ private final Descriptors.FieldDescriptor groupA;
+ private final Descriptors.FieldDescriptor repeatedGroupA;
+ private final Descriptors.FieldDescriptor nestedB;
+ private final Descriptors.FieldDescriptor foreignC;
+ private final Descriptors.FieldDescriptor importD;
+
+ private final Descriptors.EnumDescriptor nestedEnum;
+ private final Descriptors.EnumDescriptor foreignEnum;
+ private final Descriptors.EnumDescriptor importEnum;
+
+ private final Descriptors.EnumValueDescriptor nestedFoo;
+ private final Descriptors.EnumValueDescriptor nestedBar;
+ private final Descriptors.EnumValueDescriptor nestedBaz;
+ private final Descriptors.EnumValueDescriptor foreignFoo;
+ private final Descriptors.EnumValueDescriptor foreignBar;
+ private final Descriptors.EnumValueDescriptor foreignBaz;
+ private final Descriptors.EnumValueDescriptor importFoo;
+ private final Descriptors.EnumValueDescriptor importBar;
+ private final Descriptors.EnumValueDescriptor importBaz;
+
+ /**
+ * Construct a {@code ReflectionTester} that will expect messages using
+ * the given descriptor.
+ *
+ * Normally {@code baseDescriptor} should be a descriptor for the type
+ * {@code TestAllTypes}, defined in
+ * {@code google/protobuf/unittest.proto}. However, if
+ * {@code extensionRegistry} is non-null, then {@code baseDescriptor} should
+ * be for {@code TestAllExtensions} instead, and instead of reading and
+ * writing normal fields, the tester will read and write extensions.
+ * All of {@code TestAllExtensions}' extensions must be registered in the
+ * registry.
+ */
+ public ReflectionTester(Descriptors.Descriptor baseDescriptor,
+ ExtensionRegistry extensionRegistry) {
+ this.baseDescriptor = baseDescriptor;
+ this.extensionRegistry = extensionRegistry;
+
+ this.file = baseDescriptor.getFile();
+ Assert.assertEquals(1, file.getDependencies().size());
+ this.importFile = file.getDependencies().get(0);
+
+ Descriptors.Descriptor testAllTypes;
+ if (baseDescriptor.getName() == "TestAllTypes") {
+ testAllTypes = baseDescriptor;
+ } else {
+ testAllTypes = file.findMessageTypeByName("TestAllTypes");
+ Assert.assertNotNull(testAllTypes);
+ }
+
+ if (extensionRegistry == null) {
+ // Use testAllTypes, rather than baseDescriptor, to allow
+ // initialization using TestPackedTypes descriptors. These objects
+ // won't be used by the methods for packed fields.
+ this.optionalGroup =
+ testAllTypes.findNestedTypeByName("OptionalGroup");
+ this.repeatedGroup =
+ testAllTypes.findNestedTypeByName("RepeatedGroup");
+ } else {
+ this.optionalGroup =
+ file.findMessageTypeByName("OptionalGroup_extension");
+ this.repeatedGroup =
+ file.findMessageTypeByName("RepeatedGroup_extension");
+ }
+ this.nestedMessage = testAllTypes.findNestedTypeByName("NestedMessage");
+ this.foreignMessage = file.findMessageTypeByName("ForeignMessage");
+ this.importMessage = importFile.findMessageTypeByName("ImportMessage");
+
+ this.nestedEnum = testAllTypes.findEnumTypeByName("NestedEnum");
+ this.foreignEnum = file.findEnumTypeByName("ForeignEnum");
+ this.importEnum = importFile.findEnumTypeByName("ImportEnum");
+
+ Assert.assertNotNull(optionalGroup );
+ Assert.assertNotNull(repeatedGroup );
+ Assert.assertNotNull(nestedMessage );
+ Assert.assertNotNull(foreignMessage);
+ Assert.assertNotNull(importMessage );
+ Assert.assertNotNull(nestedEnum );
+ Assert.assertNotNull(foreignEnum );
+ Assert.assertNotNull(importEnum );
+
+ this.nestedB = nestedMessage .findFieldByName("bb");
+ this.foreignC = foreignMessage.findFieldByName("c");
+ this.importD = importMessage .findFieldByName("d");
+ this.nestedFoo = nestedEnum.findValueByName("FOO");
+ this.nestedBar = nestedEnum.findValueByName("BAR");
+ this.nestedBaz = nestedEnum.findValueByName("BAZ");
+ this.foreignFoo = foreignEnum.findValueByName("FOREIGN_FOO");
+ this.foreignBar = foreignEnum.findValueByName("FOREIGN_BAR");
+ this.foreignBaz = foreignEnum.findValueByName("FOREIGN_BAZ");
+ this.importFoo = importEnum.findValueByName("IMPORT_FOO");
+ this.importBar = importEnum.findValueByName("IMPORT_BAR");
+ this.importBaz = importEnum.findValueByName("IMPORT_BAZ");
+
+ this.groupA = optionalGroup.findFieldByName("a");
+ this.repeatedGroupA = repeatedGroup.findFieldByName("a");
+
+ Assert.assertNotNull(groupA );
+ Assert.assertNotNull(repeatedGroupA);
+ Assert.assertNotNull(nestedB );
+ Assert.assertNotNull(foreignC );
+ Assert.assertNotNull(importD );
+ Assert.assertNotNull(nestedFoo );
+ Assert.assertNotNull(nestedBar );
+ Assert.assertNotNull(nestedBaz );
+ Assert.assertNotNull(foreignFoo );
+ Assert.assertNotNull(foreignBar );
+ Assert.assertNotNull(foreignBaz );
+ Assert.assertNotNull(importFoo );
+ Assert.assertNotNull(importBar );
+ Assert.assertNotNull(importBaz );
+ }
+
+ /**
+ * Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+ */
+ private Descriptors.FieldDescriptor f(String name) {
+ Descriptors.FieldDescriptor result;
+ if (extensionRegistry == null) {
+ result = baseDescriptor.findFieldByName(name);
+ } else {
+ result = file.findExtensionByName(name + "_extension");
+ }
+ Assert.assertNotNull(result);
+ return result;
+ }
+
+ /**
+ * Calls {@code parent.newBuilderForField()} or uses the
+ * {@code ExtensionRegistry} to find an appropriate builder, depending
+ * on what type is being tested.
+ */
+ private Message.Builder newBuilderForField(
+ Message.Builder parent, Descriptors.FieldDescriptor field) {
+ if (extensionRegistry == null) {
+ return parent.newBuilderForField(field);
+ } else {
+ ExtensionRegistry.ExtensionInfo extension =
+ extensionRegistry.findExtensionByNumber(field.getContainingType(),
+ field.getNumber());
+ Assert.assertNotNull(extension);
+ Assert.assertNotNull(extension.defaultInstance);
+ return extension.defaultInstance.newBuilderForType();
+ }
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Set every field of {@code message} to the values expected by
+ * {@code assertAllFieldsSet()}, using the {@link Message.Builder}
+ * reflection interface.
+ */
+ void setAllFieldsViaReflection(Message.Builder message) {
+ message.setField(f("optional_int32" ), 101 );
+ message.setField(f("optional_int64" ), 102L);
+ message.setField(f("optional_uint32" ), 103 );
+ message.setField(f("optional_uint64" ), 104L);
+ message.setField(f("optional_sint32" ), 105 );
+ message.setField(f("optional_sint64" ), 106L);
+ message.setField(f("optional_fixed32" ), 107 );
+ message.setField(f("optional_fixed64" ), 108L);
+ message.setField(f("optional_sfixed32"), 109 );
+ message.setField(f("optional_sfixed64"), 110L);
+ message.setField(f("optional_float" ), 111F);
+ message.setField(f("optional_double" ), 112D);
+ message.setField(f("optional_bool" ), true);
+ message.setField(f("optional_string" ), "115");
+ message.setField(f("optional_bytes" ), toBytes("116"));
+
+ message.setField(f("optionalgroup"),
+ newBuilderForField(message, f("optionalgroup"))
+ .setField(groupA, 117).build());
+ message.setField(f("optional_nested_message"),
+ newBuilderForField(message, f("optional_nested_message"))
+ .setField(nestedB, 118).build());
+ message.setField(f("optional_foreign_message"),
+ newBuilderForField(message, f("optional_foreign_message"))
+ .setField(foreignC, 119).build());
+ message.setField(f("optional_import_message"),
+ newBuilderForField(message, f("optional_import_message"))
+ .setField(importD, 120).build());
+
+ message.setField(f("optional_nested_enum" ), nestedBaz);
+ message.setField(f("optional_foreign_enum"), foreignBaz);
+ message.setField(f("optional_import_enum" ), importBaz);
+
+ message.setField(f("optional_string_piece" ), "124");
+ message.setField(f("optional_cord" ), "125");
+
+ // -----------------------------------------------------------------
+
+ message.addRepeatedField(f("repeated_int32" ), 201 );
+ message.addRepeatedField(f("repeated_int64" ), 202L);
+ message.addRepeatedField(f("repeated_uint32" ), 203 );
+ message.addRepeatedField(f("repeated_uint64" ), 204L);
+ message.addRepeatedField(f("repeated_sint32" ), 205 );
+ message.addRepeatedField(f("repeated_sint64" ), 206L);
+ message.addRepeatedField(f("repeated_fixed32" ), 207 );
+ message.addRepeatedField(f("repeated_fixed64" ), 208L);
+ message.addRepeatedField(f("repeated_sfixed32"), 209 );
+ message.addRepeatedField(f("repeated_sfixed64"), 210L);
+ message.addRepeatedField(f("repeated_float" ), 211F);
+ message.addRepeatedField(f("repeated_double" ), 212D);
+ message.addRepeatedField(f("repeated_bool" ), true);
+ message.addRepeatedField(f("repeated_string" ), "215");
+ message.addRepeatedField(f("repeated_bytes" ), toBytes("216"));
+
+ message.addRepeatedField(f("repeatedgroup"),
+ newBuilderForField(message, f("repeatedgroup"))
+ .setField(repeatedGroupA, 217).build());
+ message.addRepeatedField(f("repeated_nested_message"),
+ newBuilderForField(message, f("repeated_nested_message"))
+ .setField(nestedB, 218).build());
+ message.addRepeatedField(f("repeated_foreign_message"),
+ newBuilderForField(message, f("repeated_foreign_message"))
+ .setField(foreignC, 219).build());
+ message.addRepeatedField(f("repeated_import_message"),
+ newBuilderForField(message, f("repeated_import_message"))
+ .setField(importD, 220).build());
+
+ message.addRepeatedField(f("repeated_nested_enum" ), nestedBar);
+ message.addRepeatedField(f("repeated_foreign_enum"), foreignBar);
+ message.addRepeatedField(f("repeated_import_enum" ), importBar);
+
+ message.addRepeatedField(f("repeated_string_piece" ), "224");
+ message.addRepeatedField(f("repeated_cord" ), "225");
+
+ // Add a second one of each field.
+ message.addRepeatedField(f("repeated_int32" ), 301 );
+ message.addRepeatedField(f("repeated_int64" ), 302L);
+ message.addRepeatedField(f("repeated_uint32" ), 303 );
+ message.addRepeatedField(f("repeated_uint64" ), 304L);
+ message.addRepeatedField(f("repeated_sint32" ), 305 );
+ message.addRepeatedField(f("repeated_sint64" ), 306L);
+ message.addRepeatedField(f("repeated_fixed32" ), 307 );
+ message.addRepeatedField(f("repeated_fixed64" ), 308L);
+ message.addRepeatedField(f("repeated_sfixed32"), 309 );
+ message.addRepeatedField(f("repeated_sfixed64"), 310L);
+ message.addRepeatedField(f("repeated_float" ), 311F);
+ message.addRepeatedField(f("repeated_double" ), 312D);
+ message.addRepeatedField(f("repeated_bool" ), false);
+ message.addRepeatedField(f("repeated_string" ), "315");
+ message.addRepeatedField(f("repeated_bytes" ), toBytes("316"));
+
+ message.addRepeatedField(f("repeatedgroup"),
+ newBuilderForField(message, f("repeatedgroup"))
+ .setField(repeatedGroupA, 317).build());
+ message.addRepeatedField(f("repeated_nested_message"),
+ newBuilderForField(message, f("repeated_nested_message"))
+ .setField(nestedB, 318).build());
+ message.addRepeatedField(f("repeated_foreign_message"),
+ newBuilderForField(message, f("repeated_foreign_message"))
+ .setField(foreignC, 319).build());
+ message.addRepeatedField(f("repeated_import_message"),
+ newBuilderForField(message, f("repeated_import_message"))
+ .setField(importD, 320).build());
+
+ message.addRepeatedField(f("repeated_nested_enum" ), nestedBaz);
+ message.addRepeatedField(f("repeated_foreign_enum"), foreignBaz);
+ message.addRepeatedField(f("repeated_import_enum" ), importBaz);
+
+ message.addRepeatedField(f("repeated_string_piece" ), "324");
+ message.addRepeatedField(f("repeated_cord" ), "325");
+
+ // -----------------------------------------------------------------
+
+ message.setField(f("default_int32" ), 401 );
+ message.setField(f("default_int64" ), 402L);
+ message.setField(f("default_uint32" ), 403 );
+ message.setField(f("default_uint64" ), 404L);
+ message.setField(f("default_sint32" ), 405 );
+ message.setField(f("default_sint64" ), 406L);
+ message.setField(f("default_fixed32" ), 407 );
+ message.setField(f("default_fixed64" ), 408L);
+ message.setField(f("default_sfixed32"), 409 );
+ message.setField(f("default_sfixed64"), 410L);
+ message.setField(f("default_float" ), 411F);
+ message.setField(f("default_double" ), 412D);
+ message.setField(f("default_bool" ), false);
+ message.setField(f("default_string" ), "415");
+ message.setField(f("default_bytes" ), toBytes("416"));
+
+ message.setField(f("default_nested_enum" ), nestedFoo);
+ message.setField(f("default_foreign_enum"), foreignFoo);
+ message.setField(f("default_import_enum" ), importFoo);
+
+ message.setField(f("default_string_piece" ), "424");
+ message.setField(f("default_cord" ), "425");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Modify the repeated fields of {@code message} to contain the values
+ * expected by {@code assertRepeatedFieldsModified()}, using the
+ * {@link Message.Builder} reflection interface.
+ */
+ void modifyRepeatedFieldsViaReflection(Message.Builder message) {
+ message.setRepeatedField(f("repeated_int32" ), 1, 501 );
+ message.setRepeatedField(f("repeated_int64" ), 1, 502L);
+ message.setRepeatedField(f("repeated_uint32" ), 1, 503 );
+ message.setRepeatedField(f("repeated_uint64" ), 1, 504L);
+ message.setRepeatedField(f("repeated_sint32" ), 1, 505 );
+ message.setRepeatedField(f("repeated_sint64" ), 1, 506L);
+ message.setRepeatedField(f("repeated_fixed32" ), 1, 507 );
+ message.setRepeatedField(f("repeated_fixed64" ), 1, 508L);
+ message.setRepeatedField(f("repeated_sfixed32"), 1, 509 );
+ message.setRepeatedField(f("repeated_sfixed64"), 1, 510L);
+ message.setRepeatedField(f("repeated_float" ), 1, 511F);
+ message.setRepeatedField(f("repeated_double" ), 1, 512D);
+ message.setRepeatedField(f("repeated_bool" ), 1, true);
+ message.setRepeatedField(f("repeated_string" ), 1, "515");
+ message.setRepeatedField(f("repeated_bytes" ), 1, toBytes("516"));
+
+ message.setRepeatedField(f("repeatedgroup"), 1,
+ newBuilderForField(message, f("repeatedgroup"))
+ .setField(repeatedGroupA, 517).build());
+ message.setRepeatedField(f("repeated_nested_message"), 1,
+ newBuilderForField(message, f("repeated_nested_message"))
+ .setField(nestedB, 518).build());
+ message.setRepeatedField(f("repeated_foreign_message"), 1,
+ newBuilderForField(message, f("repeated_foreign_message"))
+ .setField(foreignC, 519).build());
+ message.setRepeatedField(f("repeated_import_message"), 1,
+ newBuilderForField(message, f("repeated_import_message"))
+ .setField(importD, 520).build());
+
+ message.setRepeatedField(f("repeated_nested_enum" ), 1, nestedFoo);
+ message.setRepeatedField(f("repeated_foreign_enum"), 1, foreignFoo);
+ message.setRepeatedField(f("repeated_import_enum" ), 1, importFoo);
+
+ message.setRepeatedField(f("repeated_string_piece"), 1, "524");
+ message.setRepeatedField(f("repeated_cord"), 1, "525");
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are set to the values assigned by {@code setAllFields},
+ * using the {@link Message} reflection interface.
+ */
+ public void assertAllFieldsSetViaReflection(MessageOrBuilder message) {
+ Assert.assertTrue(message.hasField(f("optional_int32" )));
+ Assert.assertTrue(message.hasField(f("optional_int64" )));
+ Assert.assertTrue(message.hasField(f("optional_uint32" )));
+ Assert.assertTrue(message.hasField(f("optional_uint64" )));
+ Assert.assertTrue(message.hasField(f("optional_sint32" )));
+ Assert.assertTrue(message.hasField(f("optional_sint64" )));
+ Assert.assertTrue(message.hasField(f("optional_fixed32" )));
+ Assert.assertTrue(message.hasField(f("optional_fixed64" )));
+ Assert.assertTrue(message.hasField(f("optional_sfixed32")));
+ Assert.assertTrue(message.hasField(f("optional_sfixed64")));
+ Assert.assertTrue(message.hasField(f("optional_float" )));
+ Assert.assertTrue(message.hasField(f("optional_double" )));
+ Assert.assertTrue(message.hasField(f("optional_bool" )));
+ Assert.assertTrue(message.hasField(f("optional_string" )));
+ Assert.assertTrue(message.hasField(f("optional_bytes" )));
+
+ Assert.assertTrue(message.hasField(f("optionalgroup" )));
+ Assert.assertTrue(message.hasField(f("optional_nested_message" )));
+ Assert.assertTrue(message.hasField(f("optional_foreign_message")));
+ Assert.assertTrue(message.hasField(f("optional_import_message" )));
+
+ Assert.assertTrue(
+ ((Message)message.getField(f("optionalgroup"))).hasField(groupA));
+ Assert.assertTrue(
+ ((Message)message.getField(f("optional_nested_message")))
+ .hasField(nestedB));
+ Assert.assertTrue(
+ ((Message)message.getField(f("optional_foreign_message")))
+ .hasField(foreignC));
+ Assert.assertTrue(
+ ((Message)message.getField(f("optional_import_message")))
+ .hasField(importD));
+
+ Assert.assertTrue(message.hasField(f("optional_nested_enum" )));
+ Assert.assertTrue(message.hasField(f("optional_foreign_enum")));
+ Assert.assertTrue(message.hasField(f("optional_import_enum" )));
+
+ Assert.assertTrue(message.hasField(f("optional_string_piece")));
+ Assert.assertTrue(message.hasField(f("optional_cord")));
+
+ Assert.assertEquals(101 , message.getField(f("optional_int32" )));
+ Assert.assertEquals(102L , message.getField(f("optional_int64" )));
+ Assert.assertEquals(103 , message.getField(f("optional_uint32" )));
+ Assert.assertEquals(104L , message.getField(f("optional_uint64" )));
+ Assert.assertEquals(105 , message.getField(f("optional_sint32" )));
+ Assert.assertEquals(106L , message.getField(f("optional_sint64" )));
+ Assert.assertEquals(107 , message.getField(f("optional_fixed32" )));
+ Assert.assertEquals(108L , message.getField(f("optional_fixed64" )));
+ Assert.assertEquals(109 , message.getField(f("optional_sfixed32")));
+ Assert.assertEquals(110L , message.getField(f("optional_sfixed64")));
+ Assert.assertEquals(111F , message.getField(f("optional_float" )));
+ Assert.assertEquals(112D , message.getField(f("optional_double" )));
+ Assert.assertEquals(true , message.getField(f("optional_bool" )));
+ Assert.assertEquals("115", message.getField(f("optional_string" )));
+ Assert.assertEquals(toBytes("116"), message.getField(f("optional_bytes")));
+
+ Assert.assertEquals(117,
+ ((Message)message.getField(f("optionalgroup"))).getField(groupA));
+ Assert.assertEquals(118,
+ ((Message)message.getField(f("optional_nested_message")))
+ .getField(nestedB));
+ Assert.assertEquals(119,
+ ((Message)message.getField(f("optional_foreign_message")))
+ .getField(foreignC));
+ Assert.assertEquals(120,
+ ((Message)message.getField(f("optional_import_message")))
+ .getField(importD));
+
+ Assert.assertEquals( nestedBaz, message.getField(f("optional_nested_enum" )));
+ Assert.assertEquals(foreignBaz, message.getField(f("optional_foreign_enum")));
+ Assert.assertEquals( importBaz, message.getField(f("optional_import_enum" )));
+
+ Assert.assertEquals("124", message.getField(f("optional_string_piece")));
+ Assert.assertEquals("125", message.getField(f("optional_cord")));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_float" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_double" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bool" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bytes" )));
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeatedgroup" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_enum" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_enum" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_enum" )));
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string_piece")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_cord")));
+
+ Assert.assertEquals(201 , message.getRepeatedField(f("repeated_int32" ), 0));
+ Assert.assertEquals(202L , message.getRepeatedField(f("repeated_int64" ), 0));
+ Assert.assertEquals(203 , message.getRepeatedField(f("repeated_uint32" ), 0));
+ Assert.assertEquals(204L , message.getRepeatedField(f("repeated_uint64" ), 0));
+ Assert.assertEquals(205 , message.getRepeatedField(f("repeated_sint32" ), 0));
+ Assert.assertEquals(206L , message.getRepeatedField(f("repeated_sint64" ), 0));
+ Assert.assertEquals(207 , message.getRepeatedField(f("repeated_fixed32" ), 0));
+ Assert.assertEquals(208L , message.getRepeatedField(f("repeated_fixed64" ), 0));
+ Assert.assertEquals(209 , message.getRepeatedField(f("repeated_sfixed32"), 0));
+ Assert.assertEquals(210L , message.getRepeatedField(f("repeated_sfixed64"), 0));
+ Assert.assertEquals(211F , message.getRepeatedField(f("repeated_float" ), 0));
+ Assert.assertEquals(212D , message.getRepeatedField(f("repeated_double" ), 0));
+ Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 0));
+ Assert.assertEquals("215", message.getRepeatedField(f("repeated_string" ), 0));
+ Assert.assertEquals(toBytes("216"), message.getRepeatedField(f("repeated_bytes"), 0));
+
+ Assert.assertEquals(217,
+ ((Message)message.getRepeatedField(f("repeatedgroup"), 0))
+ .getField(repeatedGroupA));
+ Assert.assertEquals(218,
+ ((Message)message.getRepeatedField(f("repeated_nested_message"), 0))
+ .getField(nestedB));
+ Assert.assertEquals(219,
+ ((Message)message.getRepeatedField(f("repeated_foreign_message"), 0))
+ .getField(foreignC));
+ Assert.assertEquals(220,
+ ((Message)message.getRepeatedField(f("repeated_import_message"), 0))
+ .getField(importD));
+
+ Assert.assertEquals( nestedBar, message.getRepeatedField(f("repeated_nested_enum" ),0));
+ Assert.assertEquals(foreignBar, message.getRepeatedField(f("repeated_foreign_enum"),0));
+ Assert.assertEquals( importBar, message.getRepeatedField(f("repeated_import_enum" ),0));
+
+ Assert.assertEquals("224", message.getRepeatedField(f("repeated_string_piece"), 0));
+ Assert.assertEquals("225", message.getRepeatedField(f("repeated_cord"), 0));
+
+ Assert.assertEquals(301 , message.getRepeatedField(f("repeated_int32" ), 1));
+ Assert.assertEquals(302L , message.getRepeatedField(f("repeated_int64" ), 1));
+ Assert.assertEquals(303 , message.getRepeatedField(f("repeated_uint32" ), 1));
+ Assert.assertEquals(304L , message.getRepeatedField(f("repeated_uint64" ), 1));
+ Assert.assertEquals(305 , message.getRepeatedField(f("repeated_sint32" ), 1));
+ Assert.assertEquals(306L , message.getRepeatedField(f("repeated_sint64" ), 1));
+ Assert.assertEquals(307 , message.getRepeatedField(f("repeated_fixed32" ), 1));
+ Assert.assertEquals(308L , message.getRepeatedField(f("repeated_fixed64" ), 1));
+ Assert.assertEquals(309 , message.getRepeatedField(f("repeated_sfixed32"), 1));
+ Assert.assertEquals(310L , message.getRepeatedField(f("repeated_sfixed64"), 1));
+ Assert.assertEquals(311F , message.getRepeatedField(f("repeated_float" ), 1));
+ Assert.assertEquals(312D , message.getRepeatedField(f("repeated_double" ), 1));
+ Assert.assertEquals(false, message.getRepeatedField(f("repeated_bool" ), 1));
+ Assert.assertEquals("315", message.getRepeatedField(f("repeated_string" ), 1));
+ Assert.assertEquals(toBytes("316"), message.getRepeatedField(f("repeated_bytes"), 1));
+
+ Assert.assertEquals(317,
+ ((Message)message.getRepeatedField(f("repeatedgroup"), 1))
+ .getField(repeatedGroupA));
+ Assert.assertEquals(318,
+ ((Message)message.getRepeatedField(f("repeated_nested_message"), 1))
+ .getField(nestedB));
+ Assert.assertEquals(319,
+ ((Message)message.getRepeatedField(f("repeated_foreign_message"), 1))
+ .getField(foreignC));
+ Assert.assertEquals(320,
+ ((Message)message.getRepeatedField(f("repeated_import_message"), 1))
+ .getField(importD));
+
+ Assert.assertEquals( nestedBaz, message.getRepeatedField(f("repeated_nested_enum" ),1));
+ Assert.assertEquals(foreignBaz, message.getRepeatedField(f("repeated_foreign_enum"),1));
+ Assert.assertEquals( importBaz, message.getRepeatedField(f("repeated_import_enum" ),1));
+
+ Assert.assertEquals("324", message.getRepeatedField(f("repeated_string_piece"), 1));
+ Assert.assertEquals("325", message.getRepeatedField(f("repeated_cord"), 1));
+
+ // -----------------------------------------------------------------
+
+ Assert.assertTrue(message.hasField(f("default_int32" )));
+ Assert.assertTrue(message.hasField(f("default_int64" )));
+ Assert.assertTrue(message.hasField(f("default_uint32" )));
+ Assert.assertTrue(message.hasField(f("default_uint64" )));
+ Assert.assertTrue(message.hasField(f("default_sint32" )));
+ Assert.assertTrue(message.hasField(f("default_sint64" )));
+ Assert.assertTrue(message.hasField(f("default_fixed32" )));
+ Assert.assertTrue(message.hasField(f("default_fixed64" )));
+ Assert.assertTrue(message.hasField(f("default_sfixed32")));
+ Assert.assertTrue(message.hasField(f("default_sfixed64")));
+ Assert.assertTrue(message.hasField(f("default_float" )));
+ Assert.assertTrue(message.hasField(f("default_double" )));
+ Assert.assertTrue(message.hasField(f("default_bool" )));
+ Assert.assertTrue(message.hasField(f("default_string" )));
+ Assert.assertTrue(message.hasField(f("default_bytes" )));
+
+ Assert.assertTrue(message.hasField(f("default_nested_enum" )));
+ Assert.assertTrue(message.hasField(f("default_foreign_enum")));
+ Assert.assertTrue(message.hasField(f("default_import_enum" )));
+
+ Assert.assertTrue(message.hasField(f("default_string_piece")));
+ Assert.assertTrue(message.hasField(f("default_cord")));
+
+ Assert.assertEquals(401 , message.getField(f("default_int32" )));
+ Assert.assertEquals(402L , message.getField(f("default_int64" )));
+ Assert.assertEquals(403 , message.getField(f("default_uint32" )));
+ Assert.assertEquals(404L , message.getField(f("default_uint64" )));
+ Assert.assertEquals(405 , message.getField(f("default_sint32" )));
+ Assert.assertEquals(406L , message.getField(f("default_sint64" )));
+ Assert.assertEquals(407 , message.getField(f("default_fixed32" )));
+ Assert.assertEquals(408L , message.getField(f("default_fixed64" )));
+ Assert.assertEquals(409 , message.getField(f("default_sfixed32")));
+ Assert.assertEquals(410L , message.getField(f("default_sfixed64")));
+ Assert.assertEquals(411F , message.getField(f("default_float" )));
+ Assert.assertEquals(412D , message.getField(f("default_double" )));
+ Assert.assertEquals(false, message.getField(f("default_bool" )));
+ Assert.assertEquals("415", message.getField(f("default_string" )));
+ Assert.assertEquals(toBytes("416"), message.getField(f("default_bytes")));
+
+ Assert.assertEquals( nestedFoo, message.getField(f("default_nested_enum" )));
+ Assert.assertEquals(foreignFoo, message.getField(f("default_foreign_enum")));
+ Assert.assertEquals( importFoo, message.getField(f("default_import_enum" )));
+
+ Assert.assertEquals("424", message.getField(f("default_string_piece")));
+ Assert.assertEquals("425", message.getField(f("default_cord")));
+ }
+
+ // -------------------------------------------------------------------
+
+ /**
+ * Assert (using {@code junit.framework.Assert}} that all fields of
+ * {@code message} are cleared, and that getting the fields returns their
+ * default values, using the {@link Message} reflection interface.
+ */
+ public void assertClearViaReflection(MessageOrBuilder message) {
+ // has_blah() should initially be false for all optional fields.
+ Assert.assertFalse(message.hasField(f("optional_int32" )));
+ Assert.assertFalse(message.hasField(f("optional_int64" )));
+ Assert.assertFalse(message.hasField(f("optional_uint32" )));
+ Assert.assertFalse(message.hasField(f("optional_uint64" )));
+ Assert.assertFalse(message.hasField(f("optional_sint32" )));
+ Assert.assertFalse(message.hasField(f("optional_sint64" )));
+ Assert.assertFalse(message.hasField(f("optional_fixed32" )));
+ Assert.assertFalse(message.hasField(f("optional_fixed64" )));
+ Assert.assertFalse(message.hasField(f("optional_sfixed32")));
+ Assert.assertFalse(message.hasField(f("optional_sfixed64")));
+ Assert.assertFalse(message.hasField(f("optional_float" )));
+ Assert.assertFalse(message.hasField(f("optional_double" )));
+ Assert.assertFalse(message.hasField(f("optional_bool" )));
+ Assert.assertFalse(message.hasField(f("optional_string" )));
+ Assert.assertFalse(message.hasField(f("optional_bytes" )));
+
+ Assert.assertFalse(message.hasField(f("optionalgroup" )));
+ Assert.assertFalse(message.hasField(f("optional_nested_message" )));
+ Assert.assertFalse(message.hasField(f("optional_foreign_message")));
+ Assert.assertFalse(message.hasField(f("optional_import_message" )));
+
+ Assert.assertFalse(message.hasField(f("optional_nested_enum" )));
+ Assert.assertFalse(message.hasField(f("optional_foreign_enum")));
+ Assert.assertFalse(message.hasField(f("optional_import_enum" )));
+
+ Assert.assertFalse(message.hasField(f("optional_string_piece")));
+ Assert.assertFalse(message.hasField(f("optional_cord")));
+
+ // Optional fields without defaults are set to zero or something like it.
+ Assert.assertEquals(0 , message.getField(f("optional_int32" )));
+ Assert.assertEquals(0L , message.getField(f("optional_int64" )));
+ Assert.assertEquals(0 , message.getField(f("optional_uint32" )));
+ Assert.assertEquals(0L , message.getField(f("optional_uint64" )));
+ Assert.assertEquals(0 , message.getField(f("optional_sint32" )));
+ Assert.assertEquals(0L , message.getField(f("optional_sint64" )));
+ Assert.assertEquals(0 , message.getField(f("optional_fixed32" )));
+ Assert.assertEquals(0L , message.getField(f("optional_fixed64" )));
+ Assert.assertEquals(0 , message.getField(f("optional_sfixed32")));
+ Assert.assertEquals(0L , message.getField(f("optional_sfixed64")));
+ Assert.assertEquals(0F , message.getField(f("optional_float" )));
+ Assert.assertEquals(0D , message.getField(f("optional_double" )));
+ Assert.assertEquals(false, message.getField(f("optional_bool" )));
+ Assert.assertEquals("" , message.getField(f("optional_string" )));
+ Assert.assertEquals(ByteString.EMPTY, message.getField(f("optional_bytes")));
+
+ // Embedded messages should also be clear.
+ Assert.assertFalse(
+ ((Message)message.getField(f("optionalgroup"))).hasField(groupA));
+ Assert.assertFalse(
+ ((Message)message.getField(f("optional_nested_message")))
+ .hasField(nestedB));
+ Assert.assertFalse(
+ ((Message)message.getField(f("optional_foreign_message")))
+ .hasField(foreignC));
+ Assert.assertFalse(
+ ((Message)message.getField(f("optional_import_message")))
+ .hasField(importD));
+
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optionalgroup"))).getField(groupA));
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optional_nested_message")))
+ .getField(nestedB));
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optional_foreign_message")))
+ .getField(foreignC));
+ Assert.assertEquals(0,
+ ((Message)message.getField(f("optional_import_message")))
+ .getField(importD));
+
+ // Enums without defaults are set to the first value in the enum.
+ Assert.assertEquals( nestedFoo, message.getField(f("optional_nested_enum" )));
+ Assert.assertEquals(foreignFoo, message.getField(f("optional_foreign_enum")));
+ Assert.assertEquals( importFoo, message.getField(f("optional_import_enum" )));
+
+ Assert.assertEquals("", message.getField(f("optional_string_piece")));
+ Assert.assertEquals("", message.getField(f("optional_cord")));
+
+ // Repeated fields are empty.
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_int32" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_int64" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_uint32" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_uint64" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sint32" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sint64" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_float" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_double" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_bool" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_string" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_bytes" )));
+
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeatedgroup" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_import_message" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_nested_enum" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_foreign_enum" )));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_import_enum" )));
+
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_string_piece")));
+ Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_cord")));
+
+ // has_blah() should also be false for all default fields.
+ Assert.assertFalse(message.hasField(f("default_int32" )));
+ Assert.assertFalse(message.hasField(f("default_int64" )));
+ Assert.assertFalse(message.hasField(f("default_uint32" )));
+ Assert.assertFalse(message.hasField(f("default_uint64" )));
+ Assert.assertFalse(message.hasField(f("default_sint32" )));
+ Assert.assertFalse(message.hasField(f("default_sint64" )));
+ Assert.assertFalse(message.hasField(f("default_fixed32" )));
+ Assert.assertFalse(message.hasField(f("default_fixed64" )));
+ Assert.assertFalse(message.hasField(f("default_sfixed32")));
+ Assert.assertFalse(message.hasField(f("default_sfixed64")));
+ Assert.assertFalse(message.hasField(f("default_float" )));
+ Assert.assertFalse(message.hasField(f("default_double" )));
+ Assert.assertFalse(message.hasField(f("default_bool" )));
+ Assert.assertFalse(message.hasField(f("default_string" )));
+ Assert.assertFalse(message.hasField(f("default_bytes" )));
+
+ Assert.assertFalse(message.hasField(f("default_nested_enum" )));
+ Assert.assertFalse(message.hasField(f("default_foreign_enum")));
+ Assert.assertFalse(message.hasField(f("default_import_enum" )));
+
+ Assert.assertFalse(message.hasField(f("default_string_piece" )));
+ Assert.assertFalse(message.hasField(f("default_cord" )));
+
+ // Fields with defaults have their default values (duh).
+ Assert.assertEquals( 41 , message.getField(f("default_int32" )));
+ Assert.assertEquals( 42L , message.getField(f("default_int64" )));
+ Assert.assertEquals( 43 , message.getField(f("default_uint32" )));
+ Assert.assertEquals( 44L , message.getField(f("default_uint64" )));
+ Assert.assertEquals(-45 , message.getField(f("default_sint32" )));
+ Assert.assertEquals( 46L , message.getField(f("default_sint64" )));
+ Assert.assertEquals( 47 , message.getField(f("default_fixed32" )));
+ Assert.assertEquals( 48L , message.getField(f("default_fixed64" )));
+ Assert.assertEquals( 49 , message.getField(f("default_sfixed32")));
+ Assert.assertEquals(-50L , message.getField(f("default_sfixed64")));
+ Assert.assertEquals( 51.5F , message.getField(f("default_float" )));
+ Assert.assertEquals( 52e3D , message.getField(f("default_double" )));
+ Assert.assertEquals(true , message.getField(f("default_bool" )));
+ Assert.assertEquals("hello", message.getField(f("default_string" )));
+ Assert.assertEquals(toBytes("world"), message.getField(f("default_bytes")));
+
+ Assert.assertEquals( nestedBar, message.getField(f("default_nested_enum" )));
+ Assert.assertEquals(foreignBar, message.getField(f("default_foreign_enum")));
+ Assert.assertEquals( importBar, message.getField(f("default_import_enum" )));
+
+ Assert.assertEquals("abc", message.getField(f("default_string_piece")));
+ Assert.assertEquals("123", message.getField(f("default_cord")));
+ }
+
+
+ // ---------------------------------------------------------------
+
+ public void assertRepeatedFieldsModifiedViaReflection(
+ MessageOrBuilder message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_float" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_double" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bool" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bytes" )));
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeatedgroup" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_message" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_enum" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_enum" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_enum" )));
+
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string_piece")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_cord")));
+
+ Assert.assertEquals(201 , message.getRepeatedField(f("repeated_int32" ), 0));
+ Assert.assertEquals(202L , message.getRepeatedField(f("repeated_int64" ), 0));
+ Assert.assertEquals(203 , message.getRepeatedField(f("repeated_uint32" ), 0));
+ Assert.assertEquals(204L , message.getRepeatedField(f("repeated_uint64" ), 0));
+ Assert.assertEquals(205 , message.getRepeatedField(f("repeated_sint32" ), 0));
+ Assert.assertEquals(206L , message.getRepeatedField(f("repeated_sint64" ), 0));
+ Assert.assertEquals(207 , message.getRepeatedField(f("repeated_fixed32" ), 0));
+ Assert.assertEquals(208L , message.getRepeatedField(f("repeated_fixed64" ), 0));
+ Assert.assertEquals(209 , message.getRepeatedField(f("repeated_sfixed32"), 0));
+ Assert.assertEquals(210L , message.getRepeatedField(f("repeated_sfixed64"), 0));
+ Assert.assertEquals(211F , message.getRepeatedField(f("repeated_float" ), 0));
+ Assert.assertEquals(212D , message.getRepeatedField(f("repeated_double" ), 0));
+ Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 0));
+ Assert.assertEquals("215", message.getRepeatedField(f("repeated_string" ), 0));
+ Assert.assertEquals(toBytes("216"), message.getRepeatedField(f("repeated_bytes"), 0));
+
+ Assert.assertEquals(217,
+ ((Message)message.getRepeatedField(f("repeatedgroup"), 0))
+ .getField(repeatedGroupA));
+ Assert.assertEquals(218,
+ ((Message)message.getRepeatedField(f("repeated_nested_message"), 0))
+ .getField(nestedB));
+ Assert.assertEquals(219,
+ ((Message)message.getRepeatedField(f("repeated_foreign_message"), 0))
+ .getField(foreignC));
+ Assert.assertEquals(220,
+ ((Message)message.getRepeatedField(f("repeated_import_message"), 0))
+ .getField(importD));
+
+ Assert.assertEquals( nestedBar, message.getRepeatedField(f("repeated_nested_enum" ),0));
+ Assert.assertEquals(foreignBar, message.getRepeatedField(f("repeated_foreign_enum"),0));
+ Assert.assertEquals( importBar, message.getRepeatedField(f("repeated_import_enum" ),0));
+
+ Assert.assertEquals("224", message.getRepeatedField(f("repeated_string_piece"), 0));
+ Assert.assertEquals("225", message.getRepeatedField(f("repeated_cord"), 0));
+
+ Assert.assertEquals(501 , message.getRepeatedField(f("repeated_int32" ), 1));
+ Assert.assertEquals(502L , message.getRepeatedField(f("repeated_int64" ), 1));
+ Assert.assertEquals(503 , message.getRepeatedField(f("repeated_uint32" ), 1));
+ Assert.assertEquals(504L , message.getRepeatedField(f("repeated_uint64" ), 1));
+ Assert.assertEquals(505 , message.getRepeatedField(f("repeated_sint32" ), 1));
+ Assert.assertEquals(506L , message.getRepeatedField(f("repeated_sint64" ), 1));
+ Assert.assertEquals(507 , message.getRepeatedField(f("repeated_fixed32" ), 1));
+ Assert.assertEquals(508L , message.getRepeatedField(f("repeated_fixed64" ), 1));
+ Assert.assertEquals(509 , message.getRepeatedField(f("repeated_sfixed32"), 1));
+ Assert.assertEquals(510L , message.getRepeatedField(f("repeated_sfixed64"), 1));
+ Assert.assertEquals(511F , message.getRepeatedField(f("repeated_float" ), 1));
+ Assert.assertEquals(512D , message.getRepeatedField(f("repeated_double" ), 1));
+ Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool" ), 1));
+ Assert.assertEquals("515", message.getRepeatedField(f("repeated_string" ), 1));
+ Assert.assertEquals(toBytes("516"), message.getRepeatedField(f("repeated_bytes"), 1));
+
+ Assert.assertEquals(517,
+ ((Message)message.getRepeatedField(f("repeatedgroup"), 1))
+ .getField(repeatedGroupA));
+ Assert.assertEquals(518,
+ ((Message)message.getRepeatedField(f("repeated_nested_message"), 1))
+ .getField(nestedB));
+ Assert.assertEquals(519,
+ ((Message)message.getRepeatedField(f("repeated_foreign_message"), 1))
+ .getField(foreignC));
+ Assert.assertEquals(520,
+ ((Message)message.getRepeatedField(f("repeated_import_message"), 1))
+ .getField(importD));
+
+ Assert.assertEquals( nestedFoo, message.getRepeatedField(f("repeated_nested_enum" ),1));
+ Assert.assertEquals(foreignFoo, message.getRepeatedField(f("repeated_foreign_enum"),1));
+ Assert.assertEquals( importFoo, message.getRepeatedField(f("repeated_import_enum" ),1));
+
+ Assert.assertEquals("524", message.getRepeatedField(f("repeated_string_piece"), 1));
+ Assert.assertEquals("525", message.getRepeatedField(f("repeated_cord"), 1));
+ }
+
+ public void setPackedFieldsViaReflection(Message.Builder message) {
+ message.addRepeatedField(f("packed_int32" ), 601 );
+ message.addRepeatedField(f("packed_int64" ), 602L);
+ message.addRepeatedField(f("packed_uint32" ), 603 );
+ message.addRepeatedField(f("packed_uint64" ), 604L);
+ message.addRepeatedField(f("packed_sint32" ), 605 );
+ message.addRepeatedField(f("packed_sint64" ), 606L);
+ message.addRepeatedField(f("packed_fixed32" ), 607 );
+ message.addRepeatedField(f("packed_fixed64" ), 608L);
+ message.addRepeatedField(f("packed_sfixed32"), 609 );
+ message.addRepeatedField(f("packed_sfixed64"), 610L);
+ message.addRepeatedField(f("packed_float" ), 611F);
+ message.addRepeatedField(f("packed_double" ), 612D);
+ message.addRepeatedField(f("packed_bool" ), true);
+ message.addRepeatedField(f("packed_enum" ), foreignBar);
+ // Add a second one of each field.
+ message.addRepeatedField(f("packed_int32" ), 701 );
+ message.addRepeatedField(f("packed_int64" ), 702L);
+ message.addRepeatedField(f("packed_uint32" ), 703 );
+ message.addRepeatedField(f("packed_uint64" ), 704L);
+ message.addRepeatedField(f("packed_sint32" ), 705 );
+ message.addRepeatedField(f("packed_sint64" ), 706L);
+ message.addRepeatedField(f("packed_fixed32" ), 707 );
+ message.addRepeatedField(f("packed_fixed64" ), 708L);
+ message.addRepeatedField(f("packed_sfixed32"), 709 );
+ message.addRepeatedField(f("packed_sfixed64"), 710L);
+ message.addRepeatedField(f("packed_float" ), 711F);
+ message.addRepeatedField(f("packed_double" ), 712D);
+ message.addRepeatedField(f("packed_bool" ), false);
+ message.addRepeatedField(f("packed_enum" ), foreignBaz);
+ }
+
+ public void assertPackedFieldsSetViaReflection(MessageOrBuilder message) {
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed32" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed64" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed32")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed64")));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_float" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_double" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_bool" )));
+ Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_enum" )));
+ Assert.assertEquals(601 , message.getRepeatedField(f("packed_int32" ), 0));
+ Assert.assertEquals(602L , message.getRepeatedField(f("packed_int64" ), 0));
+ Assert.assertEquals(603 , message.getRepeatedField(f("packed_uint32" ), 0));
+ Assert.assertEquals(604L , message.getRepeatedField(f("packed_uint64" ), 0));
+ Assert.assertEquals(605 , message.getRepeatedField(f("packed_sint32" ), 0));
+ Assert.assertEquals(606L , message.getRepeatedField(f("packed_sint64" ), 0));
+ Assert.assertEquals(607 , message.getRepeatedField(f("packed_fixed32" ), 0));
+ Assert.assertEquals(608L , message.getRepeatedField(f("packed_fixed64" ), 0));
+ Assert.assertEquals(609 , message.getRepeatedField(f("packed_sfixed32"), 0));
+ Assert.assertEquals(610L , message.getRepeatedField(f("packed_sfixed64"), 0));
+ Assert.assertEquals(611F , message.getRepeatedField(f("packed_float" ), 0));
+ Assert.assertEquals(612D , message.getRepeatedField(f("packed_double" ), 0));
+ Assert.assertEquals(true , message.getRepeatedField(f("packed_bool" ), 0));
+ Assert.assertEquals(foreignBar, message.getRepeatedField(f("packed_enum" ),0));
+ Assert.assertEquals(701 , message.getRepeatedField(f("packed_int32" ), 1));
+ Assert.assertEquals(702L , message.getRepeatedField(f("packed_int64" ), 1));
+ Assert.assertEquals(703 , message.getRepeatedField(f("packed_uint32" ), 1));
+ Assert.assertEquals(704L , message.getRepeatedField(f("packed_uint64" ), 1));
+ Assert.assertEquals(705 , message.getRepeatedField(f("packed_sint32" ), 1));
+ Assert.assertEquals(706L , message.getRepeatedField(f("packed_sint64" ), 1));
+ Assert.assertEquals(707 , message.getRepeatedField(f("packed_fixed32" ), 1));
+ Assert.assertEquals(708L , message.getRepeatedField(f("packed_fixed64" ), 1));
+ Assert.assertEquals(709 , message.getRepeatedField(f("packed_sfixed32"), 1));
+ Assert.assertEquals(710L , message.getRepeatedField(f("packed_sfixed64"), 1));
+ Assert.assertEquals(711F , message.getRepeatedField(f("packed_float" ), 1));
+ Assert.assertEquals(712D , message.getRepeatedField(f("packed_double" ), 1));
+ Assert.assertEquals(false, message.getRepeatedField(f("packed_bool" ), 1));
+ Assert.assertEquals(foreignBaz, message.getRepeatedField(f("packed_enum" ),1));
+ }
+
+ /**
+ * Verifies that the reflection setters for the given.Builder object throw a
+ * NullPointerException if they are passed a null value. Uses Assert to throw an
+ * appropriate assertion failure, if the condition is not verified.
+ */
+ public void assertReflectionSettersRejectNull(Message.Builder builder)
+ throws Exception {
+ try {
+ builder.setField(f("optional_string"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_bytes"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_enum"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_message"),
+ (TestAllTypes.NestedMessage) null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.setField(f("optional_nested_message"),
+ (TestAllTypes.NestedMessage.Builder) null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ try {
+ builder.addRepeatedField(f("repeated_string"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_bytes"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_nested_enum"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ try {
+ builder.addRepeatedField(f("repeated_nested_message"), null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+
+ /**
+ * Verifies that the reflection repeated setters for the given Builder object throw a
+ * NullPointerException if they are passed a null value. Uses Assert to throw an appropriate
+ * assertion failure, if the condition is not verified.
+ */
+ public void assertReflectionRepeatedSettersRejectNull(Message.Builder builder)
+ throws Exception {
+ builder.addRepeatedField(f("repeated_string"), "one");
+ try {
+ builder.setRepeatedField(f("repeated_string"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(f("repeated_bytes"), toBytes("one"));
+ try {
+ builder.setRepeatedField(f("repeated_bytes"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(f("repeated_nested_enum"), nestedBaz);
+ try {
+ builder.setRepeatedField(f("repeated_nested_enum"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+
+ builder.addRepeatedField(
+ f("repeated_nested_message"),
+ TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+ try {
+ builder.setRepeatedField(f("repeated_nested_message"), 0, null);
+ Assert.fail("Exception was not thrown");
+ } catch (NullPointerException e) {
+ // We expect this exception.
+ }
+ }
+ }
+
+ /**
+ * @param filePath The path relative to
+ * {@link #getTestDataDir}.
+ */
+ public static String readTextFromFile(String filePath) {
+ return readBytesFromFile(filePath).toStringUtf8();
+ }
+
+ private static File getTestDataDir() {
+ // Search each parent directory looking for "src/google/protobuf".
+ File ancestor = new File(".");
+ try {
+ ancestor = ancestor.getCanonicalFile();
+ } catch (IOException e) {
+ throw new RuntimeException(
+ "Couldn't get canonical name of working directory.", e);
+ }
+ while (ancestor != null && ancestor.exists()) {
+ if (new File(ancestor, "src/google/protobuf").exists()) {
+ return new File(ancestor, "src/google/protobuf/testdata");
+ }
+ ancestor = ancestor.getParentFile();
+ }
+
+ throw new RuntimeException(
+ "Could not find golden files. This test must be run from within the " +
+ "protobuf source package so that it can read test data files from the " +
+ "C++ source tree.");
+ }
+
+ /**
+ * @param filename The path relative to
+ * {@link #getTestDataDir}.
+ */
+ public static ByteString readBytesFromFile(String filename) {
+ File fullPath = new File(getTestDataDir(), filename);
+ try {
+ RandomAccessFile file = new RandomAccessFile(fullPath, "r");
+ byte[] content = new byte[(int) file.length()];
+ file.readFully(content);
+ return ByteString.copyFrom(content);
+ } catch (IOException e) {
+ // Throw a RuntimeException here so that we can call this function from
+ // static initializers.
+ throw new IllegalArgumentException(
+ "Couldn't read file: " + fullPath.getPath(), e);
+ }
+ }
+
+ /**
+ * Get the bytes of the "golden message". This is a serialized TestAllTypes
+ * with all fields set as they would be by
+ * {@link #setAllFields(TestAllTypes.Builder)}, but it is loaded from a file
+ * on disk rather than generated dynamically. The file is actually generated
+ * by C++ code, so testing against it verifies compatibility with C++.
+ */
+ public static ByteString getGoldenMessage() {
+ if (goldenMessage == null) {
+ goldenMessage = readBytesFromFile("golden_message");
+ }
+ return goldenMessage;
+ }
+ private static ByteString goldenMessage = null;
+
+ /**
+ * Get the bytes of the "golden packed fields message". This is a serialized
+ * TestPackedTypes with all fields set as they would be by
+ * {@link #setPackedFields(TestPackedTypes.Builder)}, but it is loaded from a
+ * file on disk rather than generated dynamically. The file is actually
+ * generated by C++ code, so testing against it verifies compatibility with
+ * C++.
+ */
+ public static ByteString getGoldenPackedFieldsMessage() {
+ if (goldenPackedFieldsMessage == null) {
+ goldenPackedFieldsMessage =
+ readBytesFromFile("golden_packed_fields_message");
+ }
+ return goldenPackedFieldsMessage;
+ }
+ private static ByteString goldenPackedFieldsMessage = null;
+
+ /**
+ * Mock implementation of {@link GeneratedMessage.BuilderParent} for testing.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+ public static class MockBuilderParent
+ implements GeneratedMessage.BuilderParent {
+
+ private int invalidations;
+
+ //@Override (Java 1.6 override semantics, but we must support 1.5)
+ public void markDirty() {
+ invalidations++;
+ }
+
+ public int getInvalidationCount() {
+ return invalidations;
+ }
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TextFormatTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TextFormatTest.java
new file mode 100644
index 0000000..47690d1
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -0,0 +1,752 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import protobuf_unittest.UnittestMset.TestMessageSet;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
+import protobuf_unittest.UnittestProto.OneString;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+
+import junit.framework.TestCase;
+
+import java.io.StringReader;
+
+/**
+ * Test case for {@link TextFormat}.
+ *
+ * TODO(wenboz): ExtensionTest and rest of text_format_unittest.cc.
+ *
+ * @author wenboz@google.com (Wenbo Zhu)
+ */
+public class TextFormatTest extends TestCase {
+
+ // A basic string with different escapable characters for testing.
+ private final static String kEscapeTestString =
+ "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
+ + "slashes \\";
+
+ // A representation of the above string with all the characters escaped.
+ private final static String kEscapeTestStringEscaped =
+ "\\\"A string with \\' characters \\n and \\r newlines "
+ + "and \\t tabs and \\001 slashes \\\\";
+
+ private static String allFieldsSetText = TestUtil.readTextFromFile(
+ "text_format_unittest_data.txt");
+ private static String allExtensionsSetText = TestUtil.readTextFromFile(
+ "text_format_unittest_extensions_data.txt");
+
+ private static String exoticText =
+ "repeated_int32: -1\n" +
+ "repeated_int32: -2147483648\n" +
+ "repeated_int64: -1\n" +
+ "repeated_int64: -9223372036854775808\n" +
+ "repeated_uint32: 4294967295\n" +
+ "repeated_uint32: 2147483648\n" +
+ "repeated_uint64: 18446744073709551615\n" +
+ "repeated_uint64: 9223372036854775808\n" +
+ "repeated_double: 123.0\n" +
+ "repeated_double: 123.5\n" +
+ "repeated_double: 0.125\n" +
+ "repeated_double: .125\n" +
+ "repeated_double: -.125\n" +
+ "repeated_double: 1.23E17\n" +
+ "repeated_double: 1.23E+17\n" +
+ "repeated_double: -1.23e-17\n" +
+ "repeated_double: .23e+17\n" +
+ "repeated_double: -.23E17\n" +
+ "repeated_double: 1.235E22\n" +
+ "repeated_double: 1.235E-18\n" +
+ "repeated_double: 123.456789\n" +
+ "repeated_double: Infinity\n" +
+ "repeated_double: -Infinity\n" +
+ "repeated_double: NaN\n" +
+ "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" +
+ "\\341\\210\\264\"\n" +
+ "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n";
+
+ private static String canonicalExoticText =
+ exoticText.replace(": .", ": 0.").replace(": -.", ": -0.") // short-form double
+ .replace("23e", "23E").replace("E+", "E").replace("0.23E17", "2.3E16");
+
+ private String messageSetText =
+ "[protobuf_unittest.TestMessageSetExtension1] {\n" +
+ " i: 123\n" +
+ "}\n" +
+ "[protobuf_unittest.TestMessageSetExtension2] {\n" +
+ " str: \"foo\"\n" +
+ "}\n";
+
+ /** Print TestAllTypes and compare with golden file. */
+ public void testPrintMessage() throws Exception {
+ String javaText = TextFormat.printToString(TestUtil.getAllSet());
+
+ // Java likes to add a trailing ".0" to floats and doubles. C printf
+ // (with %g format) does not. Our golden files are used for both
+ // C++ and Java TextFormat classes, so we need to conform.
+ javaText = javaText.replace(".0\n", "\n");
+
+ assertEquals(allFieldsSetText, javaText);
+ }
+
+ /** Print TestAllExtensions and compare with golden file. */
+ public void testPrintExtensions() throws Exception {
+ String javaText = TextFormat.printToString(TestUtil.getAllExtensionsSet());
+
+ // Java likes to add a trailing ".0" to floats and doubles. C printf
+ // (with %g format) does not. Our golden files are used for both
+ // C++ and Java TextFormat classes, so we need to conform.
+ javaText = javaText.replace(".0\n", "\n");
+
+ assertEquals(allExtensionsSetText, javaText);
+ }
+
+ // Creates an example unknown field set.
+ private UnknownFieldSet makeUnknownFieldSet() {
+ return UnknownFieldSet.newBuilder()
+ .addField(5,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(1)
+ .addFixed32(2)
+ .addFixed64(3)
+ .addLengthDelimited(ByteString.copyFromUtf8("4"))
+ .addGroup(
+ UnknownFieldSet.newBuilder()
+ .addField(10,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(5)
+ .build())
+ .build())
+ .build())
+ .addField(8,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(1)
+ .addVarint(2)
+ .addVarint(3)
+ .build())
+ .addField(15,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(0xABCDEF1234567890L)
+ .addFixed32(0xABCD1234)
+ .addFixed64(0xABCDEF1234567890L)
+ .build())
+ .build();
+ }
+
+ public void testPrintUnknownFields() throws Exception {
+ // Test printing of unknown fields in a message.
+
+ TestEmptyMessage message =
+ TestEmptyMessage.newBuilder()
+ .setUnknownFields(makeUnknownFieldSet())
+ .build();
+
+ assertEquals(
+ "5: 1\n" +
+ "5: 0x00000002\n" +
+ "5: 0x0000000000000003\n" +
+ "5: \"4\"\n" +
+ "5 {\n" +
+ " 10: 5\n" +
+ "}\n" +
+ "8: 1\n" +
+ "8: 2\n" +
+ "8: 3\n" +
+ "15: 12379813812177893520\n" +
+ "15: 0xabcd1234\n" +
+ "15: 0xabcdef1234567890\n",
+ TextFormat.printToString(message));
+ }
+
+ public void testPrintField() throws Exception {
+ final FieldDescriptor dataField =
+ OneString.getDescriptor().findFieldByName("data");
+ assertEquals(
+ "data: \"test data\"\n",
+ TextFormat.printFieldToString(dataField, "test data"));
+
+ final FieldDescriptor optionalField =
+ TestAllTypes.getDescriptor().findFieldByName("optional_nested_message");
+ final Object value = NestedMessage.newBuilder().setBb(42).build();
+
+ assertEquals(
+ "optional_nested_message {\n bb: 42\n}\n",
+ TextFormat.printFieldToString(optionalField, value));
+ }
+
+ /**
+ * Helper to construct a ByteString from a String containing only 8-bit
+ * characters. The characters are converted directly to bytes, *not*
+ * encoded using UTF-8.
+ */
+ private ByteString bytes(String str) throws Exception {
+ return ByteString.copyFrom(str.getBytes("ISO-8859-1"));
+ }
+
+ /**
+ * Helper to construct a ByteString from a bunch of bytes. The inputs are
+ * actually ints so that I can use hex notation and not get stupid errors
+ * about precision.
+ */
+ private ByteString bytes(int... bytesAsInts) {
+ byte[] bytes = new byte[bytesAsInts.length];
+ for (int i = 0; i < bytesAsInts.length; i++) {
+ bytes[i] = (byte) bytesAsInts[i];
+ }
+ return ByteString.copyFrom(bytes);
+ }
+
+ public void testPrintExotic() throws Exception {
+ Message message = TestAllTypes.newBuilder()
+ // Signed vs. unsigned numbers.
+ .addRepeatedInt32 (-1)
+ .addRepeatedUint32(-1)
+ .addRepeatedInt64 (-1)
+ .addRepeatedUint64(-1)
+
+ .addRepeatedInt32 (1 << 31)
+ .addRepeatedUint32(1 << 31)
+ .addRepeatedInt64 (1l << 63)
+ .addRepeatedUint64(1l << 63)
+
+ // Floats of various precisions and exponents.
+ .addRepeatedDouble(123)
+ .addRepeatedDouble(123.5)
+ .addRepeatedDouble(0.125)
+ .addRepeatedDouble(.125)
+ .addRepeatedDouble(-.125)
+ .addRepeatedDouble(123e15)
+ .addRepeatedDouble(123e15)
+ .addRepeatedDouble(-1.23e-17)
+ .addRepeatedDouble(.23e17)
+ .addRepeatedDouble(-23e15)
+ .addRepeatedDouble(123.5e20)
+ .addRepeatedDouble(123.5e-20)
+ .addRepeatedDouble(123.456789)
+ .addRepeatedDouble(Double.POSITIVE_INFINITY)
+ .addRepeatedDouble(Double.NEGATIVE_INFINITY)
+ .addRepeatedDouble(Double.NaN)
+
+ // Strings and bytes that needing escaping.
+ .addRepeatedString("\0\001\007\b\f\n\r\t\013\\\'\"\u1234")
+ .addRepeatedBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe"))
+ .build();
+
+ assertEquals(canonicalExoticText, message.toString());
+ }
+
+ public void testPrintMessageSet() throws Exception {
+ TestMessageSet messageSet =
+ TestMessageSet.newBuilder()
+ .setExtension(
+ TestMessageSetExtension1.messageSetExtension,
+ TestMessageSetExtension1.newBuilder().setI(123).build())
+ .setExtension(
+ TestMessageSetExtension2.messageSetExtension,
+ TestMessageSetExtension2.newBuilder().setStr("foo").build())
+ .build();
+
+ assertEquals(messageSetText, messageSet.toString());
+ }
+
+ // =================================================================
+
+ public void testParse() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(allFieldsSetText, builder);
+ TestUtil.assertAllFieldsSet(builder.build());
+ }
+
+ public void testParseReader() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(new StringReader(allFieldsSetText), builder);
+ TestUtil.assertAllFieldsSet(builder.build());
+ }
+
+ public void testParseExtensions() throws Exception {
+ TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+ TextFormat.merge(allExtensionsSetText,
+ TestUtil.getExtensionRegistry(),
+ builder);
+ TestUtil.assertAllExtensionsSet(builder.build());
+ }
+
+ public void testParseCompatibility() throws Exception {
+ String original = "repeated_float: inf\n" +
+ "repeated_float: -inf\n" +
+ "repeated_float: nan\n" +
+ "repeated_float: inff\n" +
+ "repeated_float: -inff\n" +
+ "repeated_float: nanf\n" +
+ "repeated_float: 1.0f\n" +
+ "repeated_float: infinityf\n" +
+ "repeated_float: -Infinityf\n" +
+ "repeated_double: infinity\n" +
+ "repeated_double: -infinity\n" +
+ "repeated_double: nan\n";
+ String canonical = "repeated_float: Infinity\n" +
+ "repeated_float: -Infinity\n" +
+ "repeated_float: NaN\n" +
+ "repeated_float: Infinity\n" +
+ "repeated_float: -Infinity\n" +
+ "repeated_float: NaN\n" +
+ "repeated_float: 1.0\n" +
+ "repeated_float: Infinity\n" +
+ "repeated_float: -Infinity\n" +
+ "repeated_double: Infinity\n" +
+ "repeated_double: -Infinity\n" +
+ "repeated_double: NaN\n";
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(original, builder);
+ assertEquals(canonical, builder.build().toString());
+ }
+
+ public void testParseExotic() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(exoticText, builder);
+
+ // Too lazy to check things individually. Don't try to debug this
+ // if testPrintExotic() is failing.
+ assertEquals(canonicalExoticText, builder.build().toString());
+ }
+
+ public void testParseMessageSet() throws Exception {
+ ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+ extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+ extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
+
+ TestMessageSet.Builder builder = TestMessageSet.newBuilder();
+ TextFormat.merge(messageSetText, extensionRegistry, builder);
+ TestMessageSet messageSet = builder.build();
+
+ assertTrue(messageSet.hasExtension(
+ TestMessageSetExtension1.messageSetExtension));
+ assertEquals(123, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ assertTrue(messageSet.hasExtension(
+ TestMessageSetExtension2.messageSetExtension));
+ assertEquals("foo", messageSet.getExtension(
+ TestMessageSetExtension2.messageSetExtension).getStr());
+ }
+
+ public void testParseNumericEnum() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_nested_enum: 2", builder);
+ assertEquals(TestAllTypes.NestedEnum.BAR, builder.getOptionalNestedEnum());
+ }
+
+ public void testParseAngleBrackets() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("OptionalGroup: < a: 1 >", builder);
+ assertTrue(builder.hasOptionalGroup());
+ assertEquals(1, builder.getOptionalGroup().getA());
+ }
+
+ public void testParseComment() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(
+ "# this is a comment\n" +
+ "optional_int32: 1 # another comment\n" +
+ "optional_int64: 2\n" +
+ "# EOF comment", builder);
+ assertEquals(1, builder.getOptionalInt32());
+ assertEquals(2, builder.getOptionalInt64());
+ }
+
+ private void assertParseError(String error, String text) {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ try {
+ TextFormat.merge(text, TestUtil.getExtensionRegistry(), builder);
+ fail("Expected parse exception.");
+ } catch (TextFormat.ParseException e) {
+ assertEquals(error, e.getMessage());
+ }
+ }
+
+ public void testParseErrors() throws Exception {
+ assertParseError(
+ "1:16: Expected \":\".",
+ "optional_int32 123");
+ assertParseError(
+ "1:23: Expected identifier.",
+ "optional_nested_enum: ?");
+ assertParseError(
+ "1:18: Couldn't parse integer: Number must be positive: -1",
+ "optional_uint32: -1");
+ assertParseError(
+ "1:17: Couldn't parse integer: Number out of range for 32-bit signed " +
+ "integer: 82301481290849012385230157",
+ "optional_int32: 82301481290849012385230157");
+ assertParseError(
+ "1:16: Expected \"true\" or \"false\".",
+ "optional_bool: maybe");
+ assertParseError(
+ "1:16: Expected \"true\" or \"false\".",
+ "optional_bool: 2");
+ assertParseError(
+ "1:18: Expected string.",
+ "optional_string: 123");
+ assertParseError(
+ "1:18: String missing ending quote.",
+ "optional_string: \"ueoauaoe");
+ assertParseError(
+ "1:18: String missing ending quote.",
+ "optional_string: \"ueoauaoe\n" +
+ "optional_int32: 123");
+ assertParseError(
+ "1:18: Invalid escape sequence: '\\z'",
+ "optional_string: \"\\z\"");
+ assertParseError(
+ "1:18: String missing ending quote.",
+ "optional_string: \"ueoauaoe\n" +
+ "optional_int32: 123");
+ assertParseError(
+ "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.",
+ "[nosuchext]: 123");
+ assertParseError(
+ "1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " +
+ "not extend message type \"protobuf_unittest.TestAllTypes\".",
+ "[protobuf_unittest.optional_int32_extension]: 123");
+ assertParseError(
+ "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " +
+ "named \"nosuchfield\".",
+ "nosuchfield: 123");
+ assertParseError(
+ "1:21: Expected \">\".",
+ "OptionalGroup < a: 1");
+ assertParseError(
+ "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
+ "value named \"NO_SUCH_VALUE\".",
+ "optional_nested_enum: NO_SUCH_VALUE");
+ assertParseError(
+ "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
+ "value with number 123.",
+ "optional_nested_enum: 123");
+
+ // Delimiters must match.
+ assertParseError(
+ "1:22: Expected identifier.",
+ "OptionalGroup < a: 1 }");
+ assertParseError(
+ "1:22: Expected identifier.",
+ "OptionalGroup { a: 1 >");
+ }
+
+ // =================================================================
+
+ public void testEscape() throws Exception {
+ // Escape sequences.
+ assertEquals("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
+ TextFormat.escapeBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"")));
+ assertEquals("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
+ TextFormat.escapeText("\0\001\007\b\f\n\r\t\013\\\'\""));
+ assertEquals(bytes("\0\001\007\b\f\n\r\t\013\\\'\""),
+ TextFormat.unescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
+ assertEquals("\0\001\007\b\f\n\r\t\013\\\'\"",
+ TextFormat.unescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
+ assertEquals(kEscapeTestStringEscaped,
+ TextFormat.escapeText(kEscapeTestString));
+ assertEquals(kEscapeTestString,
+ TextFormat.unescapeText(kEscapeTestStringEscaped));
+
+ // Unicode handling.
+ assertEquals("\\341\\210\\264", TextFormat.escapeText("\u1234"));
+ assertEquals("\\341\\210\\264",
+ TextFormat.escapeBytes(bytes(0xe1, 0x88, 0xb4)));
+ assertEquals("\u1234", TextFormat.unescapeText("\\341\\210\\264"));
+ assertEquals(bytes(0xe1, 0x88, 0xb4),
+ TextFormat.unescapeBytes("\\341\\210\\264"));
+ assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4"));
+ assertEquals(bytes(0xe1, 0x88, 0xb4),
+ TextFormat.unescapeBytes("\\xe1\\x88\\xb4"));
+
+ // Handling of strings with unescaped Unicode characters > 255.
+ final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
+ ByteString zhByteString = ByteString.copyFromUtf8(zh);
+ assertEquals(zhByteString, TextFormat.unescapeBytes(zh));
+
+ // Errors.
+ try {
+ TextFormat.unescapeText("\\x");
+ fail("Should have thrown an exception.");
+ } catch (TextFormat.InvalidEscapeSequenceException e) {
+ // success
+ }
+
+ try {
+ TextFormat.unescapeText("\\z");
+ fail("Should have thrown an exception.");
+ } catch (TextFormat.InvalidEscapeSequenceException e) {
+ // success
+ }
+
+ try {
+ TextFormat.unescapeText("\\");
+ fail("Should have thrown an exception.");
+ } catch (TextFormat.InvalidEscapeSequenceException e) {
+ // success
+ }
+ }
+
+ public void testParseInteger() throws Exception {
+ assertEquals( 0, TextFormat.parseInt32( "0"));
+ assertEquals( 1, TextFormat.parseInt32( "1"));
+ assertEquals( -1, TextFormat.parseInt32( "-1"));
+ assertEquals( 12345, TextFormat.parseInt32( "12345"));
+ assertEquals( -12345, TextFormat.parseInt32( "-12345"));
+ assertEquals( 2147483647, TextFormat.parseInt32( "2147483647"));
+ assertEquals(-2147483648, TextFormat.parseInt32("-2147483648"));
+
+ assertEquals( 0, TextFormat.parseUInt32( "0"));
+ assertEquals( 1, TextFormat.parseUInt32( "1"));
+ assertEquals( 12345, TextFormat.parseUInt32( "12345"));
+ assertEquals( 2147483647, TextFormat.parseUInt32("2147483647"));
+ assertEquals((int) 2147483648L, TextFormat.parseUInt32("2147483648"));
+ assertEquals((int) 4294967295L, TextFormat.parseUInt32("4294967295"));
+
+ assertEquals( 0L, TextFormat.parseInt64( "0"));
+ assertEquals( 1L, TextFormat.parseInt64( "1"));
+ assertEquals( -1L, TextFormat.parseInt64( "-1"));
+ assertEquals( 12345L, TextFormat.parseInt64( "12345"));
+ assertEquals( -12345L, TextFormat.parseInt64( "-12345"));
+ assertEquals( 2147483647L, TextFormat.parseInt64( "2147483647"));
+ assertEquals(-2147483648L, TextFormat.parseInt64("-2147483648"));
+ assertEquals( 4294967295L, TextFormat.parseInt64( "4294967295"));
+ assertEquals( 4294967296L, TextFormat.parseInt64( "4294967296"));
+ assertEquals(9223372036854775807L,
+ TextFormat.parseInt64("9223372036854775807"));
+ assertEquals(-9223372036854775808L,
+ TextFormat.parseInt64("-9223372036854775808"));
+
+ assertEquals( 0L, TextFormat.parseUInt64( "0"));
+ assertEquals( 1L, TextFormat.parseUInt64( "1"));
+ assertEquals( 12345L, TextFormat.parseUInt64( "12345"));
+ assertEquals( 2147483647L, TextFormat.parseUInt64( "2147483647"));
+ assertEquals( 4294967295L, TextFormat.parseUInt64( "4294967295"));
+ assertEquals( 4294967296L, TextFormat.parseUInt64( "4294967296"));
+ assertEquals(9223372036854775807L,
+ TextFormat.parseUInt64("9223372036854775807"));
+ assertEquals(-9223372036854775808L,
+ TextFormat.parseUInt64("9223372036854775808"));
+ assertEquals(-1L, TextFormat.parseUInt64("18446744073709551615"));
+
+ // Hex
+ assertEquals(0x1234abcd, TextFormat.parseInt32("0x1234abcd"));
+ assertEquals(-0x1234abcd, TextFormat.parseInt32("-0x1234abcd"));
+ assertEquals(-1, TextFormat.parseUInt64("0xffffffffffffffff"));
+ assertEquals(0x7fffffffffffffffL,
+ TextFormat.parseInt64("0x7fffffffffffffff"));
+
+ // Octal
+ assertEquals(01234567, TextFormat.parseInt32("01234567"));
+
+ // Out-of-range
+ try {
+ TextFormat.parseInt32("2147483648");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+
+ try {
+ TextFormat.parseInt32("-2147483649");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+
+ try {
+ TextFormat.parseUInt32("4294967296");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+
+ try {
+ TextFormat.parseUInt32("-1");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+
+ try {
+ TextFormat.parseInt64("9223372036854775808");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+
+ try {
+ TextFormat.parseInt64("-9223372036854775809");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+
+ try {
+ TextFormat.parseUInt64("18446744073709551616");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+
+ try {
+ TextFormat.parseUInt64("-1");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+
+ // Not a number.
+ try {
+ TextFormat.parseInt32("abcd");
+ fail("Should have thrown an exception.");
+ } catch (NumberFormatException e) {
+ // success
+ }
+ }
+
+ public void testParseString() throws Exception {
+ final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_string: \"" + zh + "\"", builder);
+ assertEquals(zh, builder.getOptionalString());
+ }
+
+ public void testParseLongString() throws Exception {
+ String longText =
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890" +
+ "123456789012345678901234567890123456789012345678901234567890";
+
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_string: \"" + longText + "\"", builder);
+ assertEquals(longText, builder.getOptionalString());
+ }
+
+ public void testParseBoolean() throws Exception {
+ String goodText =
+ "repeated_bool: t repeated_bool : 0\n" +
+ "repeated_bool :f repeated_bool:1";
+ String goodTextCanonical =
+ "repeated_bool: true\n" +
+ "repeated_bool: false\n" +
+ "repeated_bool: false\n" +
+ "repeated_bool: true\n";
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge(goodText, builder);
+ assertEquals(goodTextCanonical, builder.build().toString());
+
+ try {
+ TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_bool:2", badBuilder);
+ fail("Should have thrown an exception.");
+ } catch (TextFormat.ParseException e) {
+ // success
+ }
+ try {
+ TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_bool: foo", badBuilder);
+ fail("Should have thrown an exception.");
+ } catch (TextFormat.ParseException e) {
+ // success
+ }
+ }
+
+ public void testParseAdjacentStringLiterals() throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder);
+ assertEquals("foocorgegrault", builder.getOptionalString());
+ }
+
+ public void testPrintFieldValue() throws Exception {
+ assertPrintFieldValue("\"Hello\"", "Hello", "repeated_string");
+ assertPrintFieldValue("123.0", 123f, "repeated_float");
+ assertPrintFieldValue("123.0", 123d, "repeated_double");
+ assertPrintFieldValue("123", 123, "repeated_int32");
+ assertPrintFieldValue("123", 123L, "repeated_int64");
+ assertPrintFieldValue("true", true, "repeated_bool");
+ assertPrintFieldValue("4294967295", 0xFFFFFFFF, "repeated_uint32");
+ assertPrintFieldValue("18446744073709551615", 0xFFFFFFFFFFFFFFFFL,
+ "repeated_uint64");
+ assertPrintFieldValue("\"\\001\\002\\003\"",
+ ByteString.copyFrom(new byte[] {1, 2, 3}), "repeated_bytes");
+ }
+
+ private void assertPrintFieldValue(String expect, Object value,
+ String fieldName) throws Exception {
+ TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+ StringBuilder sb = new StringBuilder();
+ TextFormat.printFieldValue(
+ TestAllTypes.getDescriptor().findFieldByName(fieldName),
+ value, sb);
+ assertEquals(expect, sb.toString());
+ }
+
+ public void testShortDebugString() {
+ assertEquals("optional_nested_message { bb: 42 } repeated_int32: 1"
+ + " repeated_uint32: 2",
+ TextFormat.shortDebugString(TestAllTypes.newBuilder()
+ .addRepeatedInt32(1)
+ .addRepeatedUint32(2)
+ .setOptionalNestedMessage(
+ NestedMessage.newBuilder().setBb(42).build())
+ .build()));
+ }
+
+ public void testShortDebugString_unknown() {
+ assertEquals("5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5 { 10: 5 }"
+ + " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:"
+ + " 0xabcdef1234567890",
+ TextFormat.shortDebugString(makeUnknownFieldSet()));
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
new file mode 100644
index 0000000..ea088b3
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
@@ -0,0 +1,437 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * Tests related to unknown field handling.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public class UnknownFieldSetTest extends TestCase {
+ public void setUp() throws Exception {
+ descriptor = TestAllTypes.getDescriptor();
+ allFields = TestUtil.getAllSet();
+ allFieldsData = allFields.toByteString();
+ emptyMessage = TestEmptyMessage.parseFrom(allFieldsData);
+ unknownFields = emptyMessage.getUnknownFields();
+ }
+
+ UnknownFieldSet.Field getField(String name) {
+ Descriptors.FieldDescriptor field = descriptor.findFieldByName(name);
+ assertNotNull(field);
+ return unknownFields.getField(field.getNumber());
+ }
+
+ // Constructs a protocol buffer which contains fields with all the same
+ // numbers as allFieldsData except that each field is some other wire
+ // type.
+ ByteString getBizarroData() throws Exception {
+ UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.newBuilder();
+
+ UnknownFieldSet.Field varintField =
+ UnknownFieldSet.Field.newBuilder().addVarint(1).build();
+ UnknownFieldSet.Field fixed32Field =
+ UnknownFieldSet.Field.newBuilder().addFixed32(1).build();
+
+ for (Map.Entry<Integer, UnknownFieldSet.Field> entry :
+ unknownFields.asMap().entrySet()) {
+ if (entry.getValue().getVarintList().isEmpty()) {
+ // Original field is not a varint, so use a varint.
+ bizarroFields.addField(entry.getKey(), varintField);
+ } else {
+ // Original field *is* a varint, so use something else.
+ bizarroFields.addField(entry.getKey(), fixed32Field);
+ }
+ }
+
+ return bizarroFields.build().toByteString();
+ }
+
+ Descriptors.Descriptor descriptor;
+ TestAllTypes allFields;
+ ByteString allFieldsData;
+
+ // An empty message that has been parsed from allFieldsData. So, it has
+ // unknown fields of every type.
+ TestEmptyMessage emptyMessage;
+ UnknownFieldSet unknownFields;
+
+ // =================================================================
+
+ public void testVarint() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_int32");
+ assertEquals(1, field.getVarintList().size());
+ assertEquals(allFields.getOptionalInt32(),
+ (long) field.getVarintList().get(0));
+ }
+
+ public void testFixed32() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_fixed32");
+ assertEquals(1, field.getFixed32List().size());
+ assertEquals(allFields.getOptionalFixed32(),
+ (int) field.getFixed32List().get(0));
+ }
+
+ public void testFixed64() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_fixed64");
+ assertEquals(1, field.getFixed64List().size());
+ assertEquals(allFields.getOptionalFixed64(),
+ (long) field.getFixed64List().get(0));
+ }
+
+ public void testLengthDelimited() throws Exception {
+ UnknownFieldSet.Field field = getField("optional_bytes");
+ assertEquals(1, field.getLengthDelimitedList().size());
+ assertEquals(allFields.getOptionalBytes(),
+ field.getLengthDelimitedList().get(0));
+ }
+
+ public void testGroup() throws Exception {
+ Descriptors.FieldDescriptor nestedFieldDescriptor =
+ TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a");
+ assertNotNull(nestedFieldDescriptor);
+
+ UnknownFieldSet.Field field = getField("optionalgroup");
+ assertEquals(1, field.getGroupList().size());
+
+ UnknownFieldSet group = field.getGroupList().get(0);
+ assertEquals(1, group.asMap().size());
+ assertTrue(group.hasField(nestedFieldDescriptor.getNumber()));
+
+ UnknownFieldSet.Field nestedField =
+ group.getField(nestedFieldDescriptor.getNumber());
+ assertEquals(1, nestedField.getVarintList().size());
+ assertEquals(allFields.getOptionalGroup().getA(),
+ (long) nestedField.getVarintList().get(0));
+ }
+
+ public void testSerialize() throws Exception {
+ // Check that serializing the UnknownFieldSet produces the original data
+ // again.
+ ByteString data = emptyMessage.toByteString();
+ assertEquals(allFieldsData, data);
+ }
+
+ public void testCopyFrom() throws Exception {
+ TestEmptyMessage message =
+ TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build();
+
+ assertEquals(emptyMessage.toString(), message.toString());
+ }
+
+ public void testMergeFrom() throws Exception {
+ TestEmptyMessage source =
+ TestEmptyMessage.newBuilder()
+ .setUnknownFields(
+ UnknownFieldSet.newBuilder()
+ .addField(2,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(2).build())
+ .addField(3,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(4).build())
+ .build())
+ .build();
+ TestEmptyMessage destination =
+ TestEmptyMessage.newBuilder()
+ .setUnknownFields(
+ UnknownFieldSet.newBuilder()
+ .addField(1,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(1).build())
+ .addField(3,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(3).build())
+ .build())
+ .mergeFrom(source)
+ .build();
+
+ assertEquals(
+ "1: 1\n" +
+ "2: 2\n" +
+ "3: 3\n" +
+ "3: 4\n",
+ destination.toString());
+ }
+
+ public void testClear() throws Exception {
+ UnknownFieldSet fields =
+ UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build();
+ assertTrue(fields.asMap().isEmpty());
+ }
+
+ public void testClearMessage() throws Exception {
+ TestEmptyMessage message =
+ TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build();
+ assertEquals(0, message.getSerializedSize());
+ }
+
+ public void testParseKnownAndUnknown() throws Exception {
+ // Test mixing known and unknown fields when parsing.
+
+ UnknownFieldSet fields =
+ UnknownFieldSet.newBuilder(unknownFields)
+ .addField(123456,
+ UnknownFieldSet.Field.newBuilder().addVarint(654321).build())
+ .build();
+
+ ByteString data = fields.toByteString();
+ TestAllTypes destination = TestAllTypes.parseFrom(data);
+
+ TestUtil.assertAllFieldsSet(destination);
+ assertEquals(1, destination.getUnknownFields().asMap().size());
+
+ UnknownFieldSet.Field field =
+ destination.getUnknownFields().getField(123456);
+ assertEquals(1, field.getVarintList().size());
+ assertEquals(654321, (long) field.getVarintList().get(0));
+ }
+
+ public void testWrongTypeTreatedAsUnknown() throws Exception {
+ // Test that fields of the wrong wire type are treated like unknown fields
+ // when parsing.
+
+ ByteString bizarroData = getBizarroData();
+ TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData);
+ TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
+
+ // All fields should have been interpreted as unknown, so the debug strings
+ // should be the same.
+ assertEquals(emptyMessage.toString(), allTypesMessage.toString());
+ }
+
+ public void testUnknownExtensions() throws Exception {
+ // Make sure fields are properly parsed to the UnknownFieldSet even when
+ // they are declared as extension numbers.
+
+ TestEmptyMessageWithExtensions message =
+ TestEmptyMessageWithExtensions.parseFrom(allFieldsData);
+
+ assertEquals(unknownFields.asMap().size(),
+ message.getUnknownFields().asMap().size());
+ assertEquals(allFieldsData, message.toByteString());
+ }
+
+ public void testWrongExtensionTypeTreatedAsUnknown() throws Exception {
+ // Test that fields of the wrong wire type are treated like unknown fields
+ // when parsing extensions.
+
+ ByteString bizarroData = getBizarroData();
+ TestAllExtensions allExtensionsMessage =
+ TestAllExtensions.parseFrom(bizarroData);
+ TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
+
+ // All fields should have been interpreted as unknown, so the debug strings
+ // should be the same.
+ assertEquals(emptyMessage.toString(),
+ allExtensionsMessage.toString());
+ }
+
+ public void testParseUnknownEnumValue() throws Exception {
+ Descriptors.FieldDescriptor singularField =
+ TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum");
+ Descriptors.FieldDescriptor repeatedField =
+ TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum");
+ assertNotNull(singularField);
+ assertNotNull(repeatedField);
+
+ ByteString data =
+ UnknownFieldSet.newBuilder()
+ .addField(singularField.getNumber(),
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(TestAllTypes.NestedEnum.BAR.getNumber())
+ .addVarint(5) // not valid
+ .build())
+ .addField(repeatedField.getNumber(),
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(TestAllTypes.NestedEnum.FOO.getNumber())
+ .addVarint(4) // not valid
+ .addVarint(TestAllTypes.NestedEnum.BAZ.getNumber())
+ .addVarint(6) // not valid
+ .build())
+ .build()
+ .toByteString();
+
+ {
+ TestAllTypes message = TestAllTypes.parseFrom(data);
+ assertEquals(TestAllTypes.NestedEnum.BAR,
+ message.getOptionalNestedEnum());
+ assertEquals(
+ Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
+ message.getRepeatedNestedEnumList());
+ assertEquals(Arrays.asList(5L),
+ message.getUnknownFields()
+ .getField(singularField.getNumber())
+ .getVarintList());
+ assertEquals(Arrays.asList(4L, 6L),
+ message.getUnknownFields()
+ .getField(repeatedField.getNumber())
+ .getVarintList());
+ }
+
+ {
+ TestAllExtensions message =
+ TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
+ assertEquals(TestAllTypes.NestedEnum.BAR,
+ message.getExtension(UnittestProto.optionalNestedEnumExtension));
+ assertEquals(
+ Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
+ message.getExtension(UnittestProto.repeatedNestedEnumExtension));
+ assertEquals(Arrays.asList(5L),
+ message.getUnknownFields()
+ .getField(singularField.getNumber())
+ .getVarintList());
+ assertEquals(Arrays.asList(4L, 6L),
+ message.getUnknownFields()
+ .getField(repeatedField.getNumber())
+ .getVarintList());
+ }
+ }
+
+ public void testLargeVarint() throws Exception {
+ ByteString data =
+ UnknownFieldSet.newBuilder()
+ .addField(1,
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(0x7FFFFFFFFFFFFFFFL)
+ .build())
+ .build()
+ .toByteString();
+ UnknownFieldSet parsed = UnknownFieldSet.parseFrom(data);
+ UnknownFieldSet.Field field = parsed.getField(1);
+ assertEquals(1, field.getVarintList().size());
+ assertEquals(0x7FFFFFFFFFFFFFFFL, (long)field.getVarintList().get(0));
+ }
+
+ public void testEqualsAndHashCode() {
+ UnknownFieldSet.Field fixed32Field =
+ UnknownFieldSet.Field.newBuilder()
+ .addFixed32(1)
+ .build();
+ UnknownFieldSet.Field fixed64Field =
+ UnknownFieldSet.Field.newBuilder()
+ .addFixed64(1)
+ .build();
+ UnknownFieldSet.Field varIntField =
+ UnknownFieldSet.Field.newBuilder()
+ .addVarint(1)
+ .build();
+ UnknownFieldSet.Field lengthDelimitedField =
+ UnknownFieldSet.Field.newBuilder()
+ .addLengthDelimited(ByteString.EMPTY)
+ .build();
+ UnknownFieldSet.Field groupField =
+ UnknownFieldSet.Field.newBuilder()
+ .addGroup(unknownFields)
+ .build();
+
+ UnknownFieldSet a =
+ UnknownFieldSet.newBuilder()
+ .addField(1, fixed32Field)
+ .build();
+ UnknownFieldSet b =
+ UnknownFieldSet.newBuilder()
+ .addField(1, fixed64Field)
+ .build();
+ UnknownFieldSet c =
+ UnknownFieldSet.newBuilder()
+ .addField(1, varIntField)
+ .build();
+ UnknownFieldSet d =
+ UnknownFieldSet.newBuilder()
+ .addField(1, lengthDelimitedField)
+ .build();
+ UnknownFieldSet e =
+ UnknownFieldSet.newBuilder()
+ .addField(1, groupField)
+ .build();
+
+ checkEqualsIsConsistent(a);
+ checkEqualsIsConsistent(b);
+ checkEqualsIsConsistent(c);
+ checkEqualsIsConsistent(d);
+ checkEqualsIsConsistent(e);
+
+ checkNotEqual(a, b);
+ checkNotEqual(a, c);
+ checkNotEqual(a, d);
+ checkNotEqual(a, e);
+ checkNotEqual(b, c);
+ checkNotEqual(b, d);
+ checkNotEqual(b, e);
+ checkNotEqual(c, d);
+ checkNotEqual(c, e);
+ checkNotEqual(d, e);
+ }
+
+ /**
+ * Asserts that the given field sets are not equal and have different
+ * hash codes.
+ *
+ * @warning It's valid for non-equal objects to have the same hash code, so
+ * this test is stricter than it needs to be. However, this should happen
+ * relatively rarely.
+ */
+ private void checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) {
+ String equalsError = String.format("%s should not be equal to %s", s1, s2);
+ assertFalse(equalsError, s1.equals(s2));
+ assertFalse(equalsError, s2.equals(s1));
+
+ assertFalse(
+ String.format("%s should have a different hash code from %s", s1, s2),
+ s1.hashCode() == s2.hashCode());
+ }
+
+ /**
+ * Asserts that the given field sets are equal and have identical hash codes.
+ */
+ private void checkEqualsIsConsistent(UnknownFieldSet set) {
+ // Object should be equal to itself.
+ assertEquals(set, set);
+
+ // Object should be equal to a copy of itself.
+ UnknownFieldSet copy = UnknownFieldSet.newBuilder(set).build();
+ assertEquals(set, copy);
+ assertEquals(copy, set);
+ assertEquals(set.hashCode(), copy.hashCode());
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
new file mode 100644
index 0000000..ed5d069
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
@@ -0,0 +1,152 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+
+/**
+ * Tests for {@link UnmodifiableLazyStringList}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class UnmodifiableLazyStringListTest extends TestCase {
+
+ private static String STRING_A = "A";
+ private static String STRING_B = "B";
+ private static String STRING_C = "C";
+
+ private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A");
+ private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B");
+ private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C");
+
+ public void testReadOnlyMethods() {
+ LazyStringArrayList rawList = createSampleList();
+ UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+ assertEquals(3, list.size());
+ assertSame(STRING_A, list.get(0));
+ assertSame(STRING_B, list.get(1));
+ assertSame(STRING_C, list.get(2));
+ assertEquals(BYTE_STRING_A, list.getByteString(0));
+ assertEquals(BYTE_STRING_B, list.getByteString(1));
+ assertEquals(BYTE_STRING_C, list.getByteString(2));
+ }
+
+ public void testModifyMethods() {
+ LazyStringArrayList rawList = createSampleList();
+ UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+ try {
+ list.remove(0);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals(3, list.size());
+
+ try {
+ list.add(STRING_B);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ assertEquals(3, list.size());
+
+ try {
+ list.set(1, STRING_B);
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+
+ public void testIterator() {
+ LazyStringArrayList rawList = createSampleList();
+ UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+ Iterator<String> iter = list.iterator();
+ int count = 0;
+ while (iter.hasNext()) {
+ iter.next();
+ count++;
+ try {
+ iter.remove();
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+ assertEquals(3, count);
+
+ }
+
+ public void testListIterator() {
+ LazyStringArrayList rawList = createSampleList();
+ UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+ ListIterator<String> iter = list.listIterator();
+ int count = 0;
+ while (iter.hasNext()) {
+ iter.next();
+ count++;
+ try {
+ iter.remove();
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ iter.set("bar");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ try {
+ iter.add("bar");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // expected
+ }
+ }
+ assertEquals(3, count);
+
+ }
+
+ private LazyStringArrayList createSampleList() {
+ LazyStringArrayList rawList = new LazyStringArrayList();
+ rawList.add(STRING_A);
+ rawList.add(STRING_B);
+ rawList.add(STRING_C);
+ return rawList;
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/WireFormatTest.java b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/WireFormatTest.java
new file mode 100644
index 0000000..5ea1dd6
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -0,0 +1,427 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestFieldOrderings;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestMset.TestMessageSet;
+import protobuf_unittest.UnittestMset.RawMessageSet;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+
+/**
+ * Tests related to parsing and serialization.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public class WireFormatTest extends TestCase {
+ public void testSerialization() throws Exception {
+ TestAllTypes message = TestUtil.getAllSet();
+
+ ByteString rawBytes = message.toByteString();
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+ TestUtil.assertAllFieldsSet(message2);
+ }
+
+ public void testSerializationPacked() throws Exception {
+ TestPackedTypes message = TestUtil.getPackedSet();
+
+ ByteString rawBytes = message.toByteString();
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
+
+ TestUtil.assertPackedFieldsSet(message2);
+ }
+
+ public void testSerializeExtensions() throws Exception {
+ // TestAllTypes and TestAllExtensions should have compatible wire formats,
+ // so if we serialize a TestAllExtensions then parse it as TestAllTypes
+ // it should work.
+
+ TestAllExtensions message = TestUtil.getAllExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+ TestUtil.assertAllFieldsSet(message2);
+ }
+
+ public void testSerializePackedExtensions() throws Exception {
+ // TestPackedTypes and TestPackedExtensions should have compatible wire
+ // formats; check that they serialize to the same string.
+ TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+
+ TestPackedTypes message2 = TestUtil.getPackedSet();
+ ByteString rawBytes2 = message2.toByteString();
+
+ assertEquals(rawBytes, rawBytes2);
+ }
+
+ public void testSerializationPackedWithoutGetSerializedSize()
+ throws Exception {
+ // Write directly to an OutputStream, without invoking getSerializedSize()
+ // This used to be a bug where the size of a packed field was incorrect,
+ // since getSerializedSize() was never invoked.
+ TestPackedTypes message = TestUtil.getPackedSet();
+
+ // Directly construct a CodedOutputStream around the actual OutputStream,
+ // in case writeTo(OutputStream output) invokes getSerializedSize();
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream);
+
+ message.writeTo(codedOutput);
+
+ codedOutput.flush();
+
+ TestPackedTypes message2 = TestPackedTypes.parseFrom(
+ outputStream.toByteArray());
+
+ TestUtil.assertPackedFieldsSet(message2);
+ }
+
+ public void testSerializeExtensionsLite() throws Exception {
+ // TestAllTypes and TestAllExtensions should have compatible wire formats,
+ // so if we serialize a TestAllExtensions then parse it as TestAllTypes
+ // it should work.
+
+ TestAllExtensionsLite message = TestUtil.getAllLiteExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+ assertEquals(rawBytes.size(), message.getSerializedSize());
+
+ TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+ TestUtil.assertAllFieldsSet(message2);
+ }
+
+ public void testSerializePackedExtensionsLite() throws Exception {
+ // TestPackedTypes and TestPackedExtensions should have compatible wire
+ // formats; check that they serialize to the same string.
+ TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+
+ TestPackedTypes message2 = TestUtil.getPackedSet();
+ ByteString rawBytes2 = message2.toByteString();
+
+ assertEquals(rawBytes, rawBytes2);
+ }
+
+ public void testParseExtensions() throws Exception {
+ // TestAllTypes and TestAllExtensions should have compatible wire formats,
+ // so if we serialize a TestAllTypes then parse it as TestAllExtensions
+ // it should work.
+
+ TestAllTypes message = TestUtil.getAllSet();
+ ByteString rawBytes = message.toByteString();
+
+ ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+ TestAllExtensions message2 =
+ TestAllExtensions.parseFrom(rawBytes, registry);
+
+ TestUtil.assertAllExtensionsSet(message2);
+ }
+
+ public void testParsePackedExtensions() throws Exception {
+ // Ensure that packed extensions can be properly parsed.
+ TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+
+ ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+ TestPackedExtensions message2 =
+ TestPackedExtensions.parseFrom(rawBytes, registry);
+
+ TestUtil.assertPackedExtensionsSet(message2);
+ }
+
+ public void testParseExtensionsLite() throws Exception {
+ // TestAllTypes and TestAllExtensions should have compatible wire formats,
+ // so if we serialize a TestAllTypes then parse it as TestAllExtensions
+ // it should work.
+
+ TestAllTypes message = TestUtil.getAllSet();
+ ByteString rawBytes = message.toByteString();
+
+ ExtensionRegistryLite registry_lite = TestUtil.getExtensionRegistryLite();
+
+ TestAllExtensionsLite message2 =
+ TestAllExtensionsLite.parseFrom(rawBytes, registry_lite);
+
+ TestUtil.assertAllExtensionsSet(message2);
+
+ // Try again using a full extension registry.
+ ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+ TestAllExtensionsLite message3 =
+ TestAllExtensionsLite.parseFrom(rawBytes, registry);
+
+ TestUtil.assertAllExtensionsSet(message3);
+ }
+
+ public void testParsePackedExtensionsLite() throws Exception {
+ // Ensure that packed extensions can be properly parsed.
+ TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+ ByteString rawBytes = message.toByteString();
+
+ ExtensionRegistryLite registry = TestUtil.getExtensionRegistryLite();
+
+ TestPackedExtensionsLite message2 =
+ TestPackedExtensionsLite.parseFrom(rawBytes, registry);
+
+ TestUtil.assertPackedExtensionsSet(message2);
+ }
+
+ public void testExtensionsSerializedSize() throws Exception {
+ assertEquals(TestUtil.getAllSet().getSerializedSize(),
+ TestUtil.getAllExtensionsSet().getSerializedSize());
+ }
+
+ public void testSerializeDelimited() throws Exception {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ TestUtil.getAllSet().writeDelimitedTo(output);
+ output.write(12);
+ TestUtil.getPackedSet().writeDelimitedTo(output);
+ output.write(34);
+
+ ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
+
+ TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input));
+ assertEquals(12, input.read());
+ TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input));
+ assertEquals(34, input.read());
+ assertEquals(-1, input.read());
+
+ // We're at EOF, so parsing again should return null.
+ assertTrue(TestAllTypes.parseDelimitedFrom(input) == null);
+ }
+
+ private void assertFieldsInOrder(ByteString data) throws Exception {
+ CodedInputStream input = data.newCodedInput();
+ int previousTag = 0;
+
+ while (true) {
+ int tag = input.readTag();
+ if (tag == 0) {
+ break;
+ }
+
+ assertTrue(tag > previousTag);
+ previousTag = tag;
+ input.skipField(tag);
+ }
+ }
+
+ public void testInterleavedFieldsAndExtensions() throws Exception {
+ // Tests that fields are written in order even when extension ranges
+ // are interleaved with field numbers.
+ ByteString data =
+ TestFieldOrderings.newBuilder()
+ .setMyInt(1)
+ .setMyString("foo")
+ .setMyFloat(1.0F)
+ .setExtension(UnittestProto.myExtensionInt, 23)
+ .setExtension(UnittestProto.myExtensionString, "bar")
+ .build().toByteString();
+ assertFieldsInOrder(data);
+
+ Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
+ ByteString dynamic_data =
+ DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
+ .setField(descriptor.findFieldByName("my_int"), 1L)
+ .setField(descriptor.findFieldByName("my_string"), "foo")
+ .setField(descriptor.findFieldByName("my_float"), 1.0F)
+ .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
+ .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
+ .build().toByteString();
+ assertFieldsInOrder(dynamic_data);
+ }
+
+ private ExtensionRegistry getTestFieldOrderingsRegistry() {
+ ExtensionRegistry result = ExtensionRegistry.newInstance();
+ result.add(UnittestProto.myExtensionInt);
+ result.add(UnittestProto.myExtensionString);
+ return result;
+ }
+
+ public void testParseMultipleExtensionRanges() throws Exception {
+ // Make sure we can parse a message that contains multiple extensions
+ // ranges.
+ TestFieldOrderings source =
+ TestFieldOrderings.newBuilder()
+ .setMyInt(1)
+ .setMyString("foo")
+ .setMyFloat(1.0F)
+ .setExtension(UnittestProto.myExtensionInt, 23)
+ .setExtension(UnittestProto.myExtensionString, "bar")
+ .build();
+ TestFieldOrderings dest =
+ TestFieldOrderings.parseFrom(source.toByteString(),
+ getTestFieldOrderingsRegistry());
+ assertEquals(source, dest);
+ }
+
+ public void testParseMultipleExtensionRangesDynamic() throws Exception {
+ // Same as above except with DynamicMessage.
+ Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
+ DynamicMessage source =
+ DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
+ .setField(descriptor.findFieldByName("my_int"), 1L)
+ .setField(descriptor.findFieldByName("my_string"), "foo")
+ .setField(descriptor.findFieldByName("my_float"), 1.0F)
+ .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
+ .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
+ .build();
+ DynamicMessage dest =
+ DynamicMessage.parseFrom(descriptor, source.toByteString(),
+ getTestFieldOrderingsRegistry());
+ assertEquals(source, dest);
+ }
+
+ private static final int UNKNOWN_TYPE_ID = 1550055;
+ private static final int TYPE_ID_1 =
+ TestMessageSetExtension1.getDescriptor().getExtensions().get(0).getNumber();
+ private static final int TYPE_ID_2 =
+ TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber();
+
+ public void testSerializeMessageSet() throws Exception {
+ // Set up a TestMessageSet with two known messages and an unknown one.
+ TestMessageSet messageSet =
+ TestMessageSet.newBuilder()
+ .setExtension(
+ TestMessageSetExtension1.messageSetExtension,
+ TestMessageSetExtension1.newBuilder().setI(123).build())
+ .setExtension(
+ TestMessageSetExtension2.messageSetExtension,
+ TestMessageSetExtension2.newBuilder().setStr("foo").build())
+ .setUnknownFields(
+ UnknownFieldSet.newBuilder()
+ .addField(UNKNOWN_TYPE_ID,
+ UnknownFieldSet.Field.newBuilder()
+ .addLengthDelimited(ByteString.copyFromUtf8("bar"))
+ .build())
+ .build())
+ .build();
+
+ ByteString data = messageSet.toByteString();
+
+ // Parse back using RawMessageSet and check the contents.
+ RawMessageSet raw = RawMessageSet.parseFrom(data);
+
+ assertTrue(raw.getUnknownFields().asMap().isEmpty());
+
+ assertEquals(3, raw.getItemCount());
+ assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId());
+ assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId());
+ assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId());
+
+ TestMessageSetExtension1 message1 =
+ TestMessageSetExtension1.parseFrom(
+ raw.getItem(0).getMessage().toByteArray());
+ assertEquals(123, message1.getI());
+
+ TestMessageSetExtension2 message2 =
+ TestMessageSetExtension2.parseFrom(
+ raw.getItem(1).getMessage().toByteArray());
+ assertEquals("foo", message2.getStr());
+
+ assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8());
+ }
+
+ public void testParseMessageSet() throws Exception {
+ ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+ extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+ extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
+
+ // Set up a RawMessageSet with two known messages and an unknown one.
+ RawMessageSet raw =
+ RawMessageSet.newBuilder()
+ .addItem(
+ RawMessageSet.Item.newBuilder()
+ .setTypeId(TYPE_ID_1)
+ .setMessage(
+ TestMessageSetExtension1.newBuilder()
+ .setI(123)
+ .build().toByteString())
+ .build())
+ .addItem(
+ RawMessageSet.Item.newBuilder()
+ .setTypeId(TYPE_ID_2)
+ .setMessage(
+ TestMessageSetExtension2.newBuilder()
+ .setStr("foo")
+ .build().toByteString())
+ .build())
+ .addItem(
+ RawMessageSet.Item.newBuilder()
+ .setTypeId(UNKNOWN_TYPE_ID)
+ .setMessage(ByteString.copyFromUtf8("bar"))
+ .build())
+ .build();
+
+ ByteString data = raw.toByteString();
+
+ // Parse as a TestMessageSet and check the contents.
+ TestMessageSet messageSet =
+ TestMessageSet.parseFrom(data, extensionRegistry);
+
+ assertEquals(123, messageSet.getExtension(
+ TestMessageSetExtension1.messageSetExtension).getI());
+ assertEquals("foo", messageSet.getExtension(
+ TestMessageSetExtension2.messageSetExtension).getStr());
+
+ // Check for unknown field with type LENGTH_DELIMITED,
+ // number UNKNOWN_TYPE_ID, and contents "bar".
+ UnknownFieldSet unknownFields = messageSet.getUnknownFields();
+ assertEquals(1, unknownFields.asMap().size());
+ assertTrue(unknownFields.hasField(UNKNOWN_TYPE_ID));
+
+ UnknownFieldSet.Field field = unknownFields.getField(UNKNOWN_TYPE_ID);
+ assertEquals(1, field.getLengthDelimitedList().size());
+ assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8());
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/multiple_files_test.proto b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/multiple_files_test.proto
new file mode 100644
index 0000000..9a04014
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/multiple_files_test.proto
@@ -0,0 +1,71 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// A proto file which tests the java_multiple_files option.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option java_generic_services = true; // auto-added
+
+import "google/protobuf/unittest.proto";
+
+package protobuf_unittest;
+
+option java_multiple_files = true;
+option java_outer_classname = "MultipleFilesTestProto";
+
+message MessageWithNoOuter {
+ message NestedMessage {
+ optional int32 i = 1;
+ }
+ enum NestedEnum {
+ BAZ = 3;
+ }
+ optional NestedMessage nested = 1;
+ repeated TestAllTypes foreign = 2;
+ optional NestedEnum nested_enum = 3;
+ optional EnumWithNoOuter foreign_enum = 4;
+}
+
+enum EnumWithNoOuter {
+ FOO = 1;
+ BAR = 2;
+}
+
+service ServiceWithNoOuter {
+ rpc Foo(MessageWithNoOuter) returns(TestAllTypes);
+}
+
+extend TestAllExtensions {
+ optional int32 extension_with_outer = 1234567;
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_builders_test.proto b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_builders_test.proto
new file mode 100644
index 0000000..abffb9d
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_builders_test.proto
@@ -0,0 +1,53 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jonp@google.com (Jon Perlow)
+//
+
+package protobuf_unittest;
+
+option java_multiple_files = true;
+option java_outer_classname = "NestedBuilders";
+
+
+message Vehicle {
+ optional Engine engine = 1;
+ repeated Wheel wheel = 2;
+}
+
+message Engine {
+ optional int32 cylinder = 1;
+ optional int32 liters = 2;
+}
+
+message Wheel {
+ optional int32 radius = 1;
+ optional int32 width = 2;
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_extension.proto b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_extension.proto
new file mode 100644
index 0000000..9fe5d56
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_extension.proto
@@ -0,0 +1,45 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with nested extensions. Note that this must be defined in
+// a separate file to properly test the initialization of the outer class.
+
+
+import "com/google/protobuf/non_nested_extension.proto";
+
+package protobuf_unittest;
+
+message MyNestedExtension {
+ extend MessageToBeExtended {
+ optional MessageToBeExtended recursiveExtension = 2;
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_extension_lite.proto b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_extension_lite.proto
new file mode 100644
index 0000000..16ee46e
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/nested_extension_lite.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with nested extensions for a MessageLite messages. Note that
+// this must be defined in a separate file to properly test the initialization
+// of the outer class.
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+import "com/google/protobuf/non_nested_extension_lite.proto";
+
+message MyNestedExtensionLite {
+ extend MessageLiteToBeExtended {
+ optional MessageLiteToBeExtended recursiveExtensionLite = 3;
+ }
+}
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension.proto b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension.proto
new file mode 100644
index 0000000..f61b419
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with extensions.
+
+
+package protobuf_unittest;
+
+message MessageToBeExtended {
+ extensions 1 to max;
+}
+
+message MyNonNestedExtension {
+}
+
+extend MessageToBeExtended {
+ optional MyNonNestedExtension nonNestedExtension = 1;
+}
+
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto
new file mode 100644
index 0000000..3c82659
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with extensions for a MessageLite messages.
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+message MessageLiteToBeExtended {
+ extensions 1 to max;
+}
+
+message MyNonNestedExtensionLite {
+}
+
+extend MessageLiteToBeExtended {
+ optional MyNonNestedExtensionLite nonNestedExtensionLite = 1;
+}
+
diff --git a/src/third_party/protobuf/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
new file mode 100644
index 0000000..9610e9d
--- /dev/null
+++ b/src/third_party/protobuf/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
@@ -0,0 +1,90 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jonp@google.com (Jon Perlow)
+
+// This file tests that various identifiers work as field and type names even
+// though the same identifiers are used internally by the java code generator.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option java_generic_services = true; // auto-added
+
+package io_protocol_tests;
+
+option java_package = "com.google.protobuf";
+option java_outer_classname = "TestBadIdentifiersProto";
+
+message TestMessage {
+}
+
+message Deprecated {
+ enum TestEnum {
+ FOO = 1;
+ }
+
+ optional int32 field1 = 1 [deprecated=true];
+ optional TestEnum field2 = 2 [deprecated=true];
+ optional TestMessage field3 = 3 [deprecated=true];
+}
+
+message Override {
+ optional int32 override = 1;
+}
+
+message Object {
+ optional int32 object = 1;
+}
+
+message String {
+ optional string string = 1;
+}
+
+message Integer {
+ optional int32 integer = 1;
+}
+
+message Long {
+ optional int32 long = 1;
+}
+
+message Float {
+ optional float float = 1;
+}
+
+message Double {
+ optional double double = 1;
+}
+
+service TestConflictingMethodNames {
+ rpc Override(TestMessage) returns (TestMessage);
+}
+
diff --git a/src/third_party/protobuf/protobuf.gyp b/src/third_party/protobuf/protobuf.gyp
new file mode 100644
index 0000000..b679cad
--- /dev/null
+++ b/src/third_party/protobuf/protobuf.gyp
@@ -0,0 +1,480 @@
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'conditions': [
+ ['use_system_protobuf==0', {
+ 'conditions': [
+ ['OS!="win"', {
+ 'variables': {
+ 'config_h_dir':
+ '.', # crafted for gcc/linux.
+ },
+ }, { # else, OS=="win"
+ 'variables': {
+ 'config_h_dir':
+ 'vsprojects', # crafted for msvc.
+ },
+ 'target_defaults': {
+ 'msvs_disabled_warnings': [
+ 4018, # signed/unsigned mismatch in comparison
+ 4244, # implicit conversion, possible loss of data
+ 4355, # 'this' used in base member initializer list
+ ],
+ 'defines!': [
+ 'WIN32_LEAN_AND_MEAN', # Protobuf defines this itself.
+ ],
+ },
+ }],
+ ['OS=="ios"', {
+ 'variables': {
+ 'ninja_output_dir': 'ninja-protoc',
+ 'ninja_product_dir':
+ '<(DEPTH)/xcodebuild/<(ninja_output_dir)/<(CONFIGURATION_NAME)',
+ # Gyp to rerun
+ 're_run_targets': [
+ 'third_party/protobuf/protobuf.gyp',
+ ],
+ },
+ 'targets': [
+ {
+ # On iOS, generating protoc is done via two actions: (1) compiling
+ # the executable with ninja, and (2) copying the executable into a
+ # location that is shared with other projects. These actions are
+ # separated into two targets in order to be able to specify that the
+ # second action should not run until the first action finishes (since
+ # the ordering of multiple actions in one target is defined only by
+ # inputs and outputs, and it's impossible to set correct inputs for
+ # the ninja build, so setting all the inputs and outputs isn't an
+ # option). The first target is given here; the second target is the
+ # normal protoc target under the condition that "OS==iOS".
+ 'target_name': 'compile_protoc',
+ 'type': 'none',
+ 'includes': ['../../build/ios/mac_build.gypi'],
+ 'actions': [
+ {
+ 'action_name': 'compile protoc',
+ 'inputs': [],
+ 'outputs': [],
+ 'action': [
+ '<@(ninja_cmd)',
+ 'protoc',
+ ],
+ 'message': 'Generating the C++ protocol buffers compiler',
+ },
+ ],
+ },
+ ],
+ }],
+ ['OS=="android"', {
+ 'targets': [
+ {
+ 'target_name': 'protobuf_lite_javalib',
+ 'type' : 'none',
+ 'dependencies': [
+ 'protoc#host',
+ ],
+ 'variables': {
+ 'script_descriptors': './protobuf_lite_java_descriptor_proto.py',
+ 'script_pom': './protobuf_lite_java_parse_pom.py',
+ 'protoc': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
+ # Variables needed by java.gypi below.
+ 'java_out_dir': '<(PRODUCT_DIR)/java_proto/protobuf_lite_java_descriptor_proto',
+ 'generated_src_dirs': ['<(java_out_dir)'],
+ 'package_name': '<(_target_name)',
+ 'java_in_dir': 'java',
+ 'maven_pom': '<(java_in_dir)/pom.xml',
+ 'javac_includes': ['<!@(<(script_pom) <(maven_pom))'],
+ 'additional_input_paths': [
+ '<(java_out_dir)/com/google/protobuf/DescriptorProtos.java'
+ ],
+ },
+ 'actions': [
+ {
+ 'action_name': 'protobuf_lite_java_gen_descriptor_proto',
+ 'inputs': [
+ '<(script_descriptors)',
+ '<(protoc)',
+ 'src/google/protobuf/descriptor.proto',
+ ],
+ 'outputs': [
+ '<(java_out_dir)/com/google/protobuf/DescriptorProtos.java',
+ ],
+ 'action': [
+ '<(script_descriptors)',
+ '<(protoc)',
+ '<(java_out_dir)',
+ 'src',
+ 'src/google/protobuf/descriptor.proto',
+ ],
+ 'message': 'Generating descriptor protos for Java',
+ },
+ ],
+ # Now that we have generated DescriptorProtos.java, build jar.
+ 'includes': ['../../build/java.gypi'],
+ },
+ ]
+ }],
+ ],
+ 'targets': [
+ # The "lite" lib is about 1/7th the size of the heavy lib,
+ # but it doesn't support some of the more exotic features of
+ # protobufs, like reflection. To generate C++ code that can link
+ # against the lite version of the library, add the option line:
+ #
+ # option optimize_for = LITE_RUNTIME;
+ #
+ # to your .proto file.
+ {
+ 'target_name': 'protobuf_lite',
+ 'type': 'static_library',
+ 'toolsets': ['host', 'target'],
+ 'sources': [
+ 'src/google/protobuf/stubs/atomicops.h',
+ 'src/google/protobuf/stubs/atomicops_internals_arm_gcc.h',
+ 'src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h',
+ 'src/google/protobuf/stubs/atomicops_internals_macosx.h',
+ 'src/google/protobuf/stubs/atomicops_internals_mips_gcc.h',
+ 'src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc',
+ 'src/google/protobuf/stubs/atomicops_internals_x86_gcc.h',
+ 'src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc',
+ 'src/google/protobuf/stubs/atomicops_internals_x86_msvc.h',
+ 'src/google/protobuf/stubs/common.h',
+ 'src/google/protobuf/stubs/once.h',
+ 'src/google/protobuf/stubs/platform_macros.h',
+ 'src/google/protobuf/extension_set.h',
+ 'src/google/protobuf/generated_message_util.h',
+ 'src/google/protobuf/message_lite.h',
+ 'src/google/protobuf/repeated_field.h',
+ 'src/google/protobuf/unknown_field_set.cc',
+ 'src/google/protobuf/unknown_field_set.h',
+ 'src/google/protobuf/wire_format_lite.h',
+ 'src/google/protobuf/wire_format_lite_inl.h',
+ 'src/google/protobuf/io/coded_stream.h',
+ 'src/google/protobuf/io/zero_copy_stream.h',
+ 'src/google/protobuf/io/zero_copy_stream_impl_lite.h',
+
+ 'src/google/protobuf/stubs/common.cc',
+ 'src/google/protobuf/stubs/once.cc',
+ 'src/google/protobuf/stubs/hash.h',
+ 'src/google/protobuf/stubs/map-util.h',
+ 'src/google/protobuf/stubs/stl_util-inl.h',
+ 'src/google/protobuf/extension_set.cc',
+ 'src/google/protobuf/generated_message_util.cc',
+ 'src/google/protobuf/message_lite.cc',
+ 'src/google/protobuf/repeated_field.cc',
+ 'src/google/protobuf/wire_format_lite.cc',
+ 'src/google/protobuf/io/coded_stream.cc',
+ 'src/google/protobuf/io/coded_stream_inl.h',
+ 'src/google/protobuf/io/zero_copy_stream.cc',
+ 'src/google/protobuf/io/zero_copy_stream_impl_lite.cc',
+ '<(config_h_dir)/config.h',
+ ],
+ 'include_dirs': [
+ '<(config_h_dir)',
+ 'src',
+ ],
+ # This macro must be defined to suppress the use of dynamic_cast<>,
+ # which requires RTTI.
+ 'defines': [
+ 'GOOGLE_PROTOBUF_NO_RTTI',
+ 'GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER',
+ ],
+
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(config_h_dir)',
+ 'src',
+ ],
+ 'defines': [
+ 'GOOGLE_PROTOBUF_NO_RTTI',
+ 'GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER',
+ ],
+ },
+ },
+ # This is the full, heavy protobuf lib that's needed for c++ .proto's
+ # that don't specify the LITE_RUNTIME option. The protocol
+ # compiler itself (protoc) falls into that category.
+ #
+ # DO NOT LINK AGAINST THIS TARGET IN CHROME CODE --agl
+ {
+ 'target_name': 'protobuf_full_do_not_use',
+ 'type': 'static_library',
+ 'toolsets': ['host','target'],
+ 'sources': [
+ 'src/google/protobuf/descriptor.h',
+ 'src/google/protobuf/descriptor.pb.h',
+ 'src/google/protobuf/descriptor_database.h',
+ 'src/google/protobuf/dynamic_message.h',
+ 'src/google/protobuf/generated_message_reflection.h',
+ 'src/google/protobuf/message.h',
+ 'src/google/protobuf/reflection_ops.h',
+ 'src/google/protobuf/service.h',
+ 'src/google/protobuf/text_format.h',
+ 'src/google/protobuf/wire_format.h',
+ 'src/google/protobuf/io/gzip_stream.h',
+ 'src/google/protobuf/io/printer.h',
+ 'src/google/protobuf/io/tokenizer.h',
+ 'src/google/protobuf/io/zero_copy_stream_impl.h',
+ 'src/google/protobuf/compiler/code_generator.h',
+ 'src/google/protobuf/compiler/command_line_interface.h',
+ 'src/google/protobuf/compiler/importer.h',
+ 'src/google/protobuf/compiler/parser.h',
+
+ 'src/google/protobuf/stubs/strutil.cc',
+ 'src/google/protobuf/stubs/strutil.h',
+ 'src/google/protobuf/stubs/substitute.cc',
+ 'src/google/protobuf/stubs/substitute.h',
+ 'src/google/protobuf/stubs/structurally_valid.cc',
+ 'src/google/protobuf/descriptor.cc',
+ 'src/google/protobuf/descriptor.pb.cc',
+ 'src/google/protobuf/descriptor_database.cc',
+ 'src/google/protobuf/dynamic_message.cc',
+ 'src/google/protobuf/extension_set_heavy.cc',
+ 'src/google/protobuf/generated_message_reflection.cc',
+ 'src/google/protobuf/message.cc',
+ 'src/google/protobuf/reflection_ops.cc',
+ 'src/google/protobuf/service.cc',
+ 'src/google/protobuf/text_format.cc',
+ 'src/google/protobuf/wire_format.cc',
+ # This file pulls in zlib, but it's not actually used by protoc, so
+ # instead of compiling zlib for the host, let's just exclude this.
+ # 'src/src/google/protobuf/io/gzip_stream.cc',
+ 'src/google/protobuf/io/printer.cc',
+ 'src/google/protobuf/io/tokenizer.cc',
+ 'src/google/protobuf/io/zero_copy_stream_impl.cc',
+ 'src/google/protobuf/compiler/importer.cc',
+ 'src/google/protobuf/compiler/parser.cc',
+ ],
+ 'dependencies': [
+ 'protobuf_lite',
+ ],
+ 'export_dependent_settings': [
+ 'protobuf_lite',
+ ],
+ },
+ {
+ 'target_name': 'protoc',
+ 'conditions': [
+ ['OS!="ios"', {
+ 'type': 'executable',
+ 'toolsets': ['host'],
+ 'sources': [
+ 'src/google/protobuf/compiler/code_generator.cc',
+ 'src/google/protobuf/compiler/command_line_interface.cc',
+ 'src/google/protobuf/compiler/plugin.cc',
+ 'src/google/protobuf/compiler/plugin.pb.cc',
+ 'src/google/protobuf/compiler/subprocess.cc',
+ 'src/google/protobuf/compiler/subprocess.h',
+ 'src/google/protobuf/compiler/zip_writer.cc',
+ 'src/google/protobuf/compiler/zip_writer.h',
+ 'src/google/protobuf/compiler/cpp/cpp_enum.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_enum.h',
+ 'src/google/protobuf/compiler/cpp/cpp_enum_field.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_enum_field.h',
+ 'src/google/protobuf/compiler/cpp/cpp_extension.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_extension.h',
+ 'src/google/protobuf/compiler/cpp/cpp_field.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_field.h',
+ 'src/google/protobuf/compiler/cpp/cpp_file.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_file.h',
+ 'src/google/protobuf/compiler/cpp/cpp_generator.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_helpers.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_helpers.h',
+ 'src/google/protobuf/compiler/cpp/cpp_message.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_message.h',
+ 'src/google/protobuf/compiler/cpp/cpp_message_field.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_message_field.h',
+ 'src/google/protobuf/compiler/cpp/cpp_primitive_field.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_primitive_field.h',
+ 'src/google/protobuf/compiler/cpp/cpp_service.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_service.h',
+ 'src/google/protobuf/compiler/cpp/cpp_string_field.cc',
+ 'src/google/protobuf/compiler/cpp/cpp_string_field.h',
+ 'src/google/protobuf/compiler/java/java_enum.cc',
+ 'src/google/protobuf/compiler/java/java_enum.h',
+ 'src/google/protobuf/compiler/java/java_enum_field.cc',
+ 'src/google/protobuf/compiler/java/java_enum_field.h',
+ 'src/google/protobuf/compiler/java/java_extension.cc',
+ 'src/google/protobuf/compiler/java/java_extension.h',
+ 'src/google/protobuf/compiler/java/java_field.cc',
+ 'src/google/protobuf/compiler/java/java_field.h',
+ 'src/google/protobuf/compiler/java/java_file.cc',
+ 'src/google/protobuf/compiler/java/java_file.h',
+ 'src/google/protobuf/compiler/java/java_generator.cc',
+ 'src/google/protobuf/compiler/java/java_helpers.cc',
+ 'src/google/protobuf/compiler/java/java_helpers.h',
+ 'src/google/protobuf/compiler/java/java_message.cc',
+ 'src/google/protobuf/compiler/java/java_message.h',
+ 'src/google/protobuf/compiler/java/java_message_field.cc',
+ 'src/google/protobuf/compiler/java/java_message_field.h',
+ 'src/google/protobuf/compiler/java/java_primitive_field.cc',
+ 'src/google/protobuf/compiler/java/java_primitive_field.h',
+ 'src/google/protobuf/compiler/java/java_service.cc',
+ 'src/google/protobuf/compiler/java/java_service.h',
+ 'src/google/protobuf/compiler/java/java_string_field.cc',
+ 'src/google/protobuf/compiler/java/java_string_field.h',
+ 'src/google/protobuf/compiler/python/python_generator.cc',
+ 'src/google/protobuf/compiler/main.cc',
+ ],
+ 'dependencies': [
+ 'protobuf_full_do_not_use',
+ ],
+ 'include_dirs': [
+ '<(config_h_dir)',
+ 'src/src',
+ ],
+ }, { # else, OS=="ios"
+ 'type': 'none',
+ 'dependencies': [
+ 'compile_protoc',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'copy protoc',
+ 'inputs': [
+ '<(ninja_product_dir)/protoc',
+ ],
+ 'outputs': [
+ '<(PRODUCT_DIR)/protoc',
+ ],
+ 'action': [
+ 'cp',
+ '<(ninja_product_dir)/protoc',
+ '<(PRODUCT_DIR)/protoc',
+ ],
+ },
+ ],
+ }],
+ ],
+ },
+ {
+ # Generate the python module needed by all protoc-generated Python code.
+ 'target_name': 'py_proto',
+ 'type': 'none',
+ 'copies': [
+ {
+ 'destination': '<(PRODUCT_DIR)/pyproto/google/',
+ 'files': [
+ # google/ module gets an empty __init__.py.
+ '__init__.py',
+ ],
+ },
+ {
+ 'destination': '<(PRODUCT_DIR)/pyproto/google/protobuf',
+ 'files': [
+ 'python/google/protobuf/__init__.py',
+ 'python/google/protobuf/descriptor.py',
+ 'python/google/protobuf/message.py',
+ 'python/google/protobuf/reflection.py',
+ 'python/google/protobuf/service.py',
+ 'python/google/protobuf/service_reflection.py',
+ 'python/google/protobuf/text_format.py',
+
+ # TODO(ncarter): protoc's python generator treats
+ # descriptor.proto specially, but it's not possible to trigger
+ # the special treatment unless you run protoc from ./src/src
+ # (the treatment is based on the path to the .proto file
+ # matching a constant exactly). I'm not sure how to convince
+ # gyp to execute a rule from a different directory. Until this
+ # is resolved, use a copy of descriptor_pb2.py that I manually
+ # generated.
+ 'descriptor_pb2.py',
+ ],
+ },
+ {
+ 'destination': '<(PRODUCT_DIR)/pyproto/google/protobuf/internal',
+ 'files': [
+ 'python/google/protobuf/internal/__init__.py',
+ 'python/google/protobuf/internal/api_implementation.py',
+ 'python/google/protobuf/internal/containers.py',
+ 'python/google/protobuf/internal/cpp_message.py',
+ 'python/google/protobuf/internal/decoder.py',
+ 'python/google/protobuf/internal/encoder.py',
+ 'python/google/protobuf/internal/generator_test.py',
+ 'python/google/protobuf/internal/message_listener.py',
+ 'python/google/protobuf/internal/python_message.py',
+ 'python/google/protobuf/internal/type_checkers.py',
+ 'python/google/protobuf/internal/wire_format.py',
+ ],
+ },
+ ],
+ # # We can't generate a proper descriptor_pb2.py -- see earlier comment.
+ # 'rules': [
+ # {
+ # 'rule_name': 'genproto',
+ # 'extension': 'proto',
+ # 'inputs': [
+ # '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
+ # ],
+ # 'variables': {
+ # # The protoc compiler requires a proto_path argument with the
+ # # directory containing the .proto file.
+ # 'rule_input_relpath': 'src/google/protobuf',
+ # },
+ # 'outputs': [
+ # '<(PRODUCT_DIR)/pyproto/google/protobuf/<(RULE_INPUT_ROOT)_pb2.py',
+ # ],
+ # 'action': [
+ # '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
+ # '-I./src',
+ # '-I.',
+ # '--python_out=<(PRODUCT_DIR)/pyproto/google/protobuf',
+ # 'google/protobuf/descriptor.proto',
+ # ],
+ # 'message': 'Generating Python code from <(RULE_INPUT_PATH)',
+ # },
+ # ],
+ # 'dependencies': [
+ # 'protoc#host',
+ # ],
+ # 'sources': [
+ # 'src/google/protobuf/descriptor.proto',
+ # ],
+ },
+ ],
+ }, { # use_system_protobuf==1
+ 'targets': [
+ {
+ 'target_name': 'protobuf_lite',
+ 'type': 'none',
+ 'direct_dependent_settings': {
+ 'cflags': [
+ # Use full protobuf, because vanilla protobuf doesn't have
+ # our custom patch to retain unknown fields in lite mode.
+ '<!@(pkg-config --cflags protobuf)',
+ ],
+ 'defines': [
+ 'USE_SYSTEM_PROTOBUF',
+
+ # This macro must be defined to suppress the use
+ # of dynamic_cast<>, which requires RTTI.
+ 'GOOGLE_PROTOBUF_NO_RTTI',
+ 'GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER',
+ ],
+ },
+ 'link_settings': {
+ # Use full protobuf, because vanilla protobuf doesn't have
+ # our custom patch to retain unknown fields in lite mode.
+ 'ldflags': [
+ '<!@(pkg-config --libs-only-L --libs-only-other protobuf)',
+ ],
+ 'libraries': [
+ '<!@(pkg-config --libs-only-l protobuf)',
+ ],
+ },
+ },
+ {
+ 'target_name': 'protoc',
+ 'type': 'none',
+ 'toolsets': ['host', 'target'],
+ },
+ {
+ 'target_name': 'py_proto',
+ 'type': 'none',
+ },
+ ],
+ }],
+ ],
+}
diff --git a/src/third_party/protobuf/protobuf_lite_java_descriptor_proto.py b/src/third_party/protobuf/protobuf_lite_java_descriptor_proto.py
new file mode 100755
index 0000000..2967ce9
--- /dev/null
+++ b/src/third_party/protobuf/protobuf_lite_java_descriptor_proto.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Generate java DescriptorProto file.
+
+Usage:
+ protobuf_lite_java_descriptor_proto.py {protoc} {java_out} {include} {proto_files}
+
+This is a helper file for the protobuf_lite_java_gen_descriptor_proto action in
+protobuf.gyp.
+
+It performs the following steps:
+1. Recursively deletes old java_out directory.
+2. Creates java_out directory.
+3. Generates Java descriptor proto file using protoc.
+"""
+
+import os
+import shutil
+import subprocess
+import sys
+
+def main(argv):
+ if len(argv) < 4:
+ usage()
+ return 1
+
+ protoc_path, java_out, include = argv[1:4]
+ proto_files = argv[4:]
+
+ # Delete all old sources
+ if os.path.exists(java_out):
+ shutil.rmtree(java_out)
+
+ # Create source directory
+ os.makedirs(java_out)
+
+ # Generate Java files using protoc
+ return subprocess.call(
+ [protoc_path, '--java_out', java_out, '-I' + include]
+ + proto_files)
+
+def usage():
+ print(__doc__);
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/src/third_party/protobuf/protobuf_lite_java_parse_pom.py b/src/third_party/protobuf/protobuf_lite_java_parse_pom.py
new file mode 100755
index 0000000..675c5cf
--- /dev/null
+++ b/src/third_party/protobuf/protobuf_lite_java_parse_pom.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Parses the Maven pom.xml file for which files to include in a lite build.
+
+Usage:
+ protobuf_lite_java_parse_pom.py {path to pom.xml}
+
+This is a helper file for the protobuf_lite_java target in protobuf.gyp.
+
+It parses the pom.xml file, and looks for all the includes specified in the
+'lite' profile. It does not return and test includes.
+
+The result is printed as one line per entry.
+"""
+
+import sys
+
+from xml.etree import ElementTree
+
+def main(argv):
+ if (len(argv) < 2):
+ usage()
+ return 1
+
+ # Setup all file and XML query paths.
+ pom_path = argv[1]
+ namespace = "{http://maven.apache.org/POM/4.0.0}"
+ profile_path = '{0}profiles/{0}profile'.format(namespace)
+ id_path = '{0}id'.format(namespace)
+ plugin_path = \
+ '{0}build/{0}plugins/{0}plugin'.format(namespace)
+ artifact_path = '{0}artifactId'.format(namespace)
+ include_path = '{0}configuration/{0}includes/{0}include'.format(namespace)
+
+ # Parse XML file and store result in includes list.
+ includes = []
+ for profile in ElementTree.parse(pom_path).getroot().findall(profile_path):
+ id_element = profile.find(id_path)
+ if (id_element is not None and id_element.text == 'lite'):
+ for plugin in profile.findall(plugin_path):
+ artifact_element = plugin.find(artifact_path)
+ if (artifact_element is not None and
+ artifact_element.text == 'maven-compiler-plugin'):
+ for include in plugin.findall(include_path):
+ includes.append(include.text)
+
+ # Print result to stdout, one item on each line.
+ print '\n'.join(includes)
+
+def usage():
+ print(__doc__);
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/src/third_party/protobuf/python/README.txt b/src/third_party/protobuf/python/README.txt
new file mode 100644
index 0000000..6dc144e
--- /dev/null
+++ b/src/third_party/protobuf/python/README.txt
@@ -0,0 +1,100 @@
+Protocol Buffers - Google's data interchange format
+Copyright 2008 Google Inc.
+
+This directory contains the Python Protocol Buffers runtime library.
+
+Normally, this directory comes as part of the protobuf package, available
+from:
+
+ http://code.google.com/p/protobuf
+
+The complete package includes the C++ source code, which includes the
+Protocol Compiler (protoc). If you downloaded this package from PyPI
+or some other Python-specific source, you may have received only the
+Python part of the code. In this case, you will need to obtain the
+Protocol Compiler from some other source before you can use this
+package.
+
+Development Warning
+===================
+
+The Python implementation of Protocol Buffers is not as mature as the C++
+and Java implementations. It may be more buggy, and it is known to be
+pretty slow at this time. If you would like to help fix these issues,
+join the Protocol Buffers discussion list and let us know!
+
+Installation
+============
+
+1) Make sure you have Python 2.4 or newer. If in doubt, run:
+
+ $ python -V
+
+2) If you do not have setuptools installed, note that it will be
+ downloaded and installed automatically as soon as you run setup.py.
+ If you would rather install it manually, you may do so by following
+ the instructions on this page:
+
+ http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions
+
+3) Build the C++ code, or install a binary distribution of protoc. If
+ you install a binary distribution, make sure that it is the same
+ version as this package. If in doubt, run:
+
+ $ protoc --version
+
+4) Run the tests:
+
+ $ python setup.py test
+
+ If some tests fail, this library may not work correctly on your
+ system. Continue at your own risk.
+
+ Please note that there is a known problem with some versions of
+ Python on Cygwin which causes the tests to fail after printing the
+ error: "sem_init: Resource temporarily unavailable". This appears
+ to be a bug either in Cygwin or in Python:
+ http://www.cygwin.com/ml/cygwin/2005-07/msg01378.html
+ We do not know if or when it might me fixed. We also do not know
+ how likely it is that this bug will affect users in practice.
+
+5) Install:
+
+ $ python setup.py install
+
+ This step may require superuser privileges.
+ NOTE: To use C++ implementation, you need to install C++ protobuf runtime
+ library of the same version and export the environment variable before this
+ step. See the "C++ Implementation" section below for more details.
+
+Usage
+=====
+
+The complete documentation for Protocol Buffers is available via the
+web at:
+
+ http://code.google.com/apis/protocolbuffers/
+
+C++ Implementation
+==================
+
+WARNING: This is EXPERIMENTAL and only available for CPython platforms.
+
+The C++ implementation for Python messages is built as a Python extension to
+improve the overall protobuf Python performance.
+
+To use the C++ implementation, you need to:
+1) Install the C++ protobuf runtime library, please see instructions in the
+ parent directory.
+2) Export an environment variable:
+
+ $ export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+
+You need to export this variable before running setup.py script to build and
+install the extension. You must also set the variable at runtime, otherwise
+the pure-Python implementation will be used. In a future release, we will
+change the default so that C++ implementation is used whenever it is available.
+It is strongly recommended to run `python setup.py test` after setting the
+variable to "cpp", so the tests will be against C++ implemented Python
+messages.
+
diff --git a/src/third_party/protobuf/python/ez_setup.py b/src/third_party/protobuf/python/ez_setup.py
new file mode 100755
index 0000000..a2cf777
--- /dev/null
+++ b/src/third_party/protobuf/python/ez_setup.py
@@ -0,0 +1,283 @@
+#!python
+
+# This file was obtained from:
+# http://peak.telecommunity.com/dist/ez_setup.py
+# on 2011/1/21.
+
+"""Bootstrap setuptools installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+ from ez_setup import use_setuptools
+ use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import sys
+DEFAULT_VERSION = "0.6c11"
+DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+
+md5_data = {
+ 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
+ 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
+ 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
+ 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
+ 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
+ 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
+ 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
+ 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
+ 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
+ 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+ 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
+ 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
+ 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
+ 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
+ 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
+ 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
+ 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
+ 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
+ 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
+ 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
+ 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
+ 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
+ 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
+ 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
+ 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
+ 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
+ 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
+ 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
+ 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
+ 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
+ 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
+ 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
+ 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
+ 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
+ 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
+ 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
+ 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
+ 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
+ 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
+ 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
+ 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
+ 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
+}
+
+import sys, os
+try: from hashlib import md5
+except ImportError: from md5 import md5
+
+def _validate_md5(egg_name, data):
+ if egg_name in md5_data:
+ digest = md5(data).hexdigest()
+ if digest != md5_data[egg_name]:
+ print >>sys.stderr, (
+ "md5 validation of %s failed! (Possible download problem?)"
+ % egg_name
+ )
+ sys.exit(2)
+ return data
+
+def use_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ download_delay=15
+):
+ """Automatically find/download setuptools and make it available on sys.path
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end with
+ a '/'). `to_dir` is the directory where setuptools will be downloaded, if
+ it is not already available. If `download_delay` is specified, it should
+ be the number of seconds that will be paused before initiating a download,
+ should one be required. If an older version of setuptools is installed,
+ this routine will print a message to ``sys.stderr`` and raise SystemExit in
+ an attempt to abort the calling script.
+ """
+ was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
+ def do_download():
+ egg = download_setuptools(version, download_base, to_dir, download_delay)
+ sys.path.insert(0, egg)
+ import setuptools; setuptools.bootstrap_install_from = egg
+ try:
+ import pkg_resources
+ except ImportError:
+ return do_download()
+ try:
+ pkg_resources.require("setuptools>="+version); return
+ except pkg_resources.VersionConflict, e:
+ if was_imported:
+ print >>sys.stderr, (
+ "The required version of setuptools (>=%s) is not available, and\n"
+ "can't be installed while this script is running. Please install\n"
+ " a more recent version first, using 'easy_install -U setuptools'."
+ "\n\n(Currently using %r)"
+ ) % (version, e.args[0])
+ sys.exit(2)
+ except pkg_resources.DistributionNotFound:
+ pass
+
+ del pkg_resources, sys.modules['pkg_resources'] # reload ok
+ return do_download()
+
+def download_setuptools(
+ version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+ delay = 15
+):
+ """Download setuptools from a specified location and return its filename
+
+ `version` should be a valid setuptools version number that is available
+ as an egg for download under the `download_base` URL (which should end
+ with a '/'). `to_dir` is the directory where the egg will be downloaded.
+ `delay` is the number of seconds to pause before an actual download attempt.
+ """
+ import urllib2, shutil
+ egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
+ url = download_base + egg_name
+ saveto = os.path.join(to_dir, egg_name)
+ src = dst = None
+ if not os.path.exists(saveto): # Avoid repeated downloads
+ try:
+ from distutils import log
+ if delay:
+ log.warn("""
+---------------------------------------------------------------------------
+This script requires setuptools version %s to run (even to display
+help). I will attempt to download it for you (from
+%s), but
+you may need to enable firewall access for this script first.
+I will start the download in %d seconds.
+
+(Note: if this machine does not have network access, please obtain the file
+
+ %s
+
+and place it in this directory before rerunning this script.)
+---------------------------------------------------------------------------""",
+ version, download_base, delay, url
+ ); from time import sleep; sleep(delay)
+ log.warn("Downloading %s", url)
+ src = urllib2.urlopen(url)
+ # Read/write all in one block, so we don't create a corrupt file
+ # if the download is interrupted.
+ data = _validate_md5(egg_name, src.read())
+ dst = open(saveto,"wb"); dst.write(data)
+ finally:
+ if src: src.close()
+ if dst: dst.close()
+ return os.path.realpath(saveto)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+def main(argv, version=DEFAULT_VERSION):
+ """Install or upgrade setuptools and EasyInstall"""
+ try:
+ import setuptools
+ except ImportError:
+ egg = None
+ try:
+ egg = download_setuptools(version, delay=0)
+ sys.path.insert(0,egg)
+ from setuptools.command.easy_install import main
+ return main(list(argv)+[egg]) # we're done here
+ finally:
+ if egg and os.path.exists(egg):
+ os.unlink(egg)
+ else:
+ if setuptools.__version__ == '0.0.1':
+ print >>sys.stderr, (
+ "You have an obsolete version of setuptools installed. Please\n"
+ "remove it from your system entirely before rerunning this script."
+ )
+ sys.exit(2)
+
+ req = "setuptools>="+version
+ import pkg_resources
+ try:
+ pkg_resources.require(req)
+ except pkg_resources.VersionConflict:
+ try:
+ from setuptools.command.easy_install import main
+ except ImportError:
+ from easy_install import main
+ main(list(argv)+[download_setuptools(delay=0)])
+ sys.exit(0) # try to force an exit
+ else:
+ if argv:
+ from setuptools.command.easy_install import main
+ main(argv)
+ else:
+ print "Setuptools version",version,"or greater has been installed."
+ print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
+
+def update_md5(filenames):
+ """Update our built-in md5 registry"""
+
+ import re
+
+ for name in filenames:
+ base = os.path.basename(name)
+ f = open(name,'rb')
+ md5_data[base] = md5(f.read()).hexdigest()
+ f.close()
+
+ data = [" %r: %r,\n" % it for it in md5_data.items()]
+ data.sort()
+ repl = "".join(data)
+
+ import inspect
+ srcfile = inspect.getsourcefile(sys.modules[__name__])
+ f = open(srcfile, 'rb'); src = f.read(); f.close()
+
+ match = re.search("\nmd5_data = {\n([^}]+)}", src)
+ if not match:
+ print >>sys.stderr, "Internal error!"
+ sys.exit(2)
+
+ src = src[:match.start(1)] + repl + src[match.end(1):]
+ f = open(srcfile,'w')
+ f.write(src)
+ f.close()
+
+
+if __name__=='__main__':
+ if len(sys.argv)>2 and sys.argv[1]=='--md5update':
+ update_md5(sys.argv[2:])
+ else:
+ main(sys.argv[1:])
diff --git a/src/third_party/protobuf/python/google/__init__.py b/src/third_party/protobuf/python/google/__init__.py
new file mode 100755
index 0000000..de40ea7
--- /dev/null
+++ b/src/third_party/protobuf/python/google/__init__.py
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/src/third_party/protobuf/python/google/protobuf/__init__.py b/src/third_party/protobuf/python/google/protobuf/__init__.py
new file mode 100755
index 0000000..8d1c8b6
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/__init__.py
@@ -0,0 +1 @@
+
diff --git a/src/third_party/protobuf/python/google/protobuf/descriptor.py b/src/third_party/protobuf/python/google/protobuf/descriptor.py
new file mode 100755
index 0000000..cf609be
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/descriptor.py
@@ -0,0 +1,598 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Descriptors essentially contain exactly the information found in a .proto
+file, in types that make this information accessible in Python.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+from google.protobuf.internal import api_implementation
+
+
+if api_implementation.Type() == 'cpp':
+ from google.protobuf.internal import cpp_message
+
+
+class Error(Exception):
+ """Base error for this module."""
+
+
+class DescriptorBase(object):
+
+ """Descriptors base class.
+
+ This class is the base of all descriptor classes. It provides common options
+ related functionaility.
+
+ Attributes:
+ has_options: True if the descriptor has non-default options. Usually it
+ is not necessary to read this -- just call GetOptions() which will
+ happily return the default instance. However, it's sometimes useful
+ for efficiency, and also useful inside the protobuf implementation to
+ avoid some bootstrapping issues.
+ """
+
+ def __init__(self, options, options_class_name):
+ """Initialize the descriptor given its options message and the name of the
+ class of the options message. The name of the class is required in case
+ the options message is None and has to be created.
+ """
+ self._options = options
+ self._options_class_name = options_class_name
+
+ # Does this descriptor have non-default options?
+ self.has_options = options is not None
+
+ def GetOptions(self):
+ """Retrieves descriptor options.
+
+ This method returns the options set or creates the default options for the
+ descriptor.
+ """
+ if self._options:
+ return self._options
+ from google.protobuf import descriptor_pb2
+ try:
+ options_class = getattr(descriptor_pb2, self._options_class_name)
+ except AttributeError:
+ raise RuntimeError('Unknown options class name %s!' %
+ (self._options_class_name))
+ self._options = options_class()
+ return self._options
+
+
+class _NestedDescriptorBase(DescriptorBase):
+ """Common class for descriptors that can be nested."""
+
+ def __init__(self, options, options_class_name, name, full_name,
+ file, containing_type, serialized_start=None,
+ serialized_end=None):
+ """Constructor.
+
+ Args:
+ options: Protocol message options or None
+ to use default message options.
+ options_class_name: (str) The class name of the above options.
+
+ name: (str) Name of this protocol message type.
+ full_name: (str) Fully-qualified name of this protocol message type,
+ which will include protocol "package" name and the name of any
+ enclosing types.
+ file: (FileDescriptor) Reference to file info.
+ containing_type: if provided, this is a nested descriptor, with this
+ descriptor as parent, otherwise None.
+ serialized_start: The start index (inclusive) in block in the
+ file.serialized_pb that describes this descriptor.
+ serialized_end: The end index (exclusive) in block in the
+ file.serialized_pb that describes this descriptor.
+ """
+ super(_NestedDescriptorBase, self).__init__(
+ options, options_class_name)
+
+ self.name = name
+ # TODO(falk): Add function to calculate full_name instead of having it in
+ # memory?
+ self.full_name = full_name
+ self.file = file
+ self.containing_type = containing_type
+
+ self._serialized_start = serialized_start
+ self._serialized_end = serialized_end
+
+ def GetTopLevelContainingType(self):
+ """Returns the root if this is a nested type, or itself if its the root."""
+ desc = self
+ while desc.containing_type is not None:
+ desc = desc.containing_type
+ return desc
+
+ def CopyToProto(self, proto):
+ """Copies this to the matching proto in descriptor_pb2.
+
+ Args:
+ proto: An empty proto instance from descriptor_pb2.
+
+ Raises:
+ Error: If self couldnt be serialized, due to to few constructor arguments.
+ """
+ if (self.file is not None and
+ self._serialized_start is not None and
+ self._serialized_end is not None):
+ proto.ParseFromString(self.file.serialized_pb[
+ self._serialized_start:self._serialized_end])
+ else:
+ raise Error('Descriptor does not contain serialization.')
+
+
+class Descriptor(_NestedDescriptorBase):
+
+ """Descriptor for a protocol message type.
+
+ A Descriptor instance has the following attributes:
+
+ name: (str) Name of this protocol message type.
+ full_name: (str) Fully-qualified name of this protocol message type,
+ which will include protocol "package" name and the name of any
+ enclosing types.
+
+ containing_type: (Descriptor) Reference to the descriptor of the
+ type containing us, or None if this is top-level.
+
+ fields: (list of FieldDescriptors) Field descriptors for all
+ fields in this type.
+ fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor
+ objects as in |fields|, but indexed by "number" attribute in each
+ FieldDescriptor.
+ fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor
+ objects as in |fields|, but indexed by "name" attribute in each
+ FieldDescriptor.
+
+ nested_types: (list of Descriptors) Descriptor references
+ for all protocol message types nested within this one.
+ nested_types_by_name: (dict str -> Descriptor) Same Descriptor
+ objects as in |nested_types|, but indexed by "name" attribute
+ in each Descriptor.
+
+ enum_types: (list of EnumDescriptors) EnumDescriptor references
+ for all enums contained within this type.
+ enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor
+ objects as in |enum_types|, but indexed by "name" attribute
+ in each EnumDescriptor.
+ enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping
+ from enum value name to EnumValueDescriptor for that value.
+
+ extensions: (list of FieldDescriptor) All extensions defined directly
+ within this message type (NOT within a nested type).
+ extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor
+ objects as |extensions|, but indexed by "name" attribute of each
+ FieldDescriptor.
+
+ is_extendable: Does this type define any extension ranges?
+
+ options: (descriptor_pb2.MessageOptions) Protocol message options or None
+ to use default message options.
+
+ file: (FileDescriptor) Reference to file descriptor.
+ """
+
+ def __init__(self, name, full_name, filename, containing_type, fields,
+ nested_types, enum_types, extensions, options=None,
+ is_extendable=True, extension_ranges=None, file=None,
+ serialized_start=None, serialized_end=None):
+ """Arguments to __init__() are as described in the description
+ of Descriptor fields above.
+
+ Note that filename is an obsolete argument, that is not used anymore.
+ Please use file.name to access this as an attribute.
+ """
+ super(Descriptor, self).__init__(
+ options, 'MessageOptions', name, full_name, file,
+ containing_type, serialized_start=serialized_start,
+ serialized_end=serialized_start)
+
+ # We have fields in addition to fields_by_name and fields_by_number,
+ # so that:
+ # 1. Clients can index fields by "order in which they're listed."
+ # 2. Clients can easily iterate over all fields with the terse
+ # syntax: for f in descriptor.fields: ...
+ self.fields = fields
+ for field in self.fields:
+ field.containing_type = self
+ self.fields_by_number = dict((f.number, f) for f in fields)
+ self.fields_by_name = dict((f.name, f) for f in fields)
+
+ self.nested_types = nested_types
+ self.nested_types_by_name = dict((t.name, t) for t in nested_types)
+
+ self.enum_types = enum_types
+ for enum_type in self.enum_types:
+ enum_type.containing_type = self
+ self.enum_types_by_name = dict((t.name, t) for t in enum_types)
+ self.enum_values_by_name = dict(
+ (v.name, v) for t in enum_types for v in t.values)
+
+ self.extensions = extensions
+ for extension in self.extensions:
+ extension.extension_scope = self
+ self.extensions_by_name = dict((f.name, f) for f in extensions)
+ self.is_extendable = is_extendable
+ self.extension_ranges = extension_ranges
+
+ self._serialized_start = serialized_start
+ self._serialized_end = serialized_end
+
+ def CopyToProto(self, proto):
+ """Copies this to a descriptor_pb2.DescriptorProto.
+
+ Args:
+ proto: An empty descriptor_pb2.DescriptorProto.
+ """
+ # This function is overriden to give a better doc comment.
+ super(Descriptor, self).CopyToProto(proto)
+
+
+# TODO(robinson): We should have aggressive checking here,
+# for example:
+# * If you specify a repeated field, you should not be allowed
+# to specify a default value.
+# * [Other examples here as needed].
+#
+# TODO(robinson): for this and other *Descriptor classes, we
+# might also want to lock things down aggressively (e.g.,
+# prevent clients from setting the attributes). Having
+# stronger invariants here in general will reduce the number
+# of runtime checks we must do in reflection.py...
+class FieldDescriptor(DescriptorBase):
+
+ """Descriptor for a single field in a .proto file.
+
+ A FieldDescriptor instance has the following attriubtes:
+
+ name: (str) Name of this field, exactly as it appears in .proto.
+ full_name: (str) Name of this field, including containing scope. This is
+ particularly relevant for extensions.
+ index: (int) Dense, 0-indexed index giving the order that this
+ field textually appears within its message in the .proto file.
+ number: (int) Tag number declared for this field in the .proto file.
+
+ type: (One of the TYPE_* constants below) Declared type.
+ cpp_type: (One of the CPPTYPE_* constants below) C++ type used to
+ represent this field.
+
+ label: (One of the LABEL_* constants below) Tells whether this
+ field is optional, required, or repeated.
+ has_default_value: (bool) True if this field has a default value defined,
+ otherwise false.
+ default_value: (Varies) Default value of this field. Only
+ meaningful for non-repeated scalar fields. Repeated fields
+ should always set this to [], and non-repeated composite
+ fields should always set this to None.
+
+ containing_type: (Descriptor) Descriptor of the protocol message
+ type that contains this field. Set by the Descriptor constructor
+ if we're passed into one.
+ Somewhat confusingly, for extension fields, this is the
+ descriptor of the EXTENDED message, not the descriptor
+ of the message containing this field. (See is_extension and
+ extension_scope below).
+ message_type: (Descriptor) If a composite field, a descriptor
+ of the message type contained in this field. Otherwise, this is None.
+ enum_type: (EnumDescriptor) If this field contains an enum, a
+ descriptor of that enum. Otherwise, this is None.
+
+ is_extension: True iff this describes an extension field.
+ extension_scope: (Descriptor) Only meaningful if is_extension is True.
+ Gives the message that immediately contains this extension field.
+ Will be None iff we're a top-level (file-level) extension field.
+
+ options: (descriptor_pb2.FieldOptions) Protocol message field options or
+ None to use default field options.
+ """
+
+ # Must be consistent with C++ FieldDescriptor::Type enum in
+ # descriptor.h.
+ #
+ # TODO(robinson): Find a way to eliminate this repetition.
+ TYPE_DOUBLE = 1
+ TYPE_FLOAT = 2
+ TYPE_INT64 = 3
+ TYPE_UINT64 = 4
+ TYPE_INT32 = 5
+ TYPE_FIXED64 = 6
+ TYPE_FIXED32 = 7
+ TYPE_BOOL = 8
+ TYPE_STRING = 9
+ TYPE_GROUP = 10
+ TYPE_MESSAGE = 11
+ TYPE_BYTES = 12
+ TYPE_UINT32 = 13
+ TYPE_ENUM = 14
+ TYPE_SFIXED32 = 15
+ TYPE_SFIXED64 = 16
+ TYPE_SINT32 = 17
+ TYPE_SINT64 = 18
+ MAX_TYPE = 18
+
+ # Must be consistent with C++ FieldDescriptor::CppType enum in
+ # descriptor.h.
+ #
+ # TODO(robinson): Find a way to eliminate this repetition.
+ CPPTYPE_INT32 = 1
+ CPPTYPE_INT64 = 2
+ CPPTYPE_UINT32 = 3
+ CPPTYPE_UINT64 = 4
+ CPPTYPE_DOUBLE = 5
+ CPPTYPE_FLOAT = 6
+ CPPTYPE_BOOL = 7
+ CPPTYPE_ENUM = 8
+ CPPTYPE_STRING = 9
+ CPPTYPE_MESSAGE = 10
+ MAX_CPPTYPE = 10
+
+ # Must be consistent with C++ FieldDescriptor::Label enum in
+ # descriptor.h.
+ #
+ # TODO(robinson): Find a way to eliminate this repetition.
+ LABEL_OPTIONAL = 1
+ LABEL_REQUIRED = 2
+ LABEL_REPEATED = 3
+ MAX_LABEL = 3
+
+ def __init__(self, name, full_name, index, number, type, cpp_type, label,
+ default_value, message_type, enum_type, containing_type,
+ is_extension, extension_scope, options=None,
+ has_default_value=True):
+ """The arguments are as described in the description of FieldDescriptor
+ attributes above.
+
+ Note that containing_type may be None, and may be set later if necessary
+ (to deal with circular references between message types, for example).
+ Likewise for extension_scope.
+ """
+ super(FieldDescriptor, self).__init__(options, 'FieldOptions')
+ self.name = name
+ self.full_name = full_name
+ self.index = index
+ self.number = number
+ self.type = type
+ self.cpp_type = cpp_type
+ self.label = label
+ self.has_default_value = has_default_value
+ self.default_value = default_value
+ self.containing_type = containing_type
+ self.message_type = message_type
+ self.enum_type = enum_type
+ self.is_extension = is_extension
+ self.extension_scope = extension_scope
+ if api_implementation.Type() == 'cpp':
+ if is_extension:
+ self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name)
+ else:
+ self._cdescriptor = cpp_message.GetFieldDescriptor(full_name)
+ else:
+ self._cdescriptor = None
+
+
+class EnumDescriptor(_NestedDescriptorBase):
+
+ """Descriptor for an enum defined in a .proto file.
+
+ An EnumDescriptor instance has the following attributes:
+
+ name: (str) Name of the enum type.
+ full_name: (str) Full name of the type, including package name
+ and any enclosing type(s).
+
+ values: (list of EnumValueDescriptors) List of the values
+ in this enum.
+ values_by_name: (dict str -> EnumValueDescriptor) Same as |values|,
+ but indexed by the "name" field of each EnumValueDescriptor.
+ values_by_number: (dict int -> EnumValueDescriptor) Same as |values|,
+ but indexed by the "number" field of each EnumValueDescriptor.
+ containing_type: (Descriptor) Descriptor of the immediate containing
+ type of this enum, or None if this is an enum defined at the
+ top level in a .proto file. Set by Descriptor's constructor
+ if we're passed into one.
+ file: (FileDescriptor) Reference to file descriptor.
+ options: (descriptor_pb2.EnumOptions) Enum options message or
+ None to use default enum options.
+ """
+
+ def __init__(self, name, full_name, filename, values,
+ containing_type=None, options=None, file=None,
+ serialized_start=None, serialized_end=None):
+ """Arguments are as described in the attribute description above.
+
+ Note that filename is an obsolete argument, that is not used anymore.
+ Please use file.name to access this as an attribute.
+ """
+ super(EnumDescriptor, self).__init__(
+ options, 'EnumOptions', name, full_name, file,
+ containing_type, serialized_start=serialized_start,
+ serialized_end=serialized_start)
+
+ self.values = values
+ for value in self.values:
+ value.type = self
+ self.values_by_name = dict((v.name, v) for v in values)
+ self.values_by_number = dict((v.number, v) for v in values)
+
+ self._serialized_start = serialized_start
+ self._serialized_end = serialized_end
+
+ def CopyToProto(self, proto):
+ """Copies this to a descriptor_pb2.EnumDescriptorProto.
+
+ Args:
+ proto: An empty descriptor_pb2.EnumDescriptorProto.
+ """
+ # This function is overriden to give a better doc comment.
+ super(EnumDescriptor, self).CopyToProto(proto)
+
+
+class EnumValueDescriptor(DescriptorBase):
+
+ """Descriptor for a single value within an enum.
+
+ name: (str) Name of this value.
+ index: (int) Dense, 0-indexed index giving the order that this
+ value appears textually within its enum in the .proto file.
+ number: (int) Actual number assigned to this enum value.
+ type: (EnumDescriptor) EnumDescriptor to which this value
+ belongs. Set by EnumDescriptor's constructor if we're
+ passed into one.
+ options: (descriptor_pb2.EnumValueOptions) Enum value options message or
+ None to use default enum value options options.
+ """
+
+ def __init__(self, name, index, number, type=None, options=None):
+ """Arguments are as described in the attribute description above."""
+ super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions')
+ self.name = name
+ self.index = index
+ self.number = number
+ self.type = type
+
+
+class ServiceDescriptor(_NestedDescriptorBase):
+
+ """Descriptor for a service.
+
+ name: (str) Name of the service.
+ full_name: (str) Full name of the service, including package name.
+ index: (int) 0-indexed index giving the order that this services
+ definition appears withing the .proto file.
+ methods: (list of MethodDescriptor) List of methods provided by this
+ service.
+ options: (descriptor_pb2.ServiceOptions) Service options message or
+ None to use default service options.
+ file: (FileDescriptor) Reference to file info.
+ """
+
+ def __init__(self, name, full_name, index, methods, options=None, file=None,
+ serialized_start=None, serialized_end=None):
+ super(ServiceDescriptor, self).__init__(
+ options, 'ServiceOptions', name, full_name, file,
+ None, serialized_start=serialized_start,
+ serialized_end=serialized_end)
+ self.index = index
+ self.methods = methods
+ # Set the containing service for each method in this service.
+ for method in self.methods:
+ method.containing_service = self
+
+ def FindMethodByName(self, name):
+ """Searches for the specified method, and returns its descriptor."""
+ for method in self.methods:
+ if name == method.name:
+ return method
+ return None
+
+ def CopyToProto(self, proto):
+ """Copies this to a descriptor_pb2.ServiceDescriptorProto.
+
+ Args:
+ proto: An empty descriptor_pb2.ServiceDescriptorProto.
+ """
+ # This function is overriden to give a better doc comment.
+ super(ServiceDescriptor, self).CopyToProto(proto)
+
+
+class MethodDescriptor(DescriptorBase):
+
+ """Descriptor for a method in a service.
+
+ name: (str) Name of the method within the service.
+ full_name: (str) Full name of method.
+ index: (int) 0-indexed index of the method inside the service.
+ containing_service: (ServiceDescriptor) The service that contains this
+ method.
+ input_type: The descriptor of the message that this method accepts.
+ output_type: The descriptor of the message that this method returns.
+ options: (descriptor_pb2.MethodOptions) Method options message or
+ None to use default method options.
+ """
+
+ def __init__(self, name, full_name, index, containing_service,
+ input_type, output_type, options=None):
+ """The arguments are as described in the description of MethodDescriptor
+ attributes above.
+
+ Note that containing_service may be None, and may be set later if necessary.
+ """
+ super(MethodDescriptor, self).__init__(options, 'MethodOptions')
+ self.name = name
+ self.full_name = full_name
+ self.index = index
+ self.containing_service = containing_service
+ self.input_type = input_type
+ self.output_type = output_type
+
+
+class FileDescriptor(DescriptorBase):
+ """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto.
+
+ name: name of file, relative to root of source tree.
+ package: name of the package
+ serialized_pb: (str) Byte string of serialized
+ descriptor_pb2.FileDescriptorProto.
+ """
+
+ def __init__(self, name, package, options=None, serialized_pb=None):
+ """Constructor."""
+ super(FileDescriptor, self).__init__(options, 'FileOptions')
+
+ self.message_types_by_name = {}
+ self.name = name
+ self.package = package
+ self.serialized_pb = serialized_pb
+ if (api_implementation.Type() == 'cpp' and
+ self.serialized_pb is not None):
+ cpp_message.BuildFile(self.serialized_pb)
+
+ def CopyToProto(self, proto):
+ """Copies this to a descriptor_pb2.FileDescriptorProto.
+
+ Args:
+ proto: An empty descriptor_pb2.FileDescriptorProto.
+ """
+ proto.ParseFromString(self.serialized_pb)
+
+
+def _ParseOptions(message, string):
+ """Parses serialized options.
+
+ This helper function is used to parse serialized options in generated
+ proto2 files. It must not be used outside proto2.
+ """
+ message.ParseFromString(string)
+ return message
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/__init__.py b/src/third_party/protobuf/python/google/protobuf/internal/__init__.py
new file mode 100755
index 0000000..8d1c8b6
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/__init__.py
@@ -0,0 +1 @@
+
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/api_implementation.py b/src/third_party/protobuf/python/google/protobuf/internal/api_implementation.py
new file mode 100644
index 0000000..b3e412e
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/api_implementation.py
@@ -0,0 +1,64 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+This module is the central entity that determines which implementation of the
+API is used.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+import os
+# This environment variable can be used to switch to a certain implementation
+# of the Python API. Right now only 'python' and 'cpp' are valid values. Any
+# other value will be ignored.
+_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
+ 'python')
+
+
+if _implementation_type != 'python':
+ # For now, by default use the pure-Python implementation.
+ # The code below checks if the C extension is available and
+ # uses it if it is available.
+ _implementation_type = 'cpp'
+ ## Determine automatically which implementation to use.
+ #try:
+ # from google.protobuf.internal import cpp_message
+ # _implementation_type = 'cpp'
+ #except ImportError, e:
+ # _implementation_type = 'python'
+
+
+# Usage of this function is discouraged. Clients shouldn't care which
+# implementation of the API is in use. Note that there is no guarantee
+# that differences between APIs will be maintained.
+# Please don't use this function if possible.
+def Type():
+ return _implementation_type
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/containers.py b/src/third_party/protobuf/python/google/protobuf/internal/containers.py
new file mode 100755
index 0000000..097a3c2
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/containers.py
@@ -0,0 +1,259 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains container classes to represent different protocol buffer types.
+
+This file defines container classes which represent categories of protocol
+buffer field types which need extra maintenance. Currently these categories
+are:
+ - Repeated scalar fields - These are all repeated fields which aren't
+ composite (e.g. they are of simple types like int32, string, etc).
+ - Repeated composite fields - Repeated fields which are composite. This
+ includes groups and nested messages.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+
+class BaseContainer(object):
+
+ """Base container class."""
+
+ # Minimizes memory usage and disallows assignment to other attributes.
+ __slots__ = ['_message_listener', '_values']
+
+ def __init__(self, message_listener):
+ """
+ Args:
+ message_listener: A MessageListener implementation.
+ The RepeatedScalarFieldContainer will call this object's
+ Modified() method when it is modified.
+ """
+ self._message_listener = message_listener
+ self._values = []
+
+ def __getitem__(self, key):
+ """Retrieves item by the specified key."""
+ return self._values[key]
+
+ def __len__(self):
+ """Returns the number of elements in the container."""
+ return len(self._values)
+
+ def __ne__(self, other):
+ """Checks if another instance isn't equal to this one."""
+ # The concrete classes should define __eq__.
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def __repr__(self):
+ return repr(self._values)
+
+ def sort(self, sort_function=cmp):
+ self._values.sort(sort_function)
+
+
+class RepeatedScalarFieldContainer(BaseContainer):
+
+ """Simple, type-checked, list-like container for holding repeated scalars."""
+
+ # Disallows assignment to other attributes.
+ __slots__ = ['_type_checker']
+
+ def __init__(self, message_listener, type_checker):
+ """
+ Args:
+ message_listener: A MessageListener implementation.
+ The RepeatedScalarFieldContainer will call this object's
+ Modified() method when it is modified.
+ type_checker: A type_checkers.ValueChecker instance to run on elements
+ inserted into this container.
+ """
+ super(RepeatedScalarFieldContainer, self).__init__(message_listener)
+ self._type_checker = type_checker
+
+ def append(self, value):
+ """Appends an item to the list. Similar to list.append()."""
+ self._type_checker.CheckValue(value)
+ self._values.append(value)
+ if not self._message_listener.dirty:
+ self._message_listener.Modified()
+
+ def insert(self, key, value):
+ """Inserts the item at the specified position. Similar to list.insert()."""
+ self._type_checker.CheckValue(value)
+ self._values.insert(key, value)
+ if not self._message_listener.dirty:
+ self._message_listener.Modified()
+
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence. Similar to list.extend()."""
+ if not elem_seq:
+ return
+
+ new_values = []
+ for elem in elem_seq:
+ self._type_checker.CheckValue(elem)
+ new_values.append(elem)
+ self._values.extend(new_values)
+ self._message_listener.Modified()
+
+ def MergeFrom(self, other):
+ """Appends the contents of another repeated field of the same type to this
+ one. We do not check the types of the individual fields.
+ """
+ self._values.extend(other._values)
+ self._message_listener.Modified()
+
+ def remove(self, elem):
+ """Removes an item from the list. Similar to list.remove()."""
+ self._values.remove(elem)
+ self._message_listener.Modified()
+
+ def __setitem__(self, key, value):
+ """Sets the item on the specified position."""
+ self._type_checker.CheckValue(value)
+ self._values[key] = value
+ self._message_listener.Modified()
+
+ def __getslice__(self, start, stop):
+ """Retrieves the subset of items from between the specified indices."""
+ return self._values[start:stop]
+
+ def __setslice__(self, start, stop, values):
+ """Sets the subset of items from between the specified indices."""
+ new_values = []
+ for value in values:
+ self._type_checker.CheckValue(value)
+ new_values.append(value)
+ self._values[start:stop] = new_values
+ self._message_listener.Modified()
+
+ def __delitem__(self, key):
+ """Deletes the item at the specified position."""
+ del self._values[key]
+ self._message_listener.Modified()
+
+ def __delslice__(self, start, stop):
+ """Deletes the subset of items from between the specified indices."""
+ del self._values[start:stop]
+ self._message_listener.Modified()
+
+ def __eq__(self, other):
+ """Compares the current instance with another one."""
+ if self is other:
+ return True
+ # Special case for the same type which should be common and fast.
+ if isinstance(other, self.__class__):
+ return other._values == self._values
+ # We are presumably comparing against some other sequence type.
+ return other == self._values
+
+
+class RepeatedCompositeFieldContainer(BaseContainer):
+
+ """Simple, list-like container for holding repeated composite fields."""
+
+ # Disallows assignment to other attributes.
+ __slots__ = ['_message_descriptor']
+
+ def __init__(self, message_listener, message_descriptor):
+ """
+ Note that we pass in a descriptor instead of the generated directly,
+ since at the time we construct a _RepeatedCompositeFieldContainer we
+ haven't yet necessarily initialized the type that will be contained in the
+ container.
+
+ Args:
+ message_listener: A MessageListener implementation.
+ The RepeatedCompositeFieldContainer will call this object's
+ Modified() method when it is modified.
+ message_descriptor: A Descriptor instance describing the protocol type
+ that should be present in this container. We'll use the
+ _concrete_class field of this descriptor when the client calls add().
+ """
+ super(RepeatedCompositeFieldContainer, self).__init__(message_listener)
+ self._message_descriptor = message_descriptor
+
+ def add(self, **kwargs):
+ """Adds a new element at the end of the list and returns it. Keyword
+ arguments may be used to initialize the element.
+ """
+ new_element = self._message_descriptor._concrete_class(**kwargs)
+ new_element._SetListener(self._message_listener)
+ self._values.append(new_element)
+ if not self._message_listener.dirty:
+ self._message_listener.Modified()
+ return new_element
+
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence of elements of the same type
+ as this one, copying each individual message.
+ """
+ message_class = self._message_descriptor._concrete_class
+ listener = self._message_listener
+ values = self._values
+ for message in elem_seq:
+ new_element = message_class()
+ new_element._SetListener(listener)
+ new_element.MergeFrom(message)
+ values.append(new_element)
+ listener.Modified()
+
+ def MergeFrom(self, other):
+ """Appends the contents of another repeated field of the same type to this
+ one, copying each individual message.
+ """
+ self.extend(other._values)
+
+ def __getslice__(self, start, stop):
+ """Retrieves the subset of items from between the specified indices."""
+ return self._values[start:stop]
+
+ def __delitem__(self, key):
+ """Deletes the item at the specified position."""
+ del self._values[key]
+ self._message_listener.Modified()
+
+ def __delslice__(self, start, stop):
+ """Deletes the subset of items from between the specified indices."""
+ del self._values[start:stop]
+ self._message_listener.Modified()
+
+ def __eq__(self, other):
+ """Compares the current instance with another one."""
+ if self is other:
+ return True
+ if not isinstance(other, self.__class__):
+ raise TypeError('Can only compare repeated composite fields against '
+ 'other repeated composite fields.')
+ return self._values == other._values
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/cpp_message.py b/src/third_party/protobuf/python/google/protobuf/internal/cpp_message.py
new file mode 100644
index 0000000..3f42650
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/cpp_message.py
@@ -0,0 +1,616 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains helper functions used to create protocol message classes from
+Descriptor objects at runtime backed by the protocol buffer C++ API.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+import operator
+from google.protobuf.internal import _net_proto2___python
+from google.protobuf import message
+
+
+_LABEL_REPEATED = _net_proto2___python.LABEL_REPEATED
+_LABEL_OPTIONAL = _net_proto2___python.LABEL_OPTIONAL
+_CPPTYPE_MESSAGE = _net_proto2___python.CPPTYPE_MESSAGE
+_TYPE_MESSAGE = _net_proto2___python.TYPE_MESSAGE
+
+
+def GetDescriptorPool():
+ """Creates a new DescriptorPool C++ object."""
+ return _net_proto2___python.NewCDescriptorPool()
+
+
+_pool = GetDescriptorPool()
+
+
+def GetFieldDescriptor(full_field_name):
+ """Searches for a field descriptor given a full field name."""
+ return _pool.FindFieldByName(full_field_name)
+
+
+def BuildFile(content):
+ """Registers a new proto file in the underlying C++ descriptor pool."""
+ _net_proto2___python.BuildFile(content)
+
+
+def GetExtensionDescriptor(full_extension_name):
+ """Searches for extension descriptor given a full field name."""
+ return _pool.FindExtensionByName(full_extension_name)
+
+
+def NewCMessage(full_message_name):
+ """Creates a new C++ protocol message by its name."""
+ return _net_proto2___python.NewCMessage(full_message_name)
+
+
+def ScalarProperty(cdescriptor):
+ """Returns a scalar property for the given descriptor."""
+
+ def Getter(self):
+ return self._cmsg.GetScalar(cdescriptor)
+
+ def Setter(self, value):
+ self._cmsg.SetScalar(cdescriptor, value)
+
+ return property(Getter, Setter)
+
+
+def CompositeProperty(cdescriptor, message_type):
+ """Returns a Python property the given composite field."""
+
+ def Getter(self):
+ sub_message = self._composite_fields.get(cdescriptor.name, None)
+ if sub_message is None:
+ cmessage = self._cmsg.NewSubMessage(cdescriptor)
+ sub_message = message_type._concrete_class(__cmessage=cmessage)
+ self._composite_fields[cdescriptor.name] = sub_message
+ return sub_message
+
+ return property(Getter)
+
+
+class RepeatedScalarContainer(object):
+ """Container for repeated scalar fields."""
+
+ __slots__ = ['_message', '_cfield_descriptor', '_cmsg']
+
+ def __init__(self, msg, cfield_descriptor):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._cfield_descriptor = cfield_descriptor
+
+ def append(self, value):
+ self._cmsg.AddRepeatedScalar(
+ self._cfield_descriptor, value)
+
+ def extend(self, sequence):
+ for element in sequence:
+ self.append(element)
+
+ def insert(self, key, value):
+ values = self[slice(None, None, None)]
+ values.insert(key, value)
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def remove(self, value):
+ values = self[slice(None, None, None)]
+ values.remove(value)
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def __setitem__(self, key, value):
+ values = self[slice(None, None, None)]
+ values[key] = value
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+ def __getitem__(self, key):
+ return self._cmsg.GetRepeatedScalar(self._cfield_descriptor, key)
+
+ def __delitem__(self, key):
+ self._cmsg.DeleteRepeatedField(self._cfield_descriptor, key)
+
+ def __len__(self):
+ return len(self[slice(None, None, None)])
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not operator.isSequenceType(other):
+ raise TypeError(
+ 'Can only compare repeated scalar fields against sequences.')
+ # We are presumably comparing against some other sequence type.
+ return other == self[slice(None, None, None)]
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def sort(self, sort_function=cmp):
+ values = self[slice(None, None, None)]
+ values.sort(sort_function)
+ self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+
+def RepeatedScalarProperty(cdescriptor):
+ """Returns a Python property the given repeated scalar field."""
+
+ def Getter(self):
+ container = self._composite_fields.get(cdescriptor.name, None)
+ if container is None:
+ container = RepeatedScalarContainer(self, cdescriptor)
+ self._composite_fields[cdescriptor.name] = container
+ return container
+
+ def Setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % cdescriptor.name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
+ return property(Getter, Setter, doc=doc)
+
+
+class RepeatedCompositeContainer(object):
+ """Container for repeated composite fields."""
+
+ __slots__ = ['_message', '_subclass', '_cfield_descriptor', '_cmsg']
+
+ def __init__(self, msg, cfield_descriptor, subclass):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._subclass = subclass
+ self._cfield_descriptor = cfield_descriptor
+
+ def add(self, **kwargs):
+ cmessage = self._cmsg.AddMessage(self._cfield_descriptor)
+ return self._subclass(__cmessage=cmessage, __owner=self._message, **kwargs)
+
+ def extend(self, elem_seq):
+ """Extends by appending the given sequence of elements of the same type
+ as this one, copying each individual message.
+ """
+ for message in elem_seq:
+ self.add().MergeFrom(message)
+
+ def MergeFrom(self, other):
+ for message in other[:]:
+ self.add().MergeFrom(message)
+
+ def __getitem__(self, key):
+ cmessages = self._cmsg.GetRepeatedMessage(
+ self._cfield_descriptor, key)
+ subclass = self._subclass
+ if not isinstance(cmessages, list):
+ return subclass(__cmessage=cmessages, __owner=self._message)
+
+ return [subclass(__cmessage=m, __owner=self._message) for m in cmessages]
+
+ def __delitem__(self, key):
+ self._cmsg.DeleteRepeatedField(
+ self._cfield_descriptor, key)
+
+ def __len__(self):
+ return self._cmsg.FieldLength(self._cfield_descriptor)
+
+ def __eq__(self, other):
+ """Compares the current instance with another one."""
+ if self is other:
+ return True
+ if not isinstance(other, self.__class__):
+ raise TypeError('Can only compare repeated composite fields against '
+ 'other repeated composite fields.')
+ messages = self[slice(None, None, None)]
+ other_messages = other[slice(None, None, None)]
+ return messages == other_messages
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def sort(self, sort_function=cmp):
+ messages = []
+ for index in range(len(self)):
+ # messages[i][0] is where the i-th element of the new array has to come
+ # from.
+ # messages[i][1] is where the i-th element of the old array has to go.
+ messages.append([index, 0, self[index]])
+ messages.sort(lambda x,y: sort_function(x[2], y[2]))
+
+ # Remember which position each elements has to move to.
+ for i in range(len(messages)):
+ messages[messages[i][0]][1] = i
+
+ # Apply the transposition.
+ for i in range(len(messages)):
+ from_position = messages[i][0]
+ if i == from_position:
+ continue
+ self._cmsg.SwapRepeatedFieldElements(
+ self._cfield_descriptor, i, from_position)
+ messages[messages[i][1]][0] = from_position
+
+
+def RepeatedCompositeProperty(cdescriptor, message_type):
+ """Returns a Python property for the given repeated composite field."""
+
+ def Getter(self):
+ container = self._composite_fields.get(cdescriptor.name, None)
+ if container is None:
+ container = RepeatedCompositeContainer(
+ self, cdescriptor, message_type._concrete_class)
+ self._composite_fields[cdescriptor.name] = container
+ return container
+
+ def Setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % cdescriptor.name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
+ return property(Getter, Setter, doc=doc)
+
+
+class ExtensionDict(object):
+ """Extension dictionary added to each protocol message."""
+
+ def __init__(self, msg):
+ self._message = msg
+ self._cmsg = msg._cmsg
+ self._values = {}
+
+ def __setitem__(self, extension, value):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_OPTIONAL or
+ cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ raise TypeError('Extension %r is repeated and/or a composite type.' % (
+ extension.full_name,))
+ self._cmsg.SetScalar(cdescriptor, value)
+ self._values[extension] = value
+
+ def __getitem__(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_REPEATED and
+ cdescriptor.cpp_type != _CPPTYPE_MESSAGE):
+ return self._cmsg.GetScalar(cdescriptor)
+
+ ext = self._values.get(extension, None)
+ if ext is not None:
+ return ext
+
+ ext = self._CreateNewHandle(extension)
+ self._values[extension] = ext
+ return ext
+
+ def ClearExtension(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ self._cmsg.ClearFieldByDescriptor(extension._cdescriptor)
+ if extension in self._values:
+ del self._values[extension]
+
+ def HasExtension(self, extension):
+ from google.protobuf import descriptor
+ if not isinstance(extension, descriptor.FieldDescriptor):
+ raise KeyError('Bad extension %r.' % (extension,))
+ return self._cmsg.HasFieldByDescriptor(extension._cdescriptor)
+
+ def _FindExtensionByName(self, name):
+ """Tries to find a known extension with the specified name.
+
+ Args:
+ name: Extension full name.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._message._extensions_by_name.get(name, None)
+
+ def _CreateNewHandle(self, extension):
+ cdescriptor = extension._cdescriptor
+ if (cdescriptor.label != _LABEL_REPEATED and
+ cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+ cmessage = self._cmsg.NewSubMessage(cdescriptor)
+ return extension.message_type._concrete_class(__cmessage=cmessage)
+
+ if cdescriptor.label == _LABEL_REPEATED:
+ if cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ return RepeatedCompositeContainer(
+ self._message, cdescriptor, extension.message_type._concrete_class)
+ else:
+ return RepeatedScalarContainer(self._message, cdescriptor)
+ # This shouldn't happen!
+ assert False
+ return None
+
+
+def NewMessage(message_descriptor, dictionary):
+ """Creates a new protocol message *class*."""
+ _AddClassAttributesForNestedExtensions(message_descriptor, dictionary)
+ _AddEnumValues(message_descriptor, dictionary)
+ _AddDescriptors(message_descriptor, dictionary)
+
+
+def InitMessage(message_descriptor, cls):
+ """Constructs a new message instance (called before instance's __init__)."""
+ cls._extensions_by_name = {}
+ _AddInitMethod(message_descriptor, cls)
+ _AddMessageMethods(message_descriptor, cls)
+ _AddPropertiesForExtensions(message_descriptor, cls)
+
+
+def _AddDescriptors(message_descriptor, dictionary):
+ """Sets up a new protocol message class dictionary.
+
+ Args:
+ message_descriptor: A Descriptor instance describing this message type.
+ dictionary: Class dictionary to which we'll add a '__slots__' entry.
+ """
+ dictionary['__descriptors'] = {}
+ for field in message_descriptor.fields:
+ dictionary['__descriptors'][field.name] = GetFieldDescriptor(
+ field.full_name)
+
+ dictionary['__slots__'] = list(dictionary['__descriptors'].iterkeys()) + [
+ '_cmsg', '_owner', '_composite_fields', 'Extensions']
+
+
+def _AddEnumValues(message_descriptor, dictionary):
+ """Sets class-level attributes for all enum fields defined in this message.
+
+ Args:
+ message_descriptor: Descriptor object for this message type.
+ dictionary: Class dictionary that should be populated.
+ """
+ for enum_type in message_descriptor.enum_types:
+ for enum_value in enum_type.values:
+ dictionary[enum_value.name] = enum_value.number
+
+
+def _AddClassAttributesForNestedExtensions(message_descriptor, dictionary):
+ """Adds class attributes for the nested extensions."""
+ extension_dict = message_descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ assert extension_name not in dictionary
+ dictionary[extension_name] = extension_field
+
+
+def _AddInitMethod(message_descriptor, cls):
+ """Adds an __init__ method to cls."""
+
+ # Create and attach message field properties to the message class.
+ # This can be done just once per message class, since property setters and
+ # getters are passed the message instance.
+ # This makes message instantiation extremely fast, and at the same time it
+ # doesn't require the creation of property objects for each message instance,
+ # which saves a lot of memory.
+ for field in message_descriptor.fields:
+ field_cdescriptor = cls.__descriptors[field.name]
+ if field.label == _LABEL_REPEATED:
+ if field.cpp_type == _CPPTYPE_MESSAGE:
+ value = RepeatedCompositeProperty(field_cdescriptor, field.message_type)
+ else:
+ value = RepeatedScalarProperty(field_cdescriptor)
+ elif field.cpp_type == _CPPTYPE_MESSAGE:
+ value = CompositeProperty(field_cdescriptor, field.message_type)
+ else:
+ value = ScalarProperty(field_cdescriptor)
+ setattr(cls, field.name, value)
+
+ # Attach a constant with the field number.
+ constant_name = field.name.upper() + '_FIELD_NUMBER'
+ setattr(cls, constant_name, field.number)
+
+ def Init(self, **kwargs):
+ """Message constructor."""
+ cmessage = kwargs.pop('__cmessage', None)
+ if cmessage is None:
+ self._cmsg = NewCMessage(message_descriptor.full_name)
+ else:
+ self._cmsg = cmessage
+
+ # Keep a reference to the owner, as the owner keeps a reference to the
+ # underlying protocol buffer message.
+ owner = kwargs.pop('__owner', None)
+ if owner is not None:
+ self._owner = owner
+
+ self.Extensions = ExtensionDict(self)
+ self._composite_fields = {}
+
+ for field_name, field_value in kwargs.iteritems():
+ field_cdescriptor = self.__descriptors.get(field_name, None)
+ if field_cdescriptor is None:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+ if field_cdescriptor.label == _LABEL_REPEATED:
+ if field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ for val in field_value:
+ getattr(self, field_name).add().MergeFrom(val)
+ else:
+ getattr(self, field_name).extend(field_value)
+ elif field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+ getattr(self, field_name).MergeFrom(field_value)
+ else:
+ setattr(self, field_name, field_value)
+
+ Init.__module__ = None
+ Init.__doc__ = None
+ cls.__init__ = Init
+
+
+def _IsMessageSetExtension(field):
+ """Checks if a field is a message set extension."""
+ return (field.is_extension and
+ field.containing_type.has_options and
+ field.containing_type.GetOptions().message_set_wire_format and
+ field.type == _TYPE_MESSAGE and
+ field.message_type == field.extension_scope and
+ field.label == _LABEL_OPTIONAL)
+
+
+def _AddMessageMethods(message_descriptor, cls):
+ """Adds the methods to a protocol message class."""
+ if message_descriptor.is_extendable:
+
+ def ClearExtension(self, extension):
+ self.Extensions.ClearExtension(extension)
+
+ def HasExtension(self, extension):
+ return self.Extensions.HasExtension(extension)
+
+ def HasField(self, field_name):
+ return self._cmsg.HasField(field_name)
+
+ def ClearField(self, field_name):
+ if field_name in self._composite_fields:
+ del self._composite_fields[field_name]
+ self._cmsg.ClearField(field_name)
+
+ def Clear(self):
+ return self._cmsg.Clear()
+
+ def IsInitialized(self, errors=None):
+ if self._cmsg.IsInitialized():
+ return True
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors());
+ return False
+
+ def SerializeToString(self):
+ if not self.IsInitialized():
+ raise message.EncodeError(
+ 'Message is missing required fields: ' +
+ ','.join(self.FindInitializationErrors()))
+ return self._cmsg.SerializeToString()
+
+ def SerializePartialToString(self):
+ return self._cmsg.SerializePartialToString()
+
+ def ParseFromString(self, serialized):
+ self.Clear()
+ self.MergeFromString(serialized)
+
+ def MergeFromString(self, serialized):
+ byte_size = self._cmsg.MergeFromString(serialized)
+ if byte_size < 0:
+ raise message.DecodeError('Unable to merge from string.')
+ return byte_size
+
+ def MergeFrom(self, msg):
+ if not isinstance(msg, cls):
+ raise TypeError(
+ "Parameter to MergeFrom() must be instance of same class.")
+ self._cmsg.MergeFrom(msg._cmsg)
+
+ def CopyFrom(self, msg):
+ self._cmsg.CopyFrom(msg._cmsg)
+
+ def ByteSize(self):
+ return self._cmsg.ByteSize()
+
+ def SetInParent(self):
+ return self._cmsg.SetInParent()
+
+ def ListFields(self):
+ all_fields = []
+ field_list = self._cmsg.ListFields()
+ fields_by_name = cls.DESCRIPTOR.fields_by_name
+ for is_extension, field_name in field_list:
+ if is_extension:
+ extension = cls._extensions_by_name[field_name]
+ all_fields.append((extension, self.Extensions[extension]))
+ else:
+ field_descriptor = fields_by_name[field_name]
+ all_fields.append(
+ (field_descriptor, getattr(self, field_name)))
+ all_fields.sort(key=lambda item: item[0].number)
+ return all_fields
+
+ def FindInitializationErrors(self):
+ return self._cmsg.FindInitializationErrors()
+
+ def __str__(self):
+ return self._cmsg.DebugString()
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not isinstance(other, self.__class__):
+ return False
+ return self.ListFields() == other.ListFields()
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def __unicode__(self):
+ return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
+
+ # Attach the local methods to the message class.
+ for key, value in locals().copy().iteritems():
+ if key not in ('key', 'value', '__builtins__', '__name__', '__doc__'):
+ setattr(cls, key, value)
+
+ # Static methods:
+
+ def RegisterExtension(extension_handle):
+ extension_handle.containing_type = cls.DESCRIPTOR
+ cls._extensions_by_name[extension_handle.full_name] = extension_handle
+
+ if _IsMessageSetExtension(extension_handle):
+ # MessageSet extension. Also register under type name.
+ cls._extensions_by_name[
+ extension_handle.message_type.full_name] = extension_handle
+ cls.RegisterExtension = staticmethod(RegisterExtension)
+
+ def FromString(string):
+ msg = cls()
+ msg.MergeFromString(string)
+ return msg
+ cls.FromString = staticmethod(FromString)
+
+
+
+def _AddPropertiesForExtensions(message_descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ extension_dict = message_descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ constant_name = extension_name.upper() + '_FIELD_NUMBER'
+ setattr(cls, constant_name, extension_field.number)
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/decoder.py b/src/third_party/protobuf/python/google/protobuf/internal/decoder.py
new file mode 100755
index 0000000..55f746f
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/decoder.py
@@ -0,0 +1,714 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Code for decoding protocol buffer primitives.
+
+This code is very similar to encoder.py -- read the docs for that module first.
+
+A "decoder" is a function with the signature:
+ Decode(buffer, pos, end, message, field_dict)
+The arguments are:
+ buffer: The string containing the encoded message.
+ pos: The current position in the string.
+ end: The position in the string where the current message ends. May be
+ less than len(buffer) if we're reading a sub-message.
+ message: The message object into which we're parsing.
+ field_dict: message._fields (avoids a hashtable lookup).
+The decoder reads the field and stores it into field_dict, returning the new
+buffer position. A decoder for a repeated field may proactively decode all of
+the elements of that field, if they appear consecutively.
+
+Note that decoders may throw any of the following:
+ IndexError: Indicates a truncated message.
+ struct.error: Unpacking of a fixed-width field failed.
+ message.DecodeError: Other errors.
+
+Decoders are expected to raise an exception if they are called with pos > end.
+This allows callers to be lax about bounds checking: it's fineto read past
+"end" as long as you are sure that someone else will notice and throw an
+exception later on.
+
+Something up the call stack is expected to catch IndexError and struct.error
+and convert them to message.DecodeError.
+
+Decoders are constructed using decoder constructors with the signature:
+ MakeDecoder(field_number, is_repeated, is_packed, key, new_default)
+The arguments are:
+ field_number: The field number of the field we want to decode.
+ is_repeated: Is the field a repeated field? (bool)
+ is_packed: Is the field a packed field? (bool)
+ key: The key to use when looking up the field within field_dict.
+ (This is actually the FieldDescriptor but nothing in this
+ file should depend on that.)
+ new_default: A function which takes a message object as a parameter and
+ returns a new instance of the default value for this field.
+ (This is called for repeated fields and sub-messages, when an
+ instance does not already exist.)
+
+As with encoders, we define a decoder constructor for every type of field.
+Then, for every field of every message class we construct an actual decoder.
+That decoder goes into a dict indexed by tag, so when we decode a message
+we repeatedly read a tag, look up the corresponding decoder, and invoke it.
+"""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import struct
+from google.protobuf.internal import encoder
+from google.protobuf.internal import wire_format
+from google.protobuf import message
+
+
+# This will overflow and thus become IEEE-754 "infinity". We would use
+# "float('inf')" but it doesn't work on Windows pre-Python-2.6.
+_POS_INF = 1e10000
+_NEG_INF = -_POS_INF
+_NAN = _POS_INF * 0
+
+
+# This is not for optimization, but rather to avoid conflicts with local
+# variables named "message".
+_DecodeError = message.DecodeError
+
+
+def _VarintDecoder(mask):
+ """Return an encoder for a basic varint value (does not include tag).
+
+ Decoded values will be bitwise-anded with the given mask before being
+ returned, e.g. to limit them to 32 bits. The returned decoder does not
+ take the usual "end" parameter -- the caller is expected to do bounds checking
+ after the fact (often the caller can defer such checking until later). The
+ decoder returns a (value, new_pos) pair.
+ """
+
+ local_ord = ord
+ def DecodeVarint(buffer, pos):
+ result = 0
+ shift = 0
+ while 1:
+ b = local_ord(buffer[pos])
+ result |= ((b & 0x7f) << shift)
+ pos += 1
+ if not (b & 0x80):
+ result &= mask
+ return (result, pos)
+ shift += 7
+ if shift >= 64:
+ raise _DecodeError('Too many bytes when decoding varint.')
+ return DecodeVarint
+
+
+def _SignedVarintDecoder(mask):
+ """Like _VarintDecoder() but decodes signed values."""
+
+ local_ord = ord
+ def DecodeVarint(buffer, pos):
+ result = 0
+ shift = 0
+ while 1:
+ b = local_ord(buffer[pos])
+ result |= ((b & 0x7f) << shift)
+ pos += 1
+ if not (b & 0x80):
+ if result > 0x7fffffffffffffff:
+ result -= (1 << 64)
+ result |= ~mask
+ else:
+ result &= mask
+ return (result, pos)
+ shift += 7
+ if shift >= 64:
+ raise _DecodeError('Too many bytes when decoding varint.')
+ return DecodeVarint
+
+
+_DecodeVarint = _VarintDecoder((1 << 64) - 1)
+_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1)
+
+# Use these versions for values which must be limited to 32 bits.
+_DecodeVarint32 = _VarintDecoder((1 << 32) - 1)
+_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1)
+
+
+def ReadTag(buffer, pos):
+ """Read a tag from the buffer, and return a (tag_bytes, new_pos) tuple.
+
+ We return the raw bytes of the tag rather than decoding them. The raw
+ bytes can then be used to look up the proper decoder. This effectively allows
+ us to trade some work that would be done in pure-python (decoding a varint)
+ for work that is done in C (searching for a byte string in a hash table).
+ In a low-level language it would be much cheaper to decode the varint and
+ use that, but not in Python.
+ """
+
+ start = pos
+ while ord(buffer[pos]) & 0x80:
+ pos += 1
+ pos += 1
+ return (buffer[start:pos], pos)
+
+
+# --------------------------------------------------------------------
+
+
+def _SimpleDecoder(wire_type, decode_value):
+ """Return a constructor for a decoder for fields of a particular type.
+
+ Args:
+ wire_type: The field's wire type.
+ decode_value: A function which decodes an individual value, e.g.
+ _DecodeVarint()
+ """
+
+ def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default):
+ if is_packed:
+ local_DecodeVarint = _DecodeVarint
+ def DecodePackedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ (endpoint, pos) = local_DecodeVarint(buffer, pos)
+ endpoint += pos
+ if endpoint > end:
+ raise _DecodeError('Truncated message.')
+ while pos < endpoint:
+ (element, pos) = decode_value(buffer, pos)
+ value.append(element)
+ if pos > endpoint:
+ del value[-1] # Discard corrupt value.
+ raise _DecodeError('Packed element was truncated.')
+ return pos
+ return DecodePackedField
+ elif is_repeated:
+ tag_bytes = encoder.TagBytes(field_number, wire_type)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ (element, new_pos) = decode_value(buffer, pos)
+ value.append(element)
+ # Predict that the next tag is another copy of the same repeated
+ # field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos >= end:
+ # Prediction failed. Return.
+ if new_pos > end:
+ raise _DecodeError('Truncated message.')
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ (field_dict[key], pos) = decode_value(buffer, pos)
+ if pos > end:
+ del field_dict[key] # Discard corrupt value.
+ raise _DecodeError('Truncated message.')
+ return pos
+ return DecodeField
+
+ return SpecificDecoder
+
+
+def _ModifiedDecoder(wire_type, decode_value, modify_value):
+ """Like SimpleDecoder but additionally invokes modify_value on every value
+ before storing it. Usually modify_value is ZigZagDecode.
+ """
+
+ # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but
+ # not enough to make a significant difference.
+
+ def InnerDecode(buffer, pos):
+ (result, new_pos) = decode_value(buffer, pos)
+ return (modify_value(result), new_pos)
+ return _SimpleDecoder(wire_type, InnerDecode)
+
+
+def _StructPackDecoder(wire_type, format):
+ """Return a constructor for a decoder for a fixed-width field.
+
+ Args:
+ wire_type: The field's wire type.
+ format: The format string to pass to struct.unpack().
+ """
+
+ value_size = struct.calcsize(format)
+ local_unpack = struct.unpack
+
+ # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but
+ # not enough to make a significant difference.
+
+ # Note that we expect someone up-stack to catch struct.error and convert
+ # it to _DecodeError -- this way we don't have to set up exception-
+ # handling blocks every time we parse one value.
+
+ def InnerDecode(buffer, pos):
+ new_pos = pos + value_size
+ result = local_unpack(format, buffer[pos:new_pos])[0]
+ return (result, new_pos)
+ return _SimpleDecoder(wire_type, InnerDecode)
+
+
+def _FloatDecoder():
+ """Returns a decoder for a float field.
+
+ This code works around a bug in struct.unpack for non-finite 32-bit
+ floating-point values.
+ """
+
+ local_unpack = struct.unpack
+
+ def InnerDecode(buffer, pos):
+ # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign
+ # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand.
+ new_pos = pos + 4
+ float_bytes = buffer[pos:new_pos]
+
+ # If this value has all its exponent bits set, then it's non-finite.
+ # In Python 2.4, struct.unpack will convert it to a finite 64-bit value.
+ # To avoid that, we parse it specially.
+ if ((float_bytes[3] in '\x7F\xFF')
+ and (float_bytes[2] >= '\x80')):
+ # If at least one significand bit is set...
+ if float_bytes[0:3] != '\x00\x00\x80':
+ return (_NAN, new_pos)
+ # If sign bit is set...
+ if float_bytes[3] == '\xFF':
+ return (_NEG_INF, new_pos)
+ return (_POS_INF, new_pos)
+
+ # Note that we expect someone up-stack to catch struct.error and convert
+ # it to _DecodeError -- this way we don't have to set up exception-
+ # handling blocks every time we parse one value.
+ result = local_unpack('<f', float_bytes)[0]
+ return (result, new_pos)
+ return _SimpleDecoder(wire_format.WIRETYPE_FIXED32, InnerDecode)
+
+
+def _DoubleDecoder():
+ """Returns a decoder for a double field.
+
+ This code works around a bug in struct.unpack for not-a-number.
+ """
+
+ local_unpack = struct.unpack
+
+ def InnerDecode(buffer, pos):
+ # We expect a 64-bit value in little-endian byte order. Bit 1 is the sign
+ # bit, bits 2-12 represent the exponent, and bits 13-64 are the significand.
+ new_pos = pos + 8
+ double_bytes = buffer[pos:new_pos]
+
+ # If this value has all its exponent bits set and at least one significand
+ # bit set, it's not a number. In Python 2.4, struct.unpack will treat it
+ # as inf or -inf. To avoid that, we treat it specially.
+ if ((double_bytes[7] in '\x7F\xFF')
+ and (double_bytes[6] >= '\xF0')
+ and (double_bytes[0:7] != '\x00\x00\x00\x00\x00\x00\xF0')):
+ return (_NAN, new_pos)
+
+ # Note that we expect someone up-stack to catch struct.error and convert
+ # it to _DecodeError -- this way we don't have to set up exception-
+ # handling blocks every time we parse one value.
+ result = local_unpack('<d', double_bytes)[0]
+ return (result, new_pos)
+ return _SimpleDecoder(wire_format.WIRETYPE_FIXED64, InnerDecode)
+
+
+# --------------------------------------------------------------------
+
+
+Int32Decoder = EnumDecoder = _SimpleDecoder(
+ wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32)
+
+Int64Decoder = _SimpleDecoder(
+ wire_format.WIRETYPE_VARINT, _DecodeSignedVarint)
+
+UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32)
+UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint)
+
+SInt32Decoder = _ModifiedDecoder(
+ wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode)
+SInt64Decoder = _ModifiedDecoder(
+ wire_format.WIRETYPE_VARINT, _DecodeVarint, wire_format.ZigZagDecode)
+
+# Note that Python conveniently guarantees that when using the '<' prefix on
+# formats, they will also have the same size across all platforms (as opposed
+# to without the prefix, where their sizes depend on the C compiler's basic
+# type sizes).
+Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<I')
+Fixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<Q')
+SFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<i')
+SFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<q')
+FloatDecoder = _FloatDecoder()
+DoubleDecoder = _DoubleDecoder()
+
+BoolDecoder = _ModifiedDecoder(
+ wire_format.WIRETYPE_VARINT, _DecodeVarint, bool)
+
+
+def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
+ """Returns a decoder for a string field."""
+
+ local_DecodeVarint = _DecodeVarint
+ local_unicode = unicode
+
+ assert not is_packed
+ if is_repeated:
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_LENGTH_DELIMITED)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated string.')
+ value.append(local_unicode(buffer[pos:new_pos], 'utf-8'))
+ # Predict that the next tag is another copy of the same repeated field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+ # Prediction failed. Return.
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated string.')
+ field_dict[key] = local_unicode(buffer[pos:new_pos], 'utf-8')
+ return new_pos
+ return DecodeField
+
+
+def BytesDecoder(field_number, is_repeated, is_packed, key, new_default):
+ """Returns a decoder for a bytes field."""
+
+ local_DecodeVarint = _DecodeVarint
+
+ assert not is_packed
+ if is_repeated:
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_LENGTH_DELIMITED)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated string.')
+ value.append(buffer[pos:new_pos])
+ # Predict that the next tag is another copy of the same repeated field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+ # Prediction failed. Return.
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated string.')
+ field_dict[key] = buffer[pos:new_pos]
+ return new_pos
+ return DecodeField
+
+
+def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
+ """Returns a decoder for a group field."""
+
+ end_tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_END_GROUP)
+ end_tag_len = len(end_tag_bytes)
+
+ assert not is_packed
+ if is_repeated:
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_START_GROUP)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ # Read sub-message.
+ pos = value.add()._InternalParse(buffer, pos, end)
+ # Read end tag.
+ new_pos = pos+end_tag_len
+ if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
+ raise _DecodeError('Missing group end tag.')
+ # Predict that the next tag is another copy of the same repeated field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+ # Prediction failed. Return.
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ # Read sub-message.
+ pos = value._InternalParse(buffer, pos, end)
+ # Read end tag.
+ new_pos = pos+end_tag_len
+ if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
+ raise _DecodeError('Missing group end tag.')
+ return new_pos
+ return DecodeField
+
+
+def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
+ """Returns a decoder for a message field."""
+
+ local_DecodeVarint = _DecodeVarint
+
+ assert not is_packed
+ if is_repeated:
+ tag_bytes = encoder.TagBytes(field_number,
+ wire_format.WIRETYPE_LENGTH_DELIMITED)
+ tag_len = len(tag_bytes)
+ def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ while 1:
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ # Read length.
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated message.')
+ # Read sub-message.
+ if value.add()._InternalParse(buffer, pos, new_pos) != new_pos:
+ # The only reason _InternalParse would return early is if it
+ # encountered an end-group tag.
+ raise _DecodeError('Unexpected end-group tag.')
+ # Predict that the next tag is another copy of the same repeated field.
+ pos = new_pos + tag_len
+ if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+ # Prediction failed. Return.
+ return new_pos
+ return DecodeRepeatedField
+ else:
+ def DecodeField(buffer, pos, end, message, field_dict):
+ value = field_dict.get(key)
+ if value is None:
+ value = field_dict.setdefault(key, new_default(message))
+ # Read length.
+ (size, pos) = local_DecodeVarint(buffer, pos)
+ new_pos = pos + size
+ if new_pos > end:
+ raise _DecodeError('Truncated message.')
+ # Read sub-message.
+ if value._InternalParse(buffer, pos, new_pos) != new_pos:
+ # The only reason _InternalParse would return early is if it encountered
+ # an end-group tag.
+ raise _DecodeError('Unexpected end-group tag.')
+ return new_pos
+ return DecodeField
+
+
+# --------------------------------------------------------------------
+
+MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP)
+
+def MessageSetItemDecoder(extensions_by_number):
+ """Returns a decoder for a MessageSet item.
+
+ The parameter is the _extensions_by_number map for the message class.
+
+ The message set message looks like this:
+ message MessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required string message = 3;
+ }
+ }
+ """
+
+ type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT)
+ message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP)
+
+ local_ReadTag = ReadTag
+ local_DecodeVarint = _DecodeVarint
+ local_SkipField = SkipField
+
+ def DecodeItem(buffer, pos, end, message, field_dict):
+ type_id = -1
+ message_start = -1
+ message_end = -1
+
+ # Technically, type_id and message can appear in any order, so we need
+ # a little loop here.
+ while 1:
+ (tag_bytes, pos) = local_ReadTag(buffer, pos)
+ if tag_bytes == type_id_tag_bytes:
+ (type_id, pos) = local_DecodeVarint(buffer, pos)
+ elif tag_bytes == message_tag_bytes:
+ (size, message_start) = local_DecodeVarint(buffer, pos)
+ pos = message_end = message_start + size
+ elif tag_bytes == item_end_tag_bytes:
+ break
+ else:
+ pos = SkipField(buffer, pos, end, tag_bytes)
+ if pos == -1:
+ raise _DecodeError('Missing group end tag.')
+
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+
+ if type_id == -1:
+ raise _DecodeError('MessageSet item missing type_id.')
+ if message_start == -1:
+ raise _DecodeError('MessageSet item missing message.')
+
+ extension = extensions_by_number.get(type_id)
+ if extension is not None:
+ value = field_dict.get(extension)
+ if value is None:
+ value = field_dict.setdefault(
+ extension, extension.message_type._concrete_class())
+ if value._InternalParse(buffer, message_start,message_end) != message_end:
+ # The only reason _InternalParse would return early is if it encountered
+ # an end-group tag.
+ raise _DecodeError('Unexpected end-group tag.')
+
+ return pos
+
+ return DecodeItem
+
+# --------------------------------------------------------------------
+# Optimization is not as heavy here because calls to SkipField() are rare,
+# except for handling end-group tags.
+
+def _SkipVarint(buffer, pos, end):
+ """Skip a varint value. Returns the new position."""
+
+ while ord(buffer[pos]) & 0x80:
+ pos += 1
+ pos += 1
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ return pos
+
+def _SkipFixed64(buffer, pos, end):
+ """Skip a fixed64 value. Returns the new position."""
+
+ pos += 8
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ return pos
+
+def _SkipLengthDelimited(buffer, pos, end):
+ """Skip a length-delimited value. Returns the new position."""
+
+ (size, pos) = _DecodeVarint(buffer, pos)
+ pos += size
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ return pos
+
+def _SkipGroup(buffer, pos, end):
+ """Skip sub-group. Returns the new position."""
+
+ while 1:
+ (tag_bytes, pos) = ReadTag(buffer, pos)
+ new_pos = SkipField(buffer, pos, end, tag_bytes)
+ if new_pos == -1:
+ return pos
+ pos = new_pos
+
+def _EndGroup(buffer, pos, end):
+ """Skipping an END_GROUP tag returns -1 to tell the parent loop to break."""
+
+ return -1
+
+def _SkipFixed32(buffer, pos, end):
+ """Skip a fixed32 value. Returns the new position."""
+
+ pos += 4
+ if pos > end:
+ raise _DecodeError('Truncated message.')
+ return pos
+
+def _RaiseInvalidWireType(buffer, pos, end):
+ """Skip function for unknown wire types. Raises an exception."""
+
+ raise _DecodeError('Tag had invalid wire type.')
+
+def _FieldSkipper():
+ """Constructs the SkipField function."""
+
+ WIRETYPE_TO_SKIPPER = [
+ _SkipVarint,
+ _SkipFixed64,
+ _SkipLengthDelimited,
+ _SkipGroup,
+ _EndGroup,
+ _SkipFixed32,
+ _RaiseInvalidWireType,
+ _RaiseInvalidWireType,
+ ]
+
+ wiretype_mask = wire_format.TAG_TYPE_MASK
+ local_ord = ord
+
+ def SkipField(buffer, pos, end, tag_bytes):
+ """Skips a field with the specified tag.
+
+ |pos| should point to the byte immediately after the tag.
+
+ Returns:
+ The new position (after the tag value), or -1 if the tag is an end-group
+ tag (in which case the calling loop should break).
+ """
+
+ # The wire type is always in the first byte since varints are little-endian.
+ wire_type = local_ord(tag_bytes[0]) & wiretype_mask
+ return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
+
+ return SkipField
+
+SkipField = _FieldSkipper()
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/descriptor_test.py b/src/third_party/protobuf/python/google/protobuf/internal/descriptor_test.py
new file mode 100755
index 0000000..05c2745
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/descriptor_test.py
@@ -0,0 +1,334 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for google.protobuf.internal.descriptor."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import unittest
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor
+from google.protobuf import text_format
+
+
+TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """
+name: 'TestEmptyMessage'
+"""
+
+
+class DescriptorTest(unittest.TestCase):
+
+ def setUp(self):
+ self.my_file = descriptor.FileDescriptor(
+ name='some/filename/some.proto',
+ package='protobuf_unittest'
+ )
+ self.my_enum = descriptor.EnumDescriptor(
+ name='ForeignEnum',
+ full_name='protobuf_unittest.ForeignEnum',
+ filename=None,
+ file=self.my_file,
+ values=[
+ descriptor.EnumValueDescriptor(name='FOREIGN_FOO', index=0, number=4),
+ descriptor.EnumValueDescriptor(name='FOREIGN_BAR', index=1, number=5),
+ descriptor.EnumValueDescriptor(name='FOREIGN_BAZ', index=2, number=6),
+ ])
+ self.my_message = descriptor.Descriptor(
+ name='NestedMessage',
+ full_name='protobuf_unittest.TestAllTypes.NestedMessage',
+ filename=None,
+ file=self.my_file,
+ containing_type=None,
+ fields=[
+ descriptor.FieldDescriptor(
+ name='bb',
+ full_name='protobuf_unittest.TestAllTypes.NestedMessage.bb',
+ index=0, number=1,
+ type=5, cpp_type=1, label=1,
+ has_default_value=False, default_value=0,
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None),
+ ],
+ nested_types=[],
+ enum_types=[
+ self.my_enum,
+ ],
+ extensions=[])
+ self.my_method = descriptor.MethodDescriptor(
+ name='Bar',
+ full_name='protobuf_unittest.TestService.Bar',
+ index=0,
+ containing_service=None,
+ input_type=None,
+ output_type=None)
+ self.my_service = descriptor.ServiceDescriptor(
+ name='TestServiceWithOptions',
+ full_name='protobuf_unittest.TestServiceWithOptions',
+ file=self.my_file,
+ index=0,
+ methods=[
+ self.my_method
+ ])
+
+ def testEnumFixups(self):
+ self.assertEqual(self.my_enum, self.my_enum.values[0].type)
+
+ def testContainingTypeFixups(self):
+ self.assertEqual(self.my_message, self.my_message.fields[0].containing_type)
+ self.assertEqual(self.my_message, self.my_enum.containing_type)
+
+ def testContainingServiceFixups(self):
+ self.assertEqual(self.my_service, self.my_method.containing_service)
+
+ def testGetOptions(self):
+ self.assertEqual(self.my_enum.GetOptions(),
+ descriptor_pb2.EnumOptions())
+ self.assertEqual(self.my_enum.values[0].GetOptions(),
+ descriptor_pb2.EnumValueOptions())
+ self.assertEqual(self.my_message.GetOptions(),
+ descriptor_pb2.MessageOptions())
+ self.assertEqual(self.my_message.fields[0].GetOptions(),
+ descriptor_pb2.FieldOptions())
+ self.assertEqual(self.my_method.GetOptions(),
+ descriptor_pb2.MethodOptions())
+ self.assertEqual(self.my_service.GetOptions(),
+ descriptor_pb2.ServiceOptions())
+
+ def testFileDescriptorReferences(self):
+ self.assertEqual(self.my_enum.file, self.my_file)
+ self.assertEqual(self.my_message.file, self.my_file)
+
+ def testFileDescriptor(self):
+ self.assertEqual(self.my_file.name, 'some/filename/some.proto')
+ self.assertEqual(self.my_file.package, 'protobuf_unittest')
+
+
+class DescriptorCopyToProtoTest(unittest.TestCase):
+ """Tests for CopyTo functions of Descriptor."""
+
+ def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii):
+ expected_proto = expected_class()
+ text_format.Merge(expected_ascii, expected_proto)
+
+ self.assertEqual(
+ actual_proto, expected_proto,
+ 'Not equal,\nActual:\n%s\nExpected:\n%s\n'
+ % (str(actual_proto), str(expected_proto)))
+
+ def _InternalTestCopyToProto(self, desc, expected_proto_class,
+ expected_proto_ascii):
+ actual = expected_proto_class()
+ desc.CopyToProto(actual)
+ self._AssertProtoEqual(
+ actual, expected_proto_class, expected_proto_ascii)
+
+ def testCopyToProto_EmptyMessage(self):
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestEmptyMessage.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII)
+
+ def testCopyToProto_NestedMessage(self):
+ TEST_NESTED_MESSAGE_ASCII = """
+ name: 'NestedMessage'
+ field: <
+ name: 'bb'
+ number: 1
+ label: 1 # Optional
+ type: 5 # TYPE_INT32
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_NESTED_MESSAGE_ASCII)
+
+ def testCopyToProto_ForeignNestedMessage(self):
+ TEST_FOREIGN_NESTED_ASCII = """
+ name: 'TestForeignNested'
+ field: <
+ name: 'foreign_nested'
+ number: 1
+ label: 1 # Optional
+ type: 11 # TYPE_MESSAGE
+ type_name: '.protobuf_unittest.TestAllTypes.NestedMessage'
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestForeignNested.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_FOREIGN_NESTED_ASCII)
+
+ def testCopyToProto_ForeignEnum(self):
+ TEST_FOREIGN_ENUM_ASCII = """
+ name: 'ForeignEnum'
+ value: <
+ name: 'FOREIGN_FOO'
+ number: 4
+ >
+ value: <
+ name: 'FOREIGN_BAR'
+ number: 5
+ >
+ value: <
+ name: 'FOREIGN_BAZ'
+ number: 6
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2._FOREIGNENUM,
+ descriptor_pb2.EnumDescriptorProto,
+ TEST_FOREIGN_ENUM_ASCII)
+
+ def testCopyToProto_Options(self):
+ TEST_DEPRECATED_FIELDS_ASCII = """
+ name: 'TestDeprecatedFields'
+ field: <
+ name: 'deprecated_int32'
+ number: 1
+ label: 1 # Optional
+ type: 5 # TYPE_INT32
+ options: <
+ deprecated: true
+ >
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestDeprecatedFields.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_DEPRECATED_FIELDS_ASCII)
+
+ def testCopyToProto_AllExtensions(self):
+ TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """
+ name: 'TestEmptyMessageWithExtensions'
+ extension_range: <
+ start: 1
+ end: 536870912
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII)
+
+ def testCopyToProto_SeveralExtensions(self):
+ TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """
+ name: 'TestMultipleExtensionRanges'
+ extension_range: <
+ start: 42
+ end: 43
+ >
+ extension_range: <
+ start: 4143
+ end: 4244
+ >
+ extension_range: <
+ start: 65536
+ end: 536870912
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR,
+ descriptor_pb2.DescriptorProto,
+ TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII)
+
+ def testCopyToProto_FileDescriptor(self):
+ UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
+ name: 'google/protobuf/unittest_import.proto'
+ package: 'protobuf_unittest_import'
+ message_type: <
+ name: 'ImportMessage'
+ field: <
+ name: 'd'
+ number: 1
+ label: 1 # Optional
+ type: 5 # TYPE_INT32
+ >
+ >
+ """ +
+ """enum_type: <
+ name: 'ImportEnum'
+ value: <
+ name: 'IMPORT_FOO'
+ number: 7
+ >
+ value: <
+ name: 'IMPORT_BAR'
+ number: 8
+ >
+ value: <
+ name: 'IMPORT_BAZ'
+ number: 9
+ >
+ >
+ options: <
+ java_package: 'com.google.protobuf.test'
+ optimize_for: 1 # SPEED
+ >
+ """)
+
+ self._InternalTestCopyToProto(
+ unittest_import_pb2.DESCRIPTOR,
+ descriptor_pb2.FileDescriptorProto,
+ UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
+
+ def testCopyToProto_ServiceDescriptor(self):
+ TEST_SERVICE_ASCII = """
+ name: 'TestService'
+ method: <
+ name: 'Foo'
+ input_type: '.protobuf_unittest.FooRequest'
+ output_type: '.protobuf_unittest.FooResponse'
+ >
+ method: <
+ name: 'Bar'
+ input_type: '.protobuf_unittest.BarRequest'
+ output_type: '.protobuf_unittest.BarResponse'
+ >
+ """
+
+ self._InternalTestCopyToProto(
+ unittest_pb2.TestService.DESCRIPTOR,
+ descriptor_pb2.ServiceDescriptorProto,
+ TEST_SERVICE_ASCII)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/encoder.py b/src/third_party/protobuf/python/google/protobuf/internal/encoder.py
new file mode 100755
index 0000000..777975e
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/encoder.py
@@ -0,0 +1,769 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Code for encoding protocol message primitives.
+
+Contains the logic for encoding every logical protocol field type
+into one of the 5 physical wire types.
+
+This code is designed to push the Python interpreter's performance to the
+limits.
+
+The basic idea is that at startup time, for every field (i.e. every
+FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The
+sizer takes a value of this field's type and computes its byte size. The
+encoder takes a writer function and a value. It encodes the value into byte
+strings and invokes the writer function to write those strings. Typically the
+writer function is the write() method of a cStringIO.
+
+We try to do as much work as possible when constructing the writer and the
+sizer rather than when calling them. In particular:
+* We copy any needed global functions to local variables, so that we do not need
+ to do costly global table lookups at runtime.
+* Similarly, we try to do any attribute lookups at startup time if possible.
+* Every field's tag is encoded to bytes at startup, since it can't change at
+ runtime.
+* Whatever component of the field size we can compute at startup, we do.
+* We *avoid* sharing code if doing so would make the code slower and not sharing
+ does not burden us too much. For example, encoders for repeated fields do
+ not just call the encoders for singular fields in a loop because this would
+ add an extra function call overhead for every loop iteration; instead, we
+ manually inline the single-value encoder into the loop.
+* If a Python function lacks a return statement, Python actually generates
+ instructions to pop the result of the last statement off the stack, push
+ None onto the stack, and then return that. If we really don't care what
+ value is returned, then we can save two instructions by returning the
+ result of the last statement. It looks funny but it helps.
+* We assume that type and bounds checking has happened at a higher level.
+"""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import struct
+from google.protobuf.internal import wire_format
+
+
+# This will overflow and thus become IEEE-754 "infinity". We would use
+# "float('inf')" but it doesn't work on Windows pre-Python-2.6.
+_POS_INF = 1e10000
+_NEG_INF = -_POS_INF
+
+
+def _VarintSize(value):
+ """Compute the size of a varint value."""
+ if value <= 0x7f: return 1
+ if value <= 0x3fff: return 2
+ if value <= 0x1fffff: return 3
+ if value <= 0xfffffff: return 4
+ if value <= 0x7ffffffff: return 5
+ if value <= 0x3ffffffffff: return 6
+ if value <= 0x1ffffffffffff: return 7
+ if value <= 0xffffffffffffff: return 8
+ if value <= 0x7fffffffffffffff: return 9
+ return 10
+
+
+def _SignedVarintSize(value):
+ """Compute the size of a signed varint value."""
+ if value < 0: return 10
+ if value <= 0x7f: return 1
+ if value <= 0x3fff: return 2
+ if value <= 0x1fffff: return 3
+ if value <= 0xfffffff: return 4
+ if value <= 0x7ffffffff: return 5
+ if value <= 0x3ffffffffff: return 6
+ if value <= 0x1ffffffffffff: return 7
+ if value <= 0xffffffffffffff: return 8
+ if value <= 0x7fffffffffffffff: return 9
+ return 10
+
+
+def _TagSize(field_number):
+ """Returns the number of bytes required to serialize a tag with this field
+ number."""
+ # Just pass in type 0, since the type won't affect the tag+type size.
+ return _VarintSize(wire_format.PackTag(field_number, 0))
+
+
+# --------------------------------------------------------------------
+# In this section we define some generic sizers. Each of these functions
+# takes parameters specific to a particular field type, e.g. int32 or fixed64.
+# It returns another function which in turn takes parameters specific to a
+# particular field, e.g. the field number and whether it is repeated or packed.
+# Look at the next section to see how these are used.
+
+
+def _SimpleSizer(compute_value_size):
+ """A sizer which uses the function compute_value_size to compute the size of
+ each value. Typically compute_value_size is _VarintSize."""
+
+ def SpecificSizer(field_number, is_repeated, is_packed):
+ tag_size = _TagSize(field_number)
+ if is_packed:
+ local_VarintSize = _VarintSize
+ def PackedFieldSize(value):
+ result = 0
+ for element in value:
+ result += compute_value_size(element)
+ return result + local_VarintSize(result) + tag_size
+ return PackedFieldSize
+ elif is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ result += compute_value_size(element)
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ return tag_size + compute_value_size(value)
+ return FieldSize
+
+ return SpecificSizer
+
+
+def _ModifiedSizer(compute_value_size, modify_value):
+ """Like SimpleSizer, but modify_value is invoked on each value before it is
+ passed to compute_value_size. modify_value is typically ZigZagEncode."""
+
+ def SpecificSizer(field_number, is_repeated, is_packed):
+ tag_size = _TagSize(field_number)
+ if is_packed:
+ local_VarintSize = _VarintSize
+ def PackedFieldSize(value):
+ result = 0
+ for element in value:
+ result += compute_value_size(modify_value(element))
+ return result + local_VarintSize(result) + tag_size
+ return PackedFieldSize
+ elif is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ result += compute_value_size(modify_value(element))
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ return tag_size + compute_value_size(modify_value(value))
+ return FieldSize
+
+ return SpecificSizer
+
+
+def _FixedSizer(value_size):
+ """Like _SimpleSizer except for a fixed-size field. The input is the size
+ of one value."""
+
+ def SpecificSizer(field_number, is_repeated, is_packed):
+ tag_size = _TagSize(field_number)
+ if is_packed:
+ local_VarintSize = _VarintSize
+ def PackedFieldSize(value):
+ result = len(value) * value_size
+ return result + local_VarintSize(result) + tag_size
+ return PackedFieldSize
+ elif is_repeated:
+ element_size = value_size + tag_size
+ def RepeatedFieldSize(value):
+ return len(value) * element_size
+ return RepeatedFieldSize
+ else:
+ field_size = value_size + tag_size
+ def FieldSize(value):
+ return field_size
+ return FieldSize
+
+ return SpecificSizer
+
+
+# ====================================================================
+# Here we declare a sizer constructor for each field type. Each "sizer
+# constructor" is a function that takes (field_number, is_repeated, is_packed)
+# as parameters and returns a sizer, which in turn takes a field value as
+# a parameter and returns its encoded size.
+
+
+Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize)
+
+UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize)
+
+SInt32Sizer = SInt64Sizer = _ModifiedSizer(
+ _SignedVarintSize, wire_format.ZigZagEncode)
+
+Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4)
+Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8)
+
+BoolSizer = _FixedSizer(1)
+
+
+def StringSizer(field_number, is_repeated, is_packed):
+ """Returns a sizer for a string field."""
+
+ tag_size = _TagSize(field_number)
+ local_VarintSize = _VarintSize
+ local_len = len
+ assert not is_packed
+ if is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ l = local_len(element.encode('utf-8'))
+ result += local_VarintSize(l) + l
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ l = local_len(value.encode('utf-8'))
+ return tag_size + local_VarintSize(l) + l
+ return FieldSize
+
+
+def BytesSizer(field_number, is_repeated, is_packed):
+ """Returns a sizer for a bytes field."""
+
+ tag_size = _TagSize(field_number)
+ local_VarintSize = _VarintSize
+ local_len = len
+ assert not is_packed
+ if is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ l = local_len(element)
+ result += local_VarintSize(l) + l
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ l = local_len(value)
+ return tag_size + local_VarintSize(l) + l
+ return FieldSize
+
+
+def GroupSizer(field_number, is_repeated, is_packed):
+ """Returns a sizer for a group field."""
+
+ tag_size = _TagSize(field_number) * 2
+ assert not is_packed
+ if is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ result += element.ByteSize()
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ return tag_size + value.ByteSize()
+ return FieldSize
+
+
+def MessageSizer(field_number, is_repeated, is_packed):
+ """Returns a sizer for a message field."""
+
+ tag_size = _TagSize(field_number)
+ local_VarintSize = _VarintSize
+ assert not is_packed
+ if is_repeated:
+ def RepeatedFieldSize(value):
+ result = tag_size * len(value)
+ for element in value:
+ l = element.ByteSize()
+ result += local_VarintSize(l) + l
+ return result
+ return RepeatedFieldSize
+ else:
+ def FieldSize(value):
+ l = value.ByteSize()
+ return tag_size + local_VarintSize(l) + l
+ return FieldSize
+
+
+# --------------------------------------------------------------------
+# MessageSet is special.
+
+
+def MessageSetItemSizer(field_number):
+ """Returns a sizer for extensions of MessageSet.
+
+ The message set message looks like this:
+ message MessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required string message = 3;
+ }
+ }
+ """
+ static_size = (_TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) +
+ _TagSize(3))
+ local_VarintSize = _VarintSize
+
+ def FieldSize(value):
+ l = value.ByteSize()
+ return static_size + local_VarintSize(l) + l
+
+ return FieldSize
+
+
+# ====================================================================
+# Encoders!
+
+
+def _VarintEncoder():
+ """Return an encoder for a basic varint value (does not include tag)."""
+
+ local_chr = chr
+ def EncodeVarint(write, value):
+ bits = value & 0x7f
+ value >>= 7
+ while value:
+ write(local_chr(0x80|bits))
+ bits = value & 0x7f
+ value >>= 7
+ return write(local_chr(bits))
+
+ return EncodeVarint
+
+
+def _SignedVarintEncoder():
+ """Return an encoder for a basic signed varint value (does not include
+ tag)."""
+
+ local_chr = chr
+ def EncodeSignedVarint(write, value):
+ if value < 0:
+ value += (1 << 64)
+ bits = value & 0x7f
+ value >>= 7
+ while value:
+ write(local_chr(0x80|bits))
+ bits = value & 0x7f
+ value >>= 7
+ return write(local_chr(bits))
+
+ return EncodeSignedVarint
+
+
+_EncodeVarint = _VarintEncoder()
+_EncodeSignedVarint = _SignedVarintEncoder()
+
+
+def _VarintBytes(value):
+ """Encode the given integer as a varint and return the bytes. This is only
+ called at startup time so it doesn't need to be fast."""
+
+ pieces = []
+ _EncodeVarint(pieces.append, value)
+ return "".join(pieces)
+
+
+def TagBytes(field_number, wire_type):
+ """Encode the given tag and return the bytes. Only called at startup."""
+
+ return _VarintBytes(wire_format.PackTag(field_number, wire_type))
+
+# --------------------------------------------------------------------
+# As with sizers (see above), we have a number of common encoder
+# implementations.
+
+
+def _SimpleEncoder(wire_type, encode_value, compute_value_size):
+ """Return a constructor for an encoder for fields of a particular type.
+
+ Args:
+ wire_type: The field's wire type, for encoding tags.
+ encode_value: A function which encodes an individual value, e.g.
+ _EncodeVarint().
+ compute_value_size: A function which computes the size of an individual
+ value, e.g. _VarintSize().
+ """
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ size = 0
+ for element in value:
+ size += compute_value_size(element)
+ local_EncodeVarint(write, size)
+ for element in value:
+ encode_value(write, element)
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ encode_value(write, element)
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ return encode_value(write, value)
+ return EncodeField
+
+ return SpecificEncoder
+
+
+def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value):
+ """Like SimpleEncoder but additionally invokes modify_value on every value
+ before passing it to encode_value. Usually modify_value is ZigZagEncode."""
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ size = 0
+ for element in value:
+ size += compute_value_size(modify_value(element))
+ local_EncodeVarint(write, size)
+ for element in value:
+ encode_value(write, modify_value(element))
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ encode_value(write, modify_value(element))
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ return encode_value(write, modify_value(value))
+ return EncodeField
+
+ return SpecificEncoder
+
+
+def _StructPackEncoder(wire_type, format):
+ """Return a constructor for an encoder for a fixed-width field.
+
+ Args:
+ wire_type: The field's wire type, for encoding tags.
+ format: The format string to pass to struct.pack().
+ """
+
+ value_size = struct.calcsize(format)
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ local_struct_pack = struct.pack
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ local_EncodeVarint(write, len(value) * value_size)
+ for element in value:
+ write(local_struct_pack(format, element))
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ write(local_struct_pack(format, element))
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ return write(local_struct_pack(format, value))
+ return EncodeField
+
+ return SpecificEncoder
+
+
+def _FloatingPointEncoder(wire_type, format):
+ """Return a constructor for an encoder for float fields.
+
+ This is like StructPackEncoder, but catches errors that may be due to
+ passing non-finite floating-point values to struct.pack, and makes a
+ second attempt to encode those values.
+
+ Args:
+ wire_type: The field's wire type, for encoding tags.
+ format: The format string to pass to struct.pack().
+ """
+
+ value_size = struct.calcsize(format)
+ if value_size == 4:
+ def EncodeNonFiniteOrRaise(write, value):
+ # Remember that the serialized form uses little-endian byte order.
+ if value == _POS_INF:
+ write('\x00\x00\x80\x7F')
+ elif value == _NEG_INF:
+ write('\x00\x00\x80\xFF')
+ elif value != value: # NaN
+ write('\x00\x00\xC0\x7F')
+ else:
+ raise
+ elif value_size == 8:
+ def EncodeNonFiniteOrRaise(write, value):
+ if value == _POS_INF:
+ write('\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ elif value == _NEG_INF:
+ write('\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ elif value != value: # NaN
+ write('\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ else:
+ raise
+ else:
+ raise ValueError('Can\'t encode floating-point values that are '
+ '%d bytes long (only 4 or 8)' % value_size)
+
+ def SpecificEncoder(field_number, is_repeated, is_packed):
+ local_struct_pack = struct.pack
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ local_EncodeVarint(write, len(value) * value_size)
+ for element in value:
+ # This try/except block is going to be faster than any code that
+ # we could write to check whether element is finite.
+ try:
+ write(local_struct_pack(format, element))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, element)
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ try:
+ write(local_struct_pack(format, element))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, element)
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_type)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ try:
+ write(local_struct_pack(format, value))
+ except SystemError:
+ EncodeNonFiniteOrRaise(write, value)
+ return EncodeField
+
+ return SpecificEncoder
+
+
+# ====================================================================
+# Here we declare an encoder constructor for each field type. These work
+# very similarly to sizer constructors, described earlier.
+
+
+Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder(
+ wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize)
+
+UInt32Encoder = UInt64Encoder = _SimpleEncoder(
+ wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize)
+
+SInt32Encoder = SInt64Encoder = _ModifiedEncoder(
+ wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize,
+ wire_format.ZigZagEncode)
+
+# Note that Python conveniently guarantees that when using the '<' prefix on
+# formats, they will also have the same size across all platforms (as opposed
+# to without the prefix, where their sizes depend on the C compiler's basic
+# type sizes).
+Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I')
+Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q')
+SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i')
+SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q')
+FloatEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED32, '<f')
+DoubleEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED64, '<d')
+
+
+def BoolEncoder(field_number, is_repeated, is_packed):
+ """Returns an encoder for a boolean field."""
+
+ false_byte = chr(0)
+ true_byte = chr(1)
+ if is_packed:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ def EncodePackedField(write, value):
+ write(tag_bytes)
+ local_EncodeVarint(write, len(value))
+ for element in value:
+ if element:
+ write(true_byte)
+ else:
+ write(false_byte)
+ return EncodePackedField
+ elif is_repeated:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag_bytes)
+ if element:
+ write(true_byte)
+ else:
+ write(false_byte)
+ return EncodeRepeatedField
+ else:
+ tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
+ def EncodeField(write, value):
+ write(tag_bytes)
+ if value:
+ return write(true_byte)
+ return write(false_byte)
+ return EncodeField
+
+
+def StringEncoder(field_number, is_repeated, is_packed):
+ """Returns an encoder for a string field."""
+
+ tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ local_len = len
+ assert not is_packed
+ if is_repeated:
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ encoded = element.encode('utf-8')
+ write(tag)
+ local_EncodeVarint(write, local_len(encoded))
+ write(encoded)
+ return EncodeRepeatedField
+ else:
+ def EncodeField(write, value):
+ encoded = value.encode('utf-8')
+ write(tag)
+ local_EncodeVarint(write, local_len(encoded))
+ return write(encoded)
+ return EncodeField
+
+
+def BytesEncoder(field_number, is_repeated, is_packed):
+ """Returns an encoder for a bytes field."""
+
+ tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ local_len = len
+ assert not is_packed
+ if is_repeated:
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag)
+ local_EncodeVarint(write, local_len(element))
+ write(element)
+ return EncodeRepeatedField
+ else:
+ def EncodeField(write, value):
+ write(tag)
+ local_EncodeVarint(write, local_len(value))
+ return write(value)
+ return EncodeField
+
+
+def GroupEncoder(field_number, is_repeated, is_packed):
+ """Returns an encoder for a group field."""
+
+ start_tag = TagBytes(field_number, wire_format.WIRETYPE_START_GROUP)
+ end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP)
+ assert not is_packed
+ if is_repeated:
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(start_tag)
+ element._InternalSerialize(write)
+ write(end_tag)
+ return EncodeRepeatedField
+ else:
+ def EncodeField(write, value):
+ write(start_tag)
+ value._InternalSerialize(write)
+ return write(end_tag)
+ return EncodeField
+
+
+def MessageEncoder(field_number, is_repeated, is_packed):
+ """Returns an encoder for a message field."""
+
+ tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+ local_EncodeVarint = _EncodeVarint
+ assert not is_packed
+ if is_repeated:
+ def EncodeRepeatedField(write, value):
+ for element in value:
+ write(tag)
+ local_EncodeVarint(write, element.ByteSize())
+ element._InternalSerialize(write)
+ return EncodeRepeatedField
+ else:
+ def EncodeField(write, value):
+ write(tag)
+ local_EncodeVarint(write, value.ByteSize())
+ return value._InternalSerialize(write)
+ return EncodeField
+
+
+# --------------------------------------------------------------------
+# As before, MessageSet is special.
+
+
+def MessageSetItemEncoder(field_number):
+ """Encoder for extensions of MessageSet.
+
+ The message set message looks like this:
+ message MessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required string message = 3;
+ }
+ }
+ """
+ start_bytes = "".join([
+ TagBytes(1, wire_format.WIRETYPE_START_GROUP),
+ TagBytes(2, wire_format.WIRETYPE_VARINT),
+ _VarintBytes(field_number),
+ TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)])
+ end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP)
+ local_EncodeVarint = _EncodeVarint
+
+ def EncodeField(write, value):
+ write(start_bytes)
+ local_EncodeVarint(write, value.ByteSize())
+ value._InternalSerialize(write)
+ return write(end_bytes)
+
+ return EncodeField
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/generator_test.py b/src/third_party/protobuf/python/google/protobuf/internal/generator_test.py
new file mode 100755
index 0000000..b3f7d9b
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/generator_test.py
@@ -0,0 +1,244 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# TODO(robinson): Flesh this out considerably. We focused on reflection_test.py
+# first, since it's testing the subtler code, and since it provides decent
+# indirect testing of the protocol compiler output.
+
+"""Unittest that directly tests the output of the pure-Python protocol
+compiler. See //google/protobuf/reflection_test.py for a test which
+further ensures that we can use Python protocol message objects as we expect.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import unittest
+from google.protobuf import unittest_custom_options_pb2
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import unittest_no_generic_services_pb2
+from google.protobuf import service
+
+MAX_EXTENSION = 536870912
+
+
+class GeneratorTest(unittest.TestCase):
+
+ def testNestedMessageDescriptor(self):
+ field_name = 'optional_nested_message'
+ proto_type = unittest_pb2.TestAllTypes
+ self.assertEqual(
+ proto_type.NestedMessage.DESCRIPTOR,
+ proto_type.DESCRIPTOR.fields_by_name[field_name].message_type)
+
+ def testEnums(self):
+ # We test only module-level enums here.
+ # TODO(robinson): Examine descriptors directly to check
+ # enum descriptor output.
+ self.assertEqual(4, unittest_pb2.FOREIGN_FOO)
+ self.assertEqual(5, unittest_pb2.FOREIGN_BAR)
+ self.assertEqual(6, unittest_pb2.FOREIGN_BAZ)
+
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(1, proto.FOO)
+ self.assertEqual(1, unittest_pb2.TestAllTypes.FOO)
+ self.assertEqual(2, proto.BAR)
+ self.assertEqual(2, unittest_pb2.TestAllTypes.BAR)
+ self.assertEqual(3, proto.BAZ)
+ self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
+
+ def testExtremeDefaultValues(self):
+ message = unittest_pb2.TestExtremeDefaultValues()
+
+ # Python pre-2.6 does not have isinf() or isnan() functions, so we have
+ # to provide our own.
+ def isnan(val):
+ # NaN is never equal to itself.
+ return val != val
+ def isinf(val):
+ # Infinity times zero equals NaN.
+ return not isnan(val) and isnan(val * 0)
+
+ self.assertTrue(isinf(message.inf_double))
+ self.assertTrue(message.inf_double > 0)
+ self.assertTrue(isinf(message.neg_inf_double))
+ self.assertTrue(message.neg_inf_double < 0)
+ self.assertTrue(isnan(message.nan_double))
+
+ self.assertTrue(isinf(message.inf_float))
+ self.assertTrue(message.inf_float > 0)
+ self.assertTrue(isinf(message.neg_inf_float))
+ self.assertTrue(message.neg_inf_float < 0)
+ self.assertTrue(isnan(message.nan_float))
+ self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph)
+
+ def testHasDefaultValues(self):
+ desc = unittest_pb2.TestAllTypes.DESCRIPTOR
+
+ expected_has_default_by_name = {
+ 'optional_int32': False,
+ 'repeated_int32': False,
+ 'optional_nested_message': False,
+ 'default_int32': True,
+ }
+
+ has_default_by_name = dict(
+ [(f.name, f.has_default_value)
+ for f in desc.fields
+ if f.name in expected_has_default_by_name])
+ self.assertEqual(expected_has_default_by_name, has_default_by_name)
+
+ def testContainingTypeBehaviorForExtensions(self):
+ self.assertEqual(unittest_pb2.optional_int32_extension.containing_type,
+ unittest_pb2.TestAllExtensions.DESCRIPTOR)
+ self.assertEqual(unittest_pb2.TestRequired.single.containing_type,
+ unittest_pb2.TestAllExtensions.DESCRIPTOR)
+
+ def testExtensionScope(self):
+ self.assertEqual(unittest_pb2.optional_int32_extension.extension_scope,
+ None)
+ self.assertEqual(unittest_pb2.TestRequired.single.extension_scope,
+ unittest_pb2.TestRequired.DESCRIPTOR)
+
+ def testIsExtension(self):
+ self.assertTrue(unittest_pb2.optional_int32_extension.is_extension)
+ self.assertTrue(unittest_pb2.TestRequired.single.is_extension)
+
+ message_descriptor = unittest_pb2.TestRequired.DESCRIPTOR
+ non_extension_descriptor = message_descriptor.fields_by_name['a']
+ self.assertTrue(not non_extension_descriptor.is_extension)
+
+ def testOptions(self):
+ proto = unittest_mset_pb2.TestMessageSet()
+ self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+
+ def testMessageWithCustomOptions(self):
+ proto = unittest_custom_options_pb2.TestMessageWithCustomOptions()
+ enum_options = proto.DESCRIPTOR.enum_types_by_name['AnEnum'].GetOptions()
+ self.assertTrue(enum_options is not None)
+ # TODO(gps): We really should test for the presense of the enum_opt1
+ # extension and for its value to be set to -789.
+
+ def testNestedTypes(self):
+ self.assertEquals(
+ set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types),
+ set([
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
+ unittest_pb2.TestAllTypes.OptionalGroup.DESCRIPTOR,
+ unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR,
+ ]))
+ self.assertEqual(unittest_pb2.TestEmptyMessage.DESCRIPTOR.nested_types, [])
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.nested_types, [])
+
+ def testContainingType(self):
+ self.assertTrue(
+ unittest_pb2.TestEmptyMessage.DESCRIPTOR.containing_type is None)
+ self.assertTrue(
+ unittest_pb2.TestAllTypes.DESCRIPTOR.containing_type is None)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR.containing_type,
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+
+ def testContainingTypeInEnumDescriptor(self):
+ self.assertTrue(unittest_pb2._FOREIGNENUM.containing_type is None)
+ self.assertEqual(unittest_pb2._TESTALLTYPES_NESTEDENUM.containing_type,
+ unittest_pb2.TestAllTypes.DESCRIPTOR)
+
+ def testPackage(self):
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.DESCRIPTOR.file.package,
+ 'protobuf_unittest')
+ desc = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR
+ self.assertEqual(desc.file.package, 'protobuf_unittest')
+ self.assertEqual(
+ unittest_import_pb2.ImportMessage.DESCRIPTOR.file.package,
+ 'protobuf_unittest_import')
+
+ self.assertEqual(
+ unittest_pb2._FOREIGNENUM.file.package, 'protobuf_unittest')
+ self.assertEqual(
+ unittest_pb2._TESTALLTYPES_NESTEDENUM.file.package,
+ 'protobuf_unittest')
+ self.assertEqual(
+ unittest_import_pb2._IMPORTENUM.file.package,
+ 'protobuf_unittest_import')
+
+ def testExtensionRange(self):
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.DESCRIPTOR.extension_ranges, [])
+ self.assertEqual(
+ unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges,
+ [(1, MAX_EXTENSION)])
+ self.assertEqual(
+ unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges,
+ [(42, 43), (4143, 4244), (65536, MAX_EXTENSION)])
+
+ def testFileDescriptor(self):
+ self.assertEqual(unittest_pb2.DESCRIPTOR.name,
+ 'google/protobuf/unittest.proto')
+ self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest')
+ self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None)
+
+ def testNoGenericServices(self):
+ self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage"))
+ self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO"))
+ self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension"))
+
+ # Make sure unittest_no_generic_services_pb2 has no services subclassing
+ # Proto2 Service class.
+ if hasattr(unittest_no_generic_services_pb2, "TestService"):
+ self.assertFalse(issubclass(unittest_no_generic_services_pb2.TestService,
+ service.Service))
+
+ def testMessageTypesByName(self):
+ file_type = unittest_pb2.DESCRIPTOR
+ self.assertEqual(
+ unittest_pb2._TESTALLTYPES,
+ file_type.message_types_by_name[unittest_pb2._TESTALLTYPES.name])
+
+ # Nested messages shouldn't be included in the message_types_by_name
+ # dictionary (like in the C++ API).
+ self.assertFalse(
+ unittest_pb2._TESTALLTYPES_NESTEDMESSAGE.name in
+ file_type.message_types_by_name)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/message_listener.py b/src/third_party/protobuf/python/google/protobuf/internal/message_listener.py
new file mode 100755
index 0000000..1080234
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/message_listener.py
@@ -0,0 +1,78 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Defines a listener interface for observing certain
+state transitions on Message objects.
+
+Also defines a null implementation of this interface.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+class MessageListener(object):
+
+ """Listens for modifications made to a message. Meant to be registered via
+ Message._SetListener().
+
+ Attributes:
+ dirty: If True, then calling Modified() would be a no-op. This can be
+ used to avoid these calls entirely in the common case.
+ """
+
+ def Modified(self):
+ """Called every time the message is modified in such a way that the parent
+ message may need to be updated. This currently means either:
+ (a) The message was modified for the first time, so the parent message
+ should henceforth mark the message as present.
+ (b) The message's cached byte size became dirty -- i.e. the message was
+ modified for the first time after a previous call to ByteSize().
+ Therefore the parent should also mark its byte size as dirty.
+ Note that (a) implies (b), since new objects start out with a client cached
+ size (zero). However, we document (a) explicitly because it is important.
+
+ Modified() will *only* be called in response to one of these two events --
+ not every time the sub-message is modified.
+
+ Note that if the listener's |dirty| attribute is true, then calling
+ Modified at the moment would be a no-op, so it can be skipped. Performance-
+ sensitive callers should check this attribute directly before calling since
+ it will be true most of the time.
+ """
+
+ raise NotImplementedError
+
+
+class NullMessageListener(object):
+
+ """No-op MessageListener implementation."""
+
+ def Modified(self):
+ pass
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/message_test.py b/src/third_party/protobuf/python/google/protobuf/internal/message_test.py
new file mode 100755
index 0000000..6517437
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/message_test.py
@@ -0,0 +1,343 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests python protocol buffers against the golden message.
+
+Note that the golden messages exercise every known field type, thus this
+test ends up exercising and verifying nearly all of the parsing and
+serialization code in the whole library.
+
+TODO(kenton): Merge with wire_format_test? It doesn't make a whole lot of
+sense to call this a test of the "message" module, which only declares an
+abstract interface.
+"""
+
+__author__ = 'gps@google.com (Gregory P. Smith)'
+
+import copy
+import math
+import unittest
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf.internal import test_util
+
+# Python pre-2.6 does not have isinf() or isnan() functions, so we have
+# to provide our own.
+def isnan(val):
+ # NaN is never equal to itself.
+ return val != val
+def isinf(val):
+ # Infinity times zero equals NaN.
+ return not isnan(val) and isnan(val * 0)
+def IsPosInf(val):
+ return isinf(val) and (val > 0)
+def IsNegInf(val):
+ return isinf(val) and (val < 0)
+
+class MessageTest(unittest.TestCase):
+
+ def testGoldenMessage(self):
+ golden_data = test_util.GoldenFile('golden_message').read()
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ test_util.ExpectAllFieldsSet(self, golden_message)
+ self.assertTrue(golden_message.SerializeToString() == golden_data)
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertTrue(golden_copy.SerializeToString() == golden_data)
+
+ def testGoldenExtensions(self):
+ golden_data = test_util.GoldenFile('golden_message').read()
+ golden_message = unittest_pb2.TestAllExtensions()
+ golden_message.ParseFromString(golden_data)
+ all_set = unittest_pb2.TestAllExtensions()
+ test_util.SetAllExtensions(all_set)
+ self.assertEquals(all_set, golden_message)
+ self.assertTrue(golden_message.SerializeToString() == golden_data)
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertTrue(golden_copy.SerializeToString() == golden_data)
+
+ def testGoldenPackedMessage(self):
+ golden_data = test_util.GoldenFile('golden_packed_fields_message').read()
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ all_set = unittest_pb2.TestPackedTypes()
+ test_util.SetAllPackedFields(all_set)
+ self.assertEquals(all_set, golden_message)
+ self.assertTrue(all_set.SerializeToString() == golden_data)
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertTrue(golden_copy.SerializeToString() == golden_data)
+
+ def testGoldenPackedExtensions(self):
+ golden_data = test_util.GoldenFile('golden_packed_fields_message').read()
+ golden_message = unittest_pb2.TestPackedExtensions()
+ golden_message.ParseFromString(golden_data)
+ all_set = unittest_pb2.TestPackedExtensions()
+ test_util.SetAllPackedExtensions(all_set)
+ self.assertEquals(all_set, golden_message)
+ self.assertTrue(all_set.SerializeToString() == golden_data)
+ golden_copy = copy.deepcopy(golden_message)
+ self.assertTrue(golden_copy.SerializeToString() == golden_data)
+
+ def testPositiveInfinity(self):
+ golden_data = ('\x5D\x00\x00\x80\x7F'
+ '\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
+ '\xCD\x02\x00\x00\x80\x7F'
+ '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsPosInf(golden_message.optional_float))
+ self.assertTrue(IsPosInf(golden_message.optional_double))
+ self.assertTrue(IsPosInf(golden_message.repeated_float[0]))
+ self.assertTrue(IsPosInf(golden_message.repeated_double[0]))
+ self.assertTrue(golden_message.SerializeToString() == golden_data)
+
+ def testNegativeInfinity(self):
+ golden_data = ('\x5D\x00\x00\x80\xFF'
+ '\x61\x00\x00\x00\x00\x00\x00\xF0\xFF'
+ '\xCD\x02\x00\x00\x80\xFF'
+ '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsNegInf(golden_message.optional_float))
+ self.assertTrue(IsNegInf(golden_message.optional_double))
+ self.assertTrue(IsNegInf(golden_message.repeated_float[0]))
+ self.assertTrue(IsNegInf(golden_message.repeated_double[0]))
+ self.assertTrue(golden_message.SerializeToString() == golden_data)
+
+ def testNotANumber(self):
+ golden_data = ('\x5D\x00\x00\xC0\x7F'
+ '\x61\x00\x00\x00\x00\x00\x00\xF8\x7F'
+ '\xCD\x02\x00\x00\xC0\x7F'
+ '\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ golden_message = unittest_pb2.TestAllTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(isnan(golden_message.optional_float))
+ self.assertTrue(isnan(golden_message.optional_double))
+ self.assertTrue(isnan(golden_message.repeated_float[0]))
+ self.assertTrue(isnan(golden_message.repeated_double[0]))
+ self.assertTrue(golden_message.SerializeToString() == golden_data)
+
+ def testPositiveInfinityPacked(self):
+ golden_data = ('\xA2\x06\x04\x00\x00\x80\x7F'
+ '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsPosInf(golden_message.packed_float[0]))
+ self.assertTrue(IsPosInf(golden_message.packed_double[0]))
+ self.assertTrue(golden_message.SerializeToString() == golden_data)
+
+ def testNegativeInfinityPacked(self):
+ golden_data = ('\xA2\x06\x04\x00\x00\x80\xFF'
+ '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(IsNegInf(golden_message.packed_float[0]))
+ self.assertTrue(IsNegInf(golden_message.packed_double[0]))
+ self.assertTrue(golden_message.SerializeToString() == golden_data)
+
+ def testNotANumberPacked(self):
+ golden_data = ('\xA2\x06\x04\x00\x00\xC0\x7F'
+ '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F')
+ golden_message = unittest_pb2.TestPackedTypes()
+ golden_message.ParseFromString(golden_data)
+ self.assertTrue(isnan(golden_message.packed_float[0]))
+ self.assertTrue(isnan(golden_message.packed_double[0]))
+ self.assertTrue(golden_message.SerializeToString() == golden_data)
+
+ def testExtremeFloatValues(self):
+ message = unittest_pb2.TestAllTypes()
+
+ # Most positive exponent, no significand bits set.
+ kMostPosExponentNoSigBits = math.pow(2, 127)
+ message.optional_float = kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostPosExponentNoSigBits)
+
+ # Most positive exponent, one significand bit set.
+ kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127)
+ message.optional_float = kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostPosExponentOneSigBit)
+
+ # Repeat last two cases with values of same magnitude, but negative.
+ message.optional_float = -kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostPosExponentNoSigBits)
+
+ message.optional_float = -kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostPosExponentOneSigBit)
+
+ # Most negative exponent, no significand bits set.
+ kMostNegExponentNoSigBits = math.pow(2, -127)
+ message.optional_float = kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostNegExponentNoSigBits)
+
+ # Most negative exponent, one significand bit set.
+ kMostNegExponentOneSigBit = 1.5 * math.pow(2, -127)
+ message.optional_float = kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == kMostNegExponentOneSigBit)
+
+ # Repeat last two cases with values of the same magnitude, but negative.
+ message.optional_float = -kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits)
+
+ message.optional_float = -kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit)
+
+ def testExtremeFloatValues(self):
+ message = unittest_pb2.TestAllTypes()
+
+ # Most positive exponent, no significand bits set.
+ kMostPosExponentNoSigBits = math.pow(2, 1023)
+ message.optional_double = kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostPosExponentNoSigBits)
+
+ # Most positive exponent, one significand bit set.
+ kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023)
+ message.optional_double = kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostPosExponentOneSigBit)
+
+ # Repeat last two cases with values of same magnitude, but negative.
+ message.optional_double = -kMostPosExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostPosExponentNoSigBits)
+
+ message.optional_double = -kMostPosExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostPosExponentOneSigBit)
+
+ # Most negative exponent, no significand bits set.
+ kMostNegExponentNoSigBits = math.pow(2, -1023)
+ message.optional_double = kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostNegExponentNoSigBits)
+
+ # Most negative exponent, one significand bit set.
+ kMostNegExponentOneSigBit = 1.5 * math.pow(2, -1023)
+ message.optional_double = kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == kMostNegExponentOneSigBit)
+
+ # Repeat last two cases with values of the same magnitude, but negative.
+ message.optional_double = -kMostNegExponentNoSigBits
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits)
+
+ message.optional_double = -kMostNegExponentOneSigBit
+ message.ParseFromString(message.SerializeToString())
+ self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit)
+
+ def testSortingRepeatedScalarFieldsDefaultComparator(self):
+ """Check some different types with the default comparator."""
+ message = unittest_pb2.TestAllTypes()
+
+ # TODO(mattp): would testing more scalar types strengthen test?
+ message.repeated_int32.append(1)
+ message.repeated_int32.append(3)
+ message.repeated_int32.append(2)
+ message.repeated_int32.sort()
+ self.assertEqual(message.repeated_int32[0], 1)
+ self.assertEqual(message.repeated_int32[1], 2)
+ self.assertEqual(message.repeated_int32[2], 3)
+
+ message.repeated_float.append(1.1)
+ message.repeated_float.append(1.3)
+ message.repeated_float.append(1.2)
+ message.repeated_float.sort()
+ self.assertAlmostEqual(message.repeated_float[0], 1.1)
+ self.assertAlmostEqual(message.repeated_float[1], 1.2)
+ self.assertAlmostEqual(message.repeated_float[2], 1.3)
+
+ message.repeated_string.append('a')
+ message.repeated_string.append('c')
+ message.repeated_string.append('b')
+ message.repeated_string.sort()
+ self.assertEqual(message.repeated_string[0], 'a')
+ self.assertEqual(message.repeated_string[1], 'b')
+ self.assertEqual(message.repeated_string[2], 'c')
+
+ message.repeated_bytes.append('a')
+ message.repeated_bytes.append('c')
+ message.repeated_bytes.append('b')
+ message.repeated_bytes.sort()
+ self.assertEqual(message.repeated_bytes[0], 'a')
+ self.assertEqual(message.repeated_bytes[1], 'b')
+ self.assertEqual(message.repeated_bytes[2], 'c')
+
+ def testSortingRepeatedScalarFieldsCustomComparator(self):
+ """Check some different types with custom comparator."""
+ message = unittest_pb2.TestAllTypes()
+
+ message.repeated_int32.append(-3)
+ message.repeated_int32.append(-2)
+ message.repeated_int32.append(-1)
+ message.repeated_int32.sort(lambda x,y: cmp(abs(x), abs(y)))
+ self.assertEqual(message.repeated_int32[0], -1)
+ self.assertEqual(message.repeated_int32[1], -2)
+ self.assertEqual(message.repeated_int32[2], -3)
+
+ message.repeated_string.append('aaa')
+ message.repeated_string.append('bb')
+ message.repeated_string.append('c')
+ message.repeated_string.sort(lambda x,y: cmp(len(x), len(y)))
+ self.assertEqual(message.repeated_string[0], 'c')
+ self.assertEqual(message.repeated_string[1], 'bb')
+ self.assertEqual(message.repeated_string[2], 'aaa')
+
+ def testSortingRepeatedCompositeFieldsCustomComparator(self):
+ """Check passing a custom comparator to sort a repeated composite field."""
+ message = unittest_pb2.TestAllTypes()
+
+ message.repeated_nested_message.add().bb = 1
+ message.repeated_nested_message.add().bb = 3
+ message.repeated_nested_message.add().bb = 2
+ message.repeated_nested_message.add().bb = 6
+ message.repeated_nested_message.add().bb = 5
+ message.repeated_nested_message.add().bb = 4
+ message.repeated_nested_message.sort(lambda x,y: cmp(x.bb, y.bb))
+ self.assertEqual(message.repeated_nested_message[0].bb, 1)
+ self.assertEqual(message.repeated_nested_message[1].bb, 2)
+ self.assertEqual(message.repeated_nested_message[2].bb, 3)
+ self.assertEqual(message.repeated_nested_message[3].bb, 4)
+ self.assertEqual(message.repeated_nested_message[4].bb, 5)
+ self.assertEqual(message.repeated_nested_message[5].bb, 6)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/more_extensions.proto b/src/third_party/protobuf/python/google/protobuf/internal/more_extensions.proto
new file mode 100644
index 0000000..e2d9701
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/more_extensions.proto
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: robinson@google.com (Will Robinson)
+
+
+package google.protobuf.internal;
+
+
+message TopLevelMessage {
+ optional ExtendedMessage submessage = 1;
+}
+
+
+message ExtendedMessage {
+ extensions 1 to max;
+}
+
+
+message ForeignMessage {
+ optional int32 foreign_message_int = 1;
+}
+
+
+extend ExtendedMessage {
+ optional int32 optional_int_extension = 1;
+ optional ForeignMessage optional_message_extension = 2;
+
+ repeated int32 repeated_int_extension = 3;
+ repeated ForeignMessage repeated_message_extension = 4;
+}
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/more_messages.proto b/src/third_party/protobuf/python/google/protobuf/internal/more_messages.proto
new file mode 100644
index 0000000..c701b44
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/more_messages.proto
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: robinson@google.com (Will Robinson)
+
+
+package google.protobuf.internal;
+
+// A message where tag numbers are listed out of order, to allow us to test our
+// canonicalization of serialized output, which should always be in tag order.
+// We also mix in some extensions for extra fun.
+message OutOfOrderFields {
+ optional sint32 optional_sint32 = 5;
+ extensions 4 to 4;
+ optional uint32 optional_uint32 = 3;
+ extensions 2 to 2;
+ optional int32 optional_int32 = 1;
+};
+
+
+extend OutOfOrderFields {
+ optional uint64 optional_uint64 = 4;
+ optional int64 optional_int64 = 2;
+}
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/python_message.py b/src/third_party/protobuf/python/google/protobuf/internal/python_message.py
new file mode 100644
index 0000000..66fca91
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/python_message.py
@@ -0,0 +1,1098 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This code is meant to work on Python 2.4 and above only.
+#
+# TODO(robinson): Helpers for verbose, common checks like seeing if a
+# descriptor's cpp_type is CPPTYPE_MESSAGE.
+
+"""Contains a metaclass and helper functions used to create
+protocol message classes from Descriptor objects at runtime.
+
+Recall that a metaclass is the "type" of a class.
+(A class is to a metaclass what an instance is to a class.)
+
+In this case, we use the GeneratedProtocolMessageType metaclass
+to inject all the useful functionality into the classes
+output by the protocol compiler at compile-time.
+
+The upshot of all this is that the real implementation
+details for ALL pure-Python protocol buffers are *here in
+this file*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
+import struct
+import weakref
+
+# We use "as" to avoid name collisions with variables.
+from google.protobuf.internal import containers
+from google.protobuf.internal import decoder
+from google.protobuf.internal import encoder
+from google.protobuf.internal import message_listener as message_listener_mod
+from google.protobuf.internal import type_checkers
+from google.protobuf.internal import wire_format
+from google.protobuf import descriptor as descriptor_mod
+from google.protobuf import message as message_mod
+from google.protobuf import text_format
+
+_FieldDescriptor = descriptor_mod.FieldDescriptor
+
+
+def NewMessage(descriptor, dictionary):
+ _AddClassAttributesForNestedExtensions(descriptor, dictionary)
+ _AddSlots(descriptor, dictionary)
+
+
+def InitMessage(descriptor, cls):
+ cls._decoders_by_tag = {}
+ cls._extensions_by_name = {}
+ cls._extensions_by_number = {}
+ if (descriptor.has_options and
+ descriptor.GetOptions().message_set_wire_format):
+ cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
+ decoder.MessageSetItemDecoder(cls._extensions_by_number))
+
+ # Attach stuff to each FieldDescriptor for quick lookup later on.
+ for field in descriptor.fields:
+ _AttachFieldHelpers(cls, field)
+
+ _AddEnumValues(descriptor, cls)
+ _AddInitMethod(descriptor, cls)
+ _AddPropertiesForFields(descriptor, cls)
+ _AddPropertiesForExtensions(descriptor, cls)
+ _AddStaticMethods(cls)
+ _AddMessageMethods(descriptor, cls)
+ _AddPrivateHelperMethods(cls)
+
+
+# Stateless helpers for GeneratedProtocolMessageType below.
+# Outside clients should not access these directly.
+#
+# I opted not to make any of these methods on the metaclass, to make it more
+# clear that I'm not really using any state there and to keep clients from
+# thinking that they have direct access to these construction helpers.
+
+
+def _PropertyName(proto_field_name):
+ """Returns the name of the public property attribute which
+ clients can use to get and (in some cases) set the value
+ of a protocol message field.
+
+ Args:
+ proto_field_name: The protocol message field name, exactly
+ as it appears (or would appear) in a .proto file.
+ """
+ # TODO(robinson): Escape Python keywords (e.g., yield), and test this support.
+ # nnorwitz makes my day by writing:
+ # """
+ # FYI. See the keyword module in the stdlib. This could be as simple as:
+ #
+ # if keyword.iskeyword(proto_field_name):
+ # return proto_field_name + "_"
+ # return proto_field_name
+ # """
+ # Kenton says: The above is a BAD IDEA. People rely on being able to use
+ # getattr() and setattr() to reflectively manipulate field values. If we
+ # rename the properties, then every such user has to also make sure to apply
+ # the same transformation. Note that currently if you name a field "yield",
+ # you can still access it just fine using getattr/setattr -- it's not even
+ # that cumbersome to do so.
+ # TODO(kenton): Remove this method entirely if/when everyone agrees with my
+ # position.
+ return proto_field_name
+
+
+def _VerifyExtensionHandle(message, extension_handle):
+ """Verify that the given extension handle is valid."""
+
+ if not isinstance(extension_handle, _FieldDescriptor):
+ raise KeyError('HasExtension() expects an extension handle, got: %s' %
+ extension_handle)
+
+ if not extension_handle.is_extension:
+ raise KeyError('"%s" is not an extension.' % extension_handle.full_name)
+
+ if extension_handle.containing_type is not message.DESCRIPTOR:
+ raise KeyError('Extension "%s" extends message type "%s", but this '
+ 'message is of type "%s".' %
+ (extension_handle.full_name,
+ extension_handle.containing_type.full_name,
+ message.DESCRIPTOR.full_name))
+
+
+def _AddSlots(message_descriptor, dictionary):
+ """Adds a __slots__ entry to dictionary, containing the names of all valid
+ attributes for this message type.
+
+ Args:
+ message_descriptor: A Descriptor instance describing this message type.
+ dictionary: Class dictionary to which we'll add a '__slots__' entry.
+ """
+ dictionary['__slots__'] = ['_cached_byte_size',
+ '_cached_byte_size_dirty',
+ '_fields',
+ '_is_present_in_parent',
+ '_listener',
+ '_listener_for_children',
+ '__weakref__']
+
+
+def _IsMessageSetExtension(field):
+ return (field.is_extension and
+ field.containing_type.has_options and
+ field.containing_type.GetOptions().message_set_wire_format and
+ field.type == _FieldDescriptor.TYPE_MESSAGE and
+ field.message_type == field.extension_scope and
+ field.label == _FieldDescriptor.LABEL_OPTIONAL)
+
+
+def _AttachFieldHelpers(cls, field_descriptor):
+ is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
+ is_packed = (field_descriptor.has_options and
+ field_descriptor.GetOptions().packed)
+
+ if _IsMessageSetExtension(field_descriptor):
+ field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
+ sizer = encoder.MessageSetItemSizer(field_descriptor.number)
+ else:
+ field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed)
+ sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed)
+
+ field_descriptor._encoder = field_encoder
+ field_descriptor._sizer = sizer
+ field_descriptor._default_constructor = _DefaultValueConstructorForField(
+ field_descriptor)
+
+ def AddDecoder(wiretype, is_packed):
+ tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
+ cls._decoders_by_tag[tag_bytes] = (
+ type_checkers.TYPE_TO_DECODER[field_descriptor.type](
+ field_descriptor.number, is_repeated, is_packed,
+ field_descriptor, field_descriptor._default_constructor))
+
+ AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
+ False)
+
+ if is_repeated and wire_format.IsTypePackable(field_descriptor.type):
+ # To support wire compatibility of adding packed = true, add a decoder for
+ # packed values regardless of the field's options.
+ AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
+
+
+def _AddClassAttributesForNestedExtensions(descriptor, dictionary):
+ extension_dict = descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ assert extension_name not in dictionary
+ dictionary[extension_name] = extension_field
+
+
+def _AddEnumValues(descriptor, cls):
+ """Sets class-level attributes for all enum fields defined in this message.
+
+ Args:
+ descriptor: Descriptor object for this message type.
+ cls: Class we're constructing for this message type.
+ """
+ for enum_type in descriptor.enum_types:
+ for enum_value in enum_type.values:
+ setattr(cls, enum_value.name, enum_value.number)
+
+
+def _DefaultValueConstructorForField(field):
+ """Returns a function which returns a default value for a field.
+
+ Args:
+ field: FieldDescriptor object for this field.
+
+ The returned function has one argument:
+ message: Message instance containing this field, or a weakref proxy
+ of same.
+
+ That function in turn returns a default value for this field. The default
+ value may refer back to |message| via a weak reference.
+ """
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ if field.default_value != []:
+ raise ValueError('Repeated field default value not empty list: %s' % (
+ field.default_value))
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ # We can't look at _concrete_class yet since it might not have
+ # been set. (Depends on order in which we initialize the classes).
+ message_type = field.message_type
+ def MakeRepeatedMessageDefault(message):
+ return containers.RepeatedCompositeFieldContainer(
+ message._listener_for_children, field.message_type)
+ return MakeRepeatedMessageDefault
+ else:
+ type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type)
+ def MakeRepeatedScalarDefault(message):
+ return containers.RepeatedScalarFieldContainer(
+ message._listener_for_children, type_checker)
+ return MakeRepeatedScalarDefault
+
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ # _concrete_class may not yet be initialized.
+ message_type = field.message_type
+ def MakeSubMessageDefault(message):
+ result = message_type._concrete_class()
+ result._SetListener(message._listener_for_children)
+ return result
+ return MakeSubMessageDefault
+
+ def MakeScalarDefault(message):
+ return field.default_value
+ return MakeScalarDefault
+
+
+def _AddInitMethod(message_descriptor, cls):
+ """Adds an __init__ method to cls."""
+ fields = message_descriptor.fields
+ def init(self, **kwargs):
+ self._cached_byte_size = 0
+ self._cached_byte_size_dirty = len(kwargs) > 0
+ self._fields = {}
+ self._is_present_in_parent = False
+ self._listener = message_listener_mod.NullMessageListener()
+ self._listener_for_children = _Listener(self)
+ for field_name, field_value in kwargs.iteritems():
+ field = _GetFieldByName(message_descriptor, field_name)
+ if field is None:
+ raise TypeError("%s() got an unexpected keyword argument '%s'" %
+ (message_descriptor.name, field_name))
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ copy = field._default_constructor(self)
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite
+ for val in field_value:
+ copy.add().MergeFrom(val)
+ else: # Scalar
+ copy.extend(field_value)
+ self._fields[field] = copy
+ elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ copy = field._default_constructor(self)
+ copy.MergeFrom(field_value)
+ self._fields[field] = copy
+ else:
+ setattr(self, field_name, field_value)
+
+ init.__module__ = None
+ init.__doc__ = None
+ cls.__init__ = init
+
+
+def _GetFieldByName(message_descriptor, field_name):
+ """Returns a field descriptor by field name.
+
+ Args:
+ message_descriptor: A Descriptor describing all fields in message.
+ field_name: The name of the field to retrieve.
+ Returns:
+ The field descriptor associated with the field name.
+ """
+ try:
+ return message_descriptor.fields_by_name[field_name]
+ except KeyError:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+
+
+def _AddPropertiesForFields(descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ for field in descriptor.fields:
+ _AddPropertiesForField(field, cls)
+
+ if descriptor.is_extendable:
+ # _ExtensionDict is just an adaptor with no state so we allocate a new one
+ # every time it is accessed.
+ cls.Extensions = property(lambda self: _ExtensionDict(self))
+
+
+def _AddPropertiesForField(field, cls):
+ """Adds a public property for a protocol message field.
+ Clients can use this property to get and (in the case
+ of non-repeated scalar fields) directly set the value
+ of a protocol message field.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ # Catch it if we add other types that we should
+ # handle specially here.
+ assert _FieldDescriptor.MAX_CPPTYPE == 10
+
+ constant_name = field.name.upper() + "_FIELD_NUMBER"
+ setattr(cls, constant_name, field.number)
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ _AddPropertiesForRepeatedField(field, cls)
+ elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ _AddPropertiesForNonRepeatedCompositeField(field, cls)
+ else:
+ _AddPropertiesForNonRepeatedScalarField(field, cls)
+
+
+def _AddPropertiesForRepeatedField(field, cls):
+ """Adds a public property for a "repeated" protocol message field. Clients
+ can use this property to get the value of the field, which will be either a
+ _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see
+ below).
+
+ Note that when clients add values to these containers, we perform
+ type-checking in the case of repeated scalar fields, and we also set any
+ necessary "has" bits as a side-effect.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+
+ def getter(self):
+ field_value = self._fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ field_value = self._fields.setdefault(field, field_value)
+ return field_value
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+
+ # We define a setter just so we can throw an exception with a more
+ # helpful error message.
+ def setter(self, new_value):
+ raise AttributeError('Assignment not allowed to repeated field '
+ '"%s" in protocol message object.' % proto_field_name)
+
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForNonRepeatedScalarField(field, cls):
+ """Adds a public property for a nonrepeated, scalar protocol message field.
+ Clients can use this property to get and directly set the value of the field.
+ Note that when the client sets the value of a field by using this property,
+ all necessary "has" bits are set as a side-effect, and we also perform
+ type-checking.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+ type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type)
+ default_value = field.default_value
+ valid_values = set()
+
+ def getter(self):
+ return self._fields.get(field, default_value)
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+ def setter(self, new_value):
+ type_checker.CheckValue(new_value)
+ self._fields[field] = new_value
+ # Check _cached_byte_size_dirty inline to improve performance, since scalar
+ # setters are called frequently.
+ if not self._cached_byte_size_dirty:
+ self._Modified()
+
+ setter.__module__ = None
+ setter.__doc__ = 'Setter for %s.' % proto_field_name
+
+ # Add a property to encapsulate the getter/setter.
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForNonRepeatedCompositeField(field, cls):
+ """Adds a public property for a nonrepeated, composite protocol message field.
+ A composite field is a "group" or "message" field.
+
+ Clients can use this property to get the value of the field, but cannot
+ assign to the property directly.
+
+ Args:
+ field: A FieldDescriptor for this field.
+ cls: The class we're constructing.
+ """
+ # TODO(robinson): Remove duplication with similar method
+ # for non-repeated scalars.
+ proto_field_name = field.name
+ property_name = _PropertyName(proto_field_name)
+ message_type = field.message_type
+
+ def getter(self):
+ field_value = self._fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = message_type._concrete_class()
+ field_value._SetListener(self._listener_for_children)
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ field_value = self._fields.setdefault(field, field_value)
+ return field_value
+ getter.__module__ = None
+ getter.__doc__ = 'Getter for %s.' % proto_field_name
+
+ # We define a setter just so we can throw an exception with a more
+ # helpful error message.
+ def setter(self, new_value):
+ raise AttributeError('Assignment not allowed to composite field '
+ '"%s" in protocol message object.' % proto_field_name)
+
+ # Add a property to encapsulate the getter.
+ doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+ setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForExtensions(descriptor, cls):
+ """Adds properties for all fields in this protocol message type."""
+ extension_dict = descriptor.extensions_by_name
+ for extension_name, extension_field in extension_dict.iteritems():
+ constant_name = extension_name.upper() + "_FIELD_NUMBER"
+ setattr(cls, constant_name, extension_field.number)
+
+
+def _AddStaticMethods(cls):
+ # TODO(robinson): This probably needs to be thread-safe(?)
+ def RegisterExtension(extension_handle):
+ extension_handle.containing_type = cls.DESCRIPTOR
+ _AttachFieldHelpers(cls, extension_handle)
+
+ # Try to insert our extension, failing if an extension with the same number
+ # already exists.
+ actual_handle = cls._extensions_by_number.setdefault(
+ extension_handle.number, extension_handle)
+ if actual_handle is not extension_handle:
+ raise AssertionError(
+ 'Extensions "%s" and "%s" both try to extend message type "%s" with '
+ 'field number %d.' %
+ (extension_handle.full_name, actual_handle.full_name,
+ cls.DESCRIPTOR.full_name, extension_handle.number))
+
+ cls._extensions_by_name[extension_handle.full_name] = extension_handle
+
+ handle = extension_handle # avoid line wrapping
+ if _IsMessageSetExtension(handle):
+ # MessageSet extension. Also register under type name.
+ cls._extensions_by_name[
+ extension_handle.message_type.full_name] = extension_handle
+
+ cls.RegisterExtension = staticmethod(RegisterExtension)
+
+ def FromString(s):
+ message = cls()
+ message.MergeFromString(s)
+ return message
+ cls.FromString = staticmethod(FromString)
+
+
+def _IsPresent(item):
+ """Given a (FieldDescriptor, value) tuple from _fields, return true if the
+ value should be included in the list returned by ListFields()."""
+
+ if item[0].label == _FieldDescriptor.LABEL_REPEATED:
+ return bool(item[1])
+ elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ return item[1]._is_present_in_parent
+ else:
+ return True
+
+
+def _AddListFieldsMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def ListFields(self):
+ all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)]
+ all_fields.sort(key = lambda item: item[0].number)
+ return all_fields
+
+ cls.ListFields = ListFields
+
+
+def _AddHasFieldMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ singular_fields = {}
+ for field in message_descriptor.fields:
+ if field.label != _FieldDescriptor.LABEL_REPEATED:
+ singular_fields[field.name] = field
+
+ def HasField(self, field_name):
+ try:
+ field = singular_fields[field_name]
+ except KeyError:
+ raise ValueError(
+ 'Protocol message has no singular "%s" field.' % field_name)
+
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ value = self._fields.get(field)
+ return value is not None and value._is_present_in_parent
+ else:
+ return field in self._fields
+ cls.HasField = HasField
+
+
+def _AddClearFieldMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def ClearField(self, field_name):
+ try:
+ field = message_descriptor.fields_by_name[field_name]
+ except KeyError:
+ raise ValueError('Protocol message has no "%s" field.' % field_name)
+
+ if field in self._fields:
+ # Note: If the field is a sub-message, its listener will still point
+ # at us. That's fine, because the worst than can happen is that it
+ # will call _Modified() and invalidate our byte size. Big deal.
+ del self._fields[field]
+
+ # Always call _Modified() -- even if nothing was changed, this is
+ # a mutating method, and thus calling it should cause the field to become
+ # present in the parent message.
+ self._Modified()
+
+ cls.ClearField = ClearField
+
+
+def _AddClearExtensionMethod(cls):
+ """Helper for _AddMessageMethods()."""
+ def ClearExtension(self, extension_handle):
+ _VerifyExtensionHandle(self, extension_handle)
+
+ # Similar to ClearField(), above.
+ if extension_handle in self._fields:
+ del self._fields[extension_handle]
+ self._Modified()
+ cls.ClearExtension = ClearExtension
+
+
+def _AddClearMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def Clear(self):
+ # Clear fields.
+ self._fields = {}
+ self._Modified()
+ cls.Clear = Clear
+
+
+def _AddHasExtensionMethod(cls):
+ """Helper for _AddMessageMethods()."""
+ def HasExtension(self, extension_handle):
+ _VerifyExtensionHandle(self, extension_handle)
+ if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
+ raise KeyError('"%s" is repeated.' % extension_handle.full_name)
+
+ if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ value = self._fields.get(extension_handle)
+ return value is not None and value._is_present_in_parent
+ else:
+ return extension_handle in self._fields
+ cls.HasExtension = HasExtension
+
+
+def _AddEqualsMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def __eq__(self, other):
+ if (not isinstance(other, message_mod.Message) or
+ other.DESCRIPTOR != self.DESCRIPTOR):
+ return False
+
+ if self is other:
+ return True
+
+ return self.ListFields() == other.ListFields()
+
+ cls.__eq__ = __eq__
+
+
+def _AddStrMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def __str__(self):
+ return text_format.MessageToString(self)
+ cls.__str__ = __str__
+
+
+def _AddUnicodeMethod(unused_message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def __unicode__(self):
+ return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
+ cls.__unicode__ = __unicode__
+
+
+def _AddSetListenerMethod(cls):
+ """Helper for _AddMessageMethods()."""
+ def SetListener(self, listener):
+ if listener is None:
+ self._listener = message_listener_mod.NullMessageListener()
+ else:
+ self._listener = listener
+ cls._SetListener = SetListener
+
+
+def _BytesForNonRepeatedElement(value, field_number, field_type):
+ """Returns the number of bytes needed to serialize a non-repeated element.
+ The returned byte count includes space for tag information and any
+ other additional space associated with serializing value.
+
+ Args:
+ value: Value we're serializing.
+ field_number: Field number of this value. (Since the field number
+ is stored as part of a varint-encoded tag, this has an impact
+ on the total bytes required to serialize the value).
+ field_type: The type of the field. One of the TYPE_* constants
+ within FieldDescriptor.
+ """
+ try:
+ fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type]
+ return fn(field_number, value)
+ except KeyError:
+ raise message_mod.EncodeError('Unrecognized field type: %d' % field_type)
+
+
+def _AddByteSizeMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def ByteSize(self):
+ if not self._cached_byte_size_dirty:
+ return self._cached_byte_size
+
+ size = 0
+ for field_descriptor, field_value in self.ListFields():
+ size += field_descriptor._sizer(field_value)
+
+ self._cached_byte_size = size
+ self._cached_byte_size_dirty = False
+ self._listener_for_children.dirty = False
+ return size
+
+ cls.ByteSize = ByteSize
+
+
+def _AddSerializeToStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def SerializeToString(self):
+ # Check if the message has all of its required fields set.
+ errors = []
+ if not self.IsInitialized():
+ raise message_mod.EncodeError(
+ 'Message is missing required fields: ' +
+ ','.join(self.FindInitializationErrors()))
+ return self.SerializePartialToString()
+ cls.SerializeToString = SerializeToString
+
+
+def _AddSerializePartialToStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+
+ def SerializePartialToString(self):
+ out = StringIO()
+ self._InternalSerialize(out.write)
+ return out.getvalue()
+ cls.SerializePartialToString = SerializePartialToString
+
+ def InternalSerialize(self, write_bytes):
+ for field_descriptor, field_value in self.ListFields():
+ field_descriptor._encoder(write_bytes, field_value)
+ cls._InternalSerialize = InternalSerialize
+
+
+def _AddMergeFromStringMethod(message_descriptor, cls):
+ """Helper for _AddMessageMethods()."""
+ def MergeFromString(self, serialized):
+ length = len(serialized)
+ try:
+ if self._InternalParse(serialized, 0, length) != length:
+ # The only reason _InternalParse would return early is if it
+ # encountered an end-group tag.
+ raise message_mod.DecodeError('Unexpected end-group tag.')
+ except IndexError:
+ raise message_mod.DecodeError('Truncated message.')
+ except struct.error, e:
+ raise message_mod.DecodeError(e)
+ return length # Return this for legacy reasons.
+ cls.MergeFromString = MergeFromString
+
+ local_ReadTag = decoder.ReadTag
+ local_SkipField = decoder.SkipField
+ decoders_by_tag = cls._decoders_by_tag
+
+ def InternalParse(self, buffer, pos, end):
+ self._Modified()
+ field_dict = self._fields
+ while pos != end:
+ (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
+ field_decoder = decoders_by_tag.get(tag_bytes)
+ if field_decoder is None:
+ new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
+ if new_pos == -1:
+ return pos
+ pos = new_pos
+ else:
+ pos = field_decoder(buffer, new_pos, end, self, field_dict)
+ return pos
+ cls._InternalParse = InternalParse
+
+
+def _AddIsInitializedMethod(message_descriptor, cls):
+ """Adds the IsInitialized and FindInitializationError methods to the
+ protocol message class."""
+
+ required_fields = [field for field in message_descriptor.fields
+ if field.label == _FieldDescriptor.LABEL_REQUIRED]
+
+ def IsInitialized(self, errors=None):
+ """Checks if all required fields of a message are set.
+
+ Args:
+ errors: A list which, if provided, will be populated with the field
+ paths of all missing required fields.
+
+ Returns:
+ True iff the specified message has all required fields set.
+ """
+
+ # Performance is critical so we avoid HasField() and ListFields().
+
+ for field in required_fields:
+ if (field not in self._fields or
+ (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
+ not self._fields[field]._is_present_in_parent)):
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+
+ for field, value in self._fields.iteritems():
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ for element in value:
+ if not element.IsInitialized():
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+ elif value._is_present_in_parent and not value.IsInitialized():
+ if errors is not None:
+ errors.extend(self.FindInitializationErrors())
+ return False
+
+ return True
+
+ cls.IsInitialized = IsInitialized
+
+ def FindInitializationErrors(self):
+ """Finds required fields which are not initialized.
+
+ Returns:
+ A list of strings. Each string is a path to an uninitialized field from
+ the top-level message, e.g. "foo.bar[5].baz".
+ """
+
+ errors = [] # simplify things
+
+ for field in required_fields:
+ if not self.HasField(field.name):
+ errors.append(field.name)
+
+ for field, value in self.ListFields():
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ if field.is_extension:
+ name = "(%s)" % field.full_name
+ else:
+ name = field.name
+
+ if field.label == _FieldDescriptor.LABEL_REPEATED:
+ for i in xrange(len(value)):
+ element = value[i]
+ prefix = "%s[%d]." % (name, i)
+ sub_errors = element.FindInitializationErrors()
+ errors += [ prefix + error for error in sub_errors ]
+ else:
+ prefix = name + "."
+ sub_errors = value.FindInitializationErrors()
+ errors += [ prefix + error for error in sub_errors ]
+
+ return errors
+
+ cls.FindInitializationErrors = FindInitializationErrors
+
+
+def _AddMergeFromMethod(cls):
+ LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED
+ CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE
+
+ def MergeFrom(self, msg):
+ if not isinstance(msg, cls):
+ raise TypeError(
+ "Parameter to MergeFrom() must be instance of same class.")
+
+ assert msg is not self
+ self._Modified()
+
+ fields = self._fields
+
+ for field, value in msg._fields.iteritems():
+ if field.label == LABEL_REPEATED:
+ field_value = fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+ fields[field] = field_value
+ field_value.MergeFrom(value)
+ elif field.cpp_type == CPPTYPE_MESSAGE:
+ if value._is_present_in_parent:
+ field_value = fields.get(field)
+ if field_value is None:
+ # Construct a new object to represent this field.
+ field_value = field._default_constructor(self)
+ fields[field] = field_value
+ field_value.MergeFrom(value)
+ else:
+ self._fields[field] = value
+ cls.MergeFrom = MergeFrom
+
+
+def _AddMessageMethods(message_descriptor, cls):
+ """Adds implementations of all Message methods to cls."""
+ _AddListFieldsMethod(message_descriptor, cls)
+ _AddHasFieldMethod(message_descriptor, cls)
+ _AddClearFieldMethod(message_descriptor, cls)
+ if message_descriptor.is_extendable:
+ _AddClearExtensionMethod(cls)
+ _AddHasExtensionMethod(cls)
+ _AddClearMethod(message_descriptor, cls)
+ _AddEqualsMethod(message_descriptor, cls)
+ _AddStrMethod(message_descriptor, cls)
+ _AddUnicodeMethod(message_descriptor, cls)
+ _AddSetListenerMethod(cls)
+ _AddByteSizeMethod(message_descriptor, cls)
+ _AddSerializeToStringMethod(message_descriptor, cls)
+ _AddSerializePartialToStringMethod(message_descriptor, cls)
+ _AddMergeFromStringMethod(message_descriptor, cls)
+ _AddIsInitializedMethod(message_descriptor, cls)
+ _AddMergeFromMethod(cls)
+
+
+def _AddPrivateHelperMethods(cls):
+ """Adds implementation of private helper methods to cls."""
+
+ def Modified(self):
+ """Sets the _cached_byte_size_dirty bit to true,
+ and propagates this to our listener iff this was a state change.
+ """
+
+ # Note: Some callers check _cached_byte_size_dirty before calling
+ # _Modified() as an extra optimization. So, if this method is ever
+ # changed such that it does stuff even when _cached_byte_size_dirty is
+ # already true, the callers need to be updated.
+ if not self._cached_byte_size_dirty:
+ self._cached_byte_size_dirty = True
+ self._listener_for_children.dirty = True
+ self._is_present_in_parent = True
+ self._listener.Modified()
+
+ cls._Modified = Modified
+ cls.SetInParent = Modified
+
+
+class _Listener(object):
+
+ """MessageListener implementation that a parent message registers with its
+ child message.
+
+ In order to support semantics like:
+
+ foo.bar.baz.qux = 23
+ assert foo.HasField('bar')
+
+ ...child objects must have back references to their parents.
+ This helper class is at the heart of this support.
+ """
+
+ def __init__(self, parent_message):
+ """Args:
+ parent_message: The message whose _Modified() method we should call when
+ we receive Modified() messages.
+ """
+ # This listener establishes a back reference from a child (contained) object
+ # to its parent (containing) object. We make this a weak reference to avoid
+ # creating cyclic garbage when the client finishes with the 'parent' object
+ # in the tree.
+ if isinstance(parent_message, weakref.ProxyType):
+ self._parent_message_weakref = parent_message
+ else:
+ self._parent_message_weakref = weakref.proxy(parent_message)
+
+ # As an optimization, we also indicate directly on the listener whether
+ # or not the parent message is dirty. This way we can avoid traversing
+ # up the tree in the common case.
+ self.dirty = False
+
+ def Modified(self):
+ if self.dirty:
+ return
+ try:
+ # Propagate the signal to our parents iff this is the first field set.
+ self._parent_message_weakref._Modified()
+ except ReferenceError:
+ # We can get here if a client has kept a reference to a child object,
+ # and is now setting a field on it, but the child's parent has been
+ # garbage-collected. This is not an error.
+ pass
+
+
+# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous...
+# TODO(robinson): Unify error handling of "unknown extension" crap.
+# TODO(robinson): Support iteritems()-style iteration over all
+# extensions with the "has" bits turned on?
+class _ExtensionDict(object):
+
+ """Dict-like container for supporting an indexable "Extensions"
+ field on proto instances.
+
+ Note that in all cases we expect extension handles to be
+ FieldDescriptors.
+ """
+
+ def __init__(self, extended_message):
+ """extended_message: Message instance for which we are the Extensions dict.
+ """
+
+ self._extended_message = extended_message
+
+ def __getitem__(self, extension_handle):
+ """Returns the current value of the given extension handle."""
+
+ _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+ result = self._extended_message._fields.get(extension_handle)
+ if result is not None:
+ return result
+
+ if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
+ result = extension_handle._default_constructor(self._extended_message)
+ elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+ result = extension_handle.message_type._concrete_class()
+ try:
+ result._SetListener(self._extended_message._listener_for_children)
+ except ReferenceError:
+ pass
+ else:
+ # Singular scalar -- just return the default without inserting into the
+ # dict.
+ return extension_handle.default_value
+
+ # Atomically check if another thread has preempted us and, if not, swap
+ # in the new object we just created. If someone has preempted us, we
+ # take that object and discard ours.
+ # WARNING: We are relying on setdefault() being atomic. This is true
+ # in CPython but we haven't investigated others. This warning appears
+ # in several other locations in this file.
+ result = self._extended_message._fields.setdefault(
+ extension_handle, result)
+
+ return result
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return False
+
+ my_fields = self._extended_message.ListFields()
+ other_fields = other._extended_message.ListFields()
+
+ # Get rid of non-extension fields.
+ my_fields = [ field for field in my_fields if field.is_extension ]
+ other_fields = [ field for field in other_fields if field.is_extension ]
+
+ return my_fields == other_fields
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ # Note that this is only meaningful for non-repeated, scalar extension
+ # fields. Note also that we may have to call _Modified() when we do
+ # successfully set a field this way, to set any necssary "has" bits in the
+ # ancestors of the extended message.
+ def __setitem__(self, extension_handle, value):
+ """If extension_handle specifies a non-repeated, scalar extension
+ field, sets the value of that field.
+ """
+
+ _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+ if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or
+ extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE):
+ raise TypeError(
+ 'Cannot assign to extension "%s" because it is a repeated or '
+ 'composite type.' % extension_handle.full_name)
+
+ # It's slightly wasteful to lookup the type checker each time,
+ # but we expect this to be a vanishingly uncommon case anyway.
+ type_checker = type_checkers.GetTypeChecker(
+ extension_handle.cpp_type, extension_handle.type)
+ type_checker.CheckValue(value)
+ self._extended_message._fields[extension_handle] = value
+ self._extended_message._Modified()
+
+ def _FindExtensionByName(self, name):
+ """Tries to find a known extension with the specified name.
+
+ Args:
+ name: Extension full name.
+
+ Returns:
+ Extension field descriptor.
+ """
+ return self._extended_message._extensions_by_name.get(name, None)
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/reflection_test.py b/src/third_party/protobuf/python/google/protobuf/internal/reflection_test.py
new file mode 100755
index 0000000..7b9d339
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/reflection_test.py
@@ -0,0 +1,2421 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for reflection.py, which also indirectly tests the output of the
+pure-Python protocol compiler.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import operator
+import struct
+
+import unittest
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor
+from google.protobuf import message
+from google.protobuf import reflection
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import more_extensions_pb2
+from google.protobuf.internal import more_messages_pb2
+from google.protobuf.internal import wire_format
+from google.protobuf.internal import test_util
+from google.protobuf.internal import decoder
+
+
+class _MiniDecoder(object):
+ """Decodes a stream of values from a string.
+
+ Once upon a time we actually had a class called decoder.Decoder. Then we
+ got rid of it during a redesign that made decoding much, much faster overall.
+ But a couple tests in this file used it to check that the serialized form of
+ a message was correct. So, this class implements just the methods that were
+ used by said tests, so that we don't have to rewrite the tests.
+ """
+
+ def __init__(self, bytes):
+ self._bytes = bytes
+ self._pos = 0
+
+ def ReadVarint(self):
+ result, self._pos = decoder._DecodeVarint(self._bytes, self._pos)
+ return result
+
+ ReadInt32 = ReadVarint
+ ReadInt64 = ReadVarint
+ ReadUInt32 = ReadVarint
+ ReadUInt64 = ReadVarint
+
+ def ReadSInt64(self):
+ return wire_format.ZigZagDecode(self.ReadVarint())
+
+ ReadSInt32 = ReadSInt64
+
+ def ReadFieldNumberAndWireType(self):
+ return wire_format.UnpackTag(self.ReadVarint())
+
+ def ReadFloat(self):
+ result = struct.unpack("<f", self._bytes[self._pos:self._pos+4])[0]
+ self._pos += 4
+ return result
+
+ def ReadDouble(self):
+ result = struct.unpack("<d", self._bytes[self._pos:self._pos+8])[0]
+ self._pos += 8
+ return result
+
+ def EndOfStream(self):
+ return self._pos == len(self._bytes)
+
+
+class ReflectionTest(unittest.TestCase):
+
+ def assertListsEqual(self, values, others):
+ self.assertEqual(len(values), len(others))
+ for i in range(len(values)):
+ self.assertEqual(values[i], others[i])
+
+ def testScalarConstructor(self):
+ # Constructor with only scalar types should succeed.
+ proto = unittest_pb2.TestAllTypes(
+ optional_int32=24,
+ optional_double=54.321,
+ optional_string='optional_string')
+
+ self.assertEqual(24, proto.optional_int32)
+ self.assertEqual(54.321, proto.optional_double)
+ self.assertEqual('optional_string', proto.optional_string)
+
+ def testRepeatedScalarConstructor(self):
+ # Constructor with only repeated scalar types should succeed.
+ proto = unittest_pb2.TestAllTypes(
+ repeated_int32=[1, 2, 3, 4],
+ repeated_double=[1.23, 54.321],
+ repeated_bool=[True, False, False],
+ repeated_string=["optional_string"])
+
+ self.assertEquals([1, 2, 3, 4], list(proto.repeated_int32))
+ self.assertEquals([1.23, 54.321], list(proto.repeated_double))
+ self.assertEquals([True, False, False], list(proto.repeated_bool))
+ self.assertEquals(["optional_string"], list(proto.repeated_string))
+
+ def testRepeatedCompositeConstructor(self):
+ # Constructor with only repeated composite types should succeed.
+ proto = unittest_pb2.TestAllTypes(
+ repeated_nested_message=[
+ unittest_pb2.TestAllTypes.NestedMessage(
+ bb=unittest_pb2.TestAllTypes.FOO),
+ unittest_pb2.TestAllTypes.NestedMessage(
+ bb=unittest_pb2.TestAllTypes.BAR)],
+ repeated_foreign_message=[
+ unittest_pb2.ForeignMessage(c=-43),
+ unittest_pb2.ForeignMessage(c=45324),
+ unittest_pb2.ForeignMessage(c=12)],
+ repeatedgroup=[
+ unittest_pb2.TestAllTypes.RepeatedGroup(),
+ unittest_pb2.TestAllTypes.RepeatedGroup(a=1),
+ unittest_pb2.TestAllTypes.RepeatedGroup(a=2)])
+
+ self.assertEquals(
+ [unittest_pb2.TestAllTypes.NestedMessage(
+ bb=unittest_pb2.TestAllTypes.FOO),
+ unittest_pb2.TestAllTypes.NestedMessage(
+ bb=unittest_pb2.TestAllTypes.BAR)],
+ list(proto.repeated_nested_message))
+ self.assertEquals(
+ [unittest_pb2.ForeignMessage(c=-43),
+ unittest_pb2.ForeignMessage(c=45324),
+ unittest_pb2.ForeignMessage(c=12)],
+ list(proto.repeated_foreign_message))
+ self.assertEquals(
+ [unittest_pb2.TestAllTypes.RepeatedGroup(),
+ unittest_pb2.TestAllTypes.RepeatedGroup(a=1),
+ unittest_pb2.TestAllTypes.RepeatedGroup(a=2)],
+ list(proto.repeatedgroup))
+
+ def testMixedConstructor(self):
+ # Constructor with only mixed types should succeed.
+ proto = unittest_pb2.TestAllTypes(
+ optional_int32=24,
+ optional_string='optional_string',
+ repeated_double=[1.23, 54.321],
+ repeated_bool=[True, False, False],
+ repeated_nested_message=[
+ unittest_pb2.TestAllTypes.NestedMessage(
+ bb=unittest_pb2.TestAllTypes.FOO),
+ unittest_pb2.TestAllTypes.NestedMessage(
+ bb=unittest_pb2.TestAllTypes.BAR)],
+ repeated_foreign_message=[
+ unittest_pb2.ForeignMessage(c=-43),
+ unittest_pb2.ForeignMessage(c=45324),
+ unittest_pb2.ForeignMessage(c=12)])
+
+ self.assertEqual(24, proto.optional_int32)
+ self.assertEqual('optional_string', proto.optional_string)
+ self.assertEquals([1.23, 54.321], list(proto.repeated_double))
+ self.assertEquals([True, False, False], list(proto.repeated_bool))
+ self.assertEquals(
+ [unittest_pb2.TestAllTypes.NestedMessage(
+ bb=unittest_pb2.TestAllTypes.FOO),
+ unittest_pb2.TestAllTypes.NestedMessage(
+ bb=unittest_pb2.TestAllTypes.BAR)],
+ list(proto.repeated_nested_message))
+ self.assertEquals(
+ [unittest_pb2.ForeignMessage(c=-43),
+ unittest_pb2.ForeignMessage(c=45324),
+ unittest_pb2.ForeignMessage(c=12)],
+ list(proto.repeated_foreign_message))
+
+ def testConstructorTypeError(self):
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, optional_int32="foo")
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, optional_string=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, optional_nested_message=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_int32=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_int32=["foo"])
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_string=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_string=[1234])
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=1234)
+ self.assertRaises(
+ TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=[1234])
+
+ def testConstructorInvalidatesCachedByteSize(self):
+ message = unittest_pb2.TestAllTypes(optional_int32 = 12)
+ self.assertEquals(2, message.ByteSize())
+
+ message = unittest_pb2.TestAllTypes(
+ optional_nested_message = unittest_pb2.TestAllTypes.NestedMessage())
+ self.assertEquals(3, message.ByteSize())
+
+ message = unittest_pb2.TestAllTypes(repeated_int32 = [12])
+ self.assertEquals(3, message.ByteSize())
+
+ message = unittest_pb2.TestAllTypes(
+ repeated_nested_message = [unittest_pb2.TestAllTypes.NestedMessage()])
+ self.assertEquals(3, message.ByteSize())
+
+ def testSimpleHasBits(self):
+ # Test a scalar.
+ proto = unittest_pb2.TestAllTypes()
+ self.assertTrue(not proto.HasField('optional_int32'))
+ self.assertEqual(0, proto.optional_int32)
+ # HasField() shouldn't be true if all we've done is
+ # read the default value.
+ self.assertTrue(not proto.HasField('optional_int32'))
+ proto.optional_int32 = 1
+ # Setting a value however *should* set the "has" bit.
+ self.assertTrue(proto.HasField('optional_int32'))
+ proto.ClearField('optional_int32')
+ # And clearing that value should unset the "has" bit.
+ self.assertTrue(not proto.HasField('optional_int32'))
+
+ def testHasBitsWithSinglyNestedScalar(self):
+ # Helper used to test foreign messages and groups.
+ #
+ # composite_field_name should be the name of a non-repeated
+ # composite (i.e., foreign or group) field in TestAllTypes,
+ # and scalar_field_name should be the name of an integer-valued
+ # scalar field within that composite.
+ #
+ # I never thought I'd miss C++ macros and templates so much. :(
+ # This helper is semantically just:
+ #
+ # assert proto.composite_field.scalar_field == 0
+ # assert not proto.composite_field.HasField('scalar_field')
+ # assert not proto.HasField('composite_field')
+ #
+ # proto.composite_field.scalar_field = 10
+ # old_composite_field = proto.composite_field
+ #
+ # assert proto.composite_field.scalar_field == 10
+ # assert proto.composite_field.HasField('scalar_field')
+ # assert proto.HasField('composite_field')
+ #
+ # proto.ClearField('composite_field')
+ #
+ # assert not proto.composite_field.HasField('scalar_field')
+ # assert not proto.HasField('composite_field')
+ # assert proto.composite_field.scalar_field == 0
+ #
+ # # Now ensure that ClearField('composite_field') disconnected
+ # # the old field object from the object tree...
+ # assert old_composite_field is not proto.composite_field
+ # old_composite_field.scalar_field = 20
+ # assert not proto.composite_field.HasField('scalar_field')
+ # assert not proto.HasField('composite_field')
+ def TestCompositeHasBits(composite_field_name, scalar_field_name):
+ proto = unittest_pb2.TestAllTypes()
+ # First, check that we can get the scalar value, and see that it's the
+ # default (0), but that proto.HasField('omposite') and
+ # proto.composite.HasField('scalar') will still return False.
+ composite_field = getattr(proto, composite_field_name)
+ original_scalar_value = getattr(composite_field, scalar_field_name)
+ self.assertEqual(0, original_scalar_value)
+ # Assert that the composite object does not "have" the scalar.
+ self.assertTrue(not composite_field.HasField(scalar_field_name))
+ # Assert that proto does not "have" the composite field.
+ self.assertTrue(not proto.HasField(composite_field_name))
+
+ # Now set the scalar within the composite field. Ensure that the setting
+ # is reflected, and that proto.HasField('composite') and
+ # proto.composite.HasField('scalar') now both return True.
+ new_val = 20
+ setattr(composite_field, scalar_field_name, new_val)
+ self.assertEqual(new_val, getattr(composite_field, scalar_field_name))
+ # Hold on to a reference to the current composite_field object.
+ old_composite_field = composite_field
+ # Assert that the has methods now return true.
+ self.assertTrue(composite_field.HasField(scalar_field_name))
+ self.assertTrue(proto.HasField(composite_field_name))
+
+ # Now call the clear method...
+ proto.ClearField(composite_field_name)
+
+ # ...and ensure that the "has" bits are all back to False...
+ composite_field = getattr(proto, composite_field_name)
+ self.assertTrue(not composite_field.HasField(scalar_field_name))
+ self.assertTrue(not proto.HasField(composite_field_name))
+ # ...and ensure that the scalar field has returned to its default.
+ self.assertEqual(0, getattr(composite_field, scalar_field_name))
+
+ # Finally, ensure that modifications to the old composite field object
+ # don't have any effect on the parent. Possible only with the pure-python
+ # implementation of the API.
+ #
+ # (NOTE that when we clear the composite field in the parent, we actually
+ # don't recursively clear down the tree. Instead, we just disconnect the
+ # cleared composite from the tree.)
+ if api_implementation.Type() != 'python':
+ return
+ self.assertTrue(old_composite_field is not composite_field)
+ setattr(old_composite_field, scalar_field_name, new_val)
+ self.assertTrue(not composite_field.HasField(scalar_field_name))
+ self.assertTrue(not proto.HasField(composite_field_name))
+ self.assertEqual(0, getattr(composite_field, scalar_field_name))
+
+ # Test simple, single-level nesting when we set a scalar.
+ TestCompositeHasBits('optionalgroup', 'a')
+ TestCompositeHasBits('optional_nested_message', 'bb')
+ TestCompositeHasBits('optional_foreign_message', 'c')
+ TestCompositeHasBits('optional_import_message', 'd')
+
+ def testReferencesToNestedMessage(self):
+ proto = unittest_pb2.TestAllTypes()
+ nested = proto.optional_nested_message
+ del proto
+ # A previous version had a bug where this would raise an exception when
+ # hitting a now-dead weak reference.
+ nested.bb = 23
+
+ def testDisconnectingNestedMessageBeforeSettingField(self):
+ if api_implementation.Type() != 'python':
+ return
+ proto = unittest_pb2.TestAllTypes()
+ nested = proto.optional_nested_message
+ proto.ClearField('optional_nested_message') # Should disconnect from parent
+ self.assertTrue(nested is not proto.optional_nested_message)
+ nested.bb = 23
+ self.assertTrue(not proto.HasField('optional_nested_message'))
+ self.assertEqual(0, proto.optional_nested_message.bb)
+
+ def testHasBitsWhenModifyingRepeatedFields(self):
+ # Test nesting when we add an element to a repeated field in a submessage.
+ proto = unittest_pb2.TestNestedMessageHasBits()
+ proto.optional_nested_message.nestedmessage_repeated_int32.append(5)
+ self.assertEqual(
+ [5], proto.optional_nested_message.nestedmessage_repeated_int32)
+ self.assertTrue(proto.HasField('optional_nested_message'))
+
+ # Do the same test, but with a repeated composite field within the
+ # submessage.
+ proto.ClearField('optional_nested_message')
+ self.assertTrue(not proto.HasField('optional_nested_message'))
+ proto.optional_nested_message.nestedmessage_repeated_foreignmessage.add()
+ self.assertTrue(proto.HasField('optional_nested_message'))
+
+ def testHasBitsForManyLevelsOfNesting(self):
+ # Test nesting many levels deep.
+ recursive_proto = unittest_pb2.TestMutualRecursionA()
+ self.assertTrue(not recursive_proto.HasField('bb'))
+ self.assertEqual(0, recursive_proto.bb.a.bb.a.bb.optional_int32)
+ self.assertTrue(not recursive_proto.HasField('bb'))
+ recursive_proto.bb.a.bb.a.bb.optional_int32 = 5
+ self.assertEqual(5, recursive_proto.bb.a.bb.a.bb.optional_int32)
+ self.assertTrue(recursive_proto.HasField('bb'))
+ self.assertTrue(recursive_proto.bb.HasField('a'))
+ self.assertTrue(recursive_proto.bb.a.HasField('bb'))
+ self.assertTrue(recursive_proto.bb.a.bb.HasField('a'))
+ self.assertTrue(recursive_proto.bb.a.bb.a.HasField('bb'))
+ self.assertTrue(not recursive_proto.bb.a.bb.a.bb.HasField('a'))
+ self.assertTrue(recursive_proto.bb.a.bb.a.bb.HasField('optional_int32'))
+
+ def testSingularListFields(self):
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_fixed32 = 1
+ proto.optional_int32 = 5
+ proto.optional_string = 'foo'
+ # Access sub-message but don't set it yet.
+ nested_message = proto.optional_nested_message
+ self.assertEqual(
+ [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 5),
+ (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1),
+ (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo') ],
+ proto.ListFields())
+
+ proto.optional_nested_message.bb = 123
+ self.assertEqual(
+ [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 5),
+ (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1),
+ (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo'),
+ (proto.DESCRIPTOR.fields_by_name['optional_nested_message' ],
+ nested_message) ],
+ proto.ListFields())
+
+ def testRepeatedListFields(self):
+ proto = unittest_pb2.TestAllTypes()
+ proto.repeated_fixed32.append(1)
+ proto.repeated_int32.append(5)
+ proto.repeated_int32.append(11)
+ proto.repeated_string.extend(['foo', 'bar'])
+ proto.repeated_string.extend([])
+ proto.repeated_string.append('baz')
+ proto.repeated_string.extend(str(x) for x in xrange(2))
+ proto.optional_int32 = 21
+ proto.repeated_bool # Access but don't set anything; should not be listed.
+ self.assertEqual(
+ [ (proto.DESCRIPTOR.fields_by_name['optional_int32' ], 21),
+ (proto.DESCRIPTOR.fields_by_name['repeated_int32' ], [5, 11]),
+ (proto.DESCRIPTOR.fields_by_name['repeated_fixed32'], [1]),
+ (proto.DESCRIPTOR.fields_by_name['repeated_string' ],
+ ['foo', 'bar', 'baz', '0', '1']) ],
+ proto.ListFields())
+
+ def testSingularListExtensions(self):
+ proto = unittest_pb2.TestAllExtensions()
+ proto.Extensions[unittest_pb2.optional_fixed32_extension] = 1
+ proto.Extensions[unittest_pb2.optional_int32_extension ] = 5
+ proto.Extensions[unittest_pb2.optional_string_extension ] = 'foo'
+ self.assertEqual(
+ [ (unittest_pb2.optional_int32_extension , 5),
+ (unittest_pb2.optional_fixed32_extension, 1),
+ (unittest_pb2.optional_string_extension , 'foo') ],
+ proto.ListFields())
+
+ def testRepeatedListExtensions(self):
+ proto = unittest_pb2.TestAllExtensions()
+ proto.Extensions[unittest_pb2.repeated_fixed32_extension].append(1)
+ proto.Extensions[unittest_pb2.repeated_int32_extension ].append(5)
+ proto.Extensions[unittest_pb2.repeated_int32_extension ].append(11)
+ proto.Extensions[unittest_pb2.repeated_string_extension ].append('foo')
+ proto.Extensions[unittest_pb2.repeated_string_extension ].append('bar')
+ proto.Extensions[unittest_pb2.repeated_string_extension ].append('baz')
+ proto.Extensions[unittest_pb2.optional_int32_extension ] = 21
+ self.assertEqual(
+ [ (unittest_pb2.optional_int32_extension , 21),
+ (unittest_pb2.repeated_int32_extension , [5, 11]),
+ (unittest_pb2.repeated_fixed32_extension, [1]),
+ (unittest_pb2.repeated_string_extension , ['foo', 'bar', 'baz']) ],
+ proto.ListFields())
+
+ def testListFieldsAndExtensions(self):
+ proto = unittest_pb2.TestFieldOrderings()
+ test_util.SetAllFieldsAndExtensions(proto)
+ unittest_pb2.my_extension_int
+ self.assertEqual(
+ [ (proto.DESCRIPTOR.fields_by_name['my_int' ], 1),
+ (unittest_pb2.my_extension_int , 23),
+ (proto.DESCRIPTOR.fields_by_name['my_string'], 'foo'),
+ (unittest_pb2.my_extension_string , 'bar'),
+ (proto.DESCRIPTOR.fields_by_name['my_float' ], 1.0) ],
+ proto.ListFields())
+
+ def testDefaultValues(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(0, proto.optional_int32)
+ self.assertEqual(0, proto.optional_int64)
+ self.assertEqual(0, proto.optional_uint32)
+ self.assertEqual(0, proto.optional_uint64)
+ self.assertEqual(0, proto.optional_sint32)
+ self.assertEqual(0, proto.optional_sint64)
+ self.assertEqual(0, proto.optional_fixed32)
+ self.assertEqual(0, proto.optional_fixed64)
+ self.assertEqual(0, proto.optional_sfixed32)
+ self.assertEqual(0, proto.optional_sfixed64)
+ self.assertEqual(0.0, proto.optional_float)
+ self.assertEqual(0.0, proto.optional_double)
+ self.assertEqual(False, proto.optional_bool)
+ self.assertEqual('', proto.optional_string)
+ self.assertEqual('', proto.optional_bytes)
+
+ self.assertEqual(41, proto.default_int32)
+ self.assertEqual(42, proto.default_int64)
+ self.assertEqual(43, proto.default_uint32)
+ self.assertEqual(44, proto.default_uint64)
+ self.assertEqual(-45, proto.default_sint32)
+ self.assertEqual(46, proto.default_sint64)
+ self.assertEqual(47, proto.default_fixed32)
+ self.assertEqual(48, proto.default_fixed64)
+ self.assertEqual(49, proto.default_sfixed32)
+ self.assertEqual(-50, proto.default_sfixed64)
+ self.assertEqual(51.5, proto.default_float)
+ self.assertEqual(52e3, proto.default_double)
+ self.assertEqual(True, proto.default_bool)
+ self.assertEqual('hello', proto.default_string)
+ self.assertEqual('world', proto.default_bytes)
+ self.assertEqual(unittest_pb2.TestAllTypes.BAR, proto.default_nested_enum)
+ self.assertEqual(unittest_pb2.FOREIGN_BAR, proto.default_foreign_enum)
+ self.assertEqual(unittest_import_pb2.IMPORT_BAR,
+ proto.default_import_enum)
+
+ proto = unittest_pb2.TestExtremeDefaultValues()
+ self.assertEqual(u'\u1234', proto.utf8_string)
+
+ def testHasFieldWithUnknownFieldName(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertRaises(ValueError, proto.HasField, 'nonexistent_field')
+
+ def testClearFieldWithUnknownFieldName(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertRaises(ValueError, proto.ClearField, 'nonexistent_field')
+
+ def testDisallowedAssignments(self):
+ # It's illegal to assign values directly to repeated fields
+ # or to nonrepeated composite fields. Ensure that this fails.
+ proto = unittest_pb2.TestAllTypes()
+ # Repeated fields.
+ self.assertRaises(AttributeError, setattr, proto, 'repeated_int32', 10)
+ # Lists shouldn't work, either.
+ self.assertRaises(AttributeError, setattr, proto, 'repeated_int32', [10])
+ # Composite fields.
+ self.assertRaises(AttributeError, setattr, proto,
+ 'optional_nested_message', 23)
+ # Assignment to a repeated nested message field without specifying
+ # the index in the array of nested messages.
+ self.assertRaises(AttributeError, setattr, proto.repeated_nested_message,
+ 'bb', 34)
+ # Assignment to an attribute of a repeated field.
+ self.assertRaises(AttributeError, setattr, proto.repeated_float,
+ 'some_attribute', 34)
+ # proto.nonexistent_field = 23 should fail as well.
+ self.assertRaises(AttributeError, setattr, proto, 'nonexistent_field', 23)
+
+ def testSingleScalarTypeSafety(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertRaises(TypeError, setattr, proto, 'optional_int32', 1.1)
+ self.assertRaises(TypeError, setattr, proto, 'optional_int32', 'foo')
+ self.assertRaises(TypeError, setattr, proto, 'optional_string', 10)
+ self.assertRaises(TypeError, setattr, proto, 'optional_bytes', 10)
+
+ def testSingleScalarBoundsChecking(self):
+ def TestMinAndMaxIntegers(field_name, expected_min, expected_max):
+ pb = unittest_pb2.TestAllTypes()
+ setattr(pb, field_name, expected_min)
+ self.assertEqual(expected_min, getattr(pb, field_name))
+ setattr(pb, field_name, expected_max)
+ self.assertEqual(expected_max, getattr(pb, field_name))
+ self.assertRaises(ValueError, setattr, pb, field_name, expected_min - 1)
+ self.assertRaises(ValueError, setattr, pb, field_name, expected_max + 1)
+
+ TestMinAndMaxIntegers('optional_int32', -(1 << 31), (1 << 31) - 1)
+ TestMinAndMaxIntegers('optional_uint32', 0, 0xffffffff)
+ TestMinAndMaxIntegers('optional_int64', -(1 << 63), (1 << 63) - 1)
+ TestMinAndMaxIntegers('optional_uint64', 0, 0xffffffffffffffff)
+
+ pb = unittest_pb2.TestAllTypes()
+ pb.optional_nested_enum = 1
+ self.assertEqual(1, pb.optional_nested_enum)
+
+ # Invalid enum values.
+ pb.optional_nested_enum = 0
+ self.assertEqual(0, pb.optional_nested_enum)
+
+ bytes_size_before = pb.ByteSize()
+
+ pb.optional_nested_enum = 4
+ self.assertEqual(4, pb.optional_nested_enum)
+
+ pb.optional_nested_enum = 0
+ self.assertEqual(0, pb.optional_nested_enum)
+
+ # Make sure that setting the same enum field doesn't just add unknown
+ # fields (but overwrites them).
+ self.assertEqual(bytes_size_before, pb.ByteSize())
+
+ # Is the invalid value preserved after serialization?
+ serialized = pb.SerializeToString()
+ pb2 = unittest_pb2.TestAllTypes()
+ pb2.ParseFromString(serialized)
+ self.assertEqual(0, pb2.optional_nested_enum)
+ self.assertEqual(pb, pb2)
+
+ def testRepeatedScalarTypeSafety(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertRaises(TypeError, proto.repeated_int32.append, 1.1)
+ self.assertRaises(TypeError, proto.repeated_int32.append, 'foo')
+ self.assertRaises(TypeError, proto.repeated_string, 10)
+ self.assertRaises(TypeError, proto.repeated_bytes, 10)
+
+ proto.repeated_int32.append(10)
+ proto.repeated_int32[0] = 23
+ self.assertRaises(IndexError, proto.repeated_int32.__setitem__, 500, 23)
+ self.assertRaises(TypeError, proto.repeated_int32.__setitem__, 0, 'abc')
+
+ # Repeated enums tests.
+ #proto.repeated_nested_enum.append(0)
+
+ def testSingleScalarGettersAndSetters(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(0, proto.optional_int32)
+ proto.optional_int32 = 1
+ self.assertEqual(1, proto.optional_int32)
+
+ proto.optional_uint64 = 0xffffffffffff
+ self.assertEqual(0xffffffffffff, proto.optional_uint64)
+ proto.optional_uint64 = 0xffffffffffffffff
+ self.assertEqual(0xffffffffffffffff, proto.optional_uint64)
+ # TODO(robinson): Test all other scalar field types.
+
+ def testSingleScalarClearField(self):
+ proto = unittest_pb2.TestAllTypes()
+ # Should be allowed to clear something that's not there (a no-op).
+ proto.ClearField('optional_int32')
+ proto.optional_int32 = 1
+ self.assertTrue(proto.HasField('optional_int32'))
+ proto.ClearField('optional_int32')
+ self.assertEqual(0, proto.optional_int32)
+ self.assertTrue(not proto.HasField('optional_int32'))
+ # TODO(robinson): Test all other scalar field types.
+
+ def testEnums(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(1, proto.FOO)
+ self.assertEqual(1, unittest_pb2.TestAllTypes.FOO)
+ self.assertEqual(2, proto.BAR)
+ self.assertEqual(2, unittest_pb2.TestAllTypes.BAR)
+ self.assertEqual(3, proto.BAZ)
+ self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
+
+ def testRepeatedScalars(self):
+ proto = unittest_pb2.TestAllTypes()
+
+ self.assertTrue(not proto.repeated_int32)
+ self.assertEqual(0, len(proto.repeated_int32))
+ proto.repeated_int32.append(5)
+ proto.repeated_int32.append(10)
+ proto.repeated_int32.append(15)
+ self.assertTrue(proto.repeated_int32)
+ self.assertEqual(3, len(proto.repeated_int32))
+
+ self.assertEqual([5, 10, 15], proto.repeated_int32)
+
+ # Test single retrieval.
+ self.assertEqual(5, proto.repeated_int32[0])
+ self.assertEqual(15, proto.repeated_int32[-1])
+ # Test out-of-bounds indices.
+ self.assertRaises(IndexError, proto.repeated_int32.__getitem__, 1234)
+ self.assertRaises(IndexError, proto.repeated_int32.__getitem__, -1234)
+ # Test incorrect types passed to __getitem__.
+ self.assertRaises(TypeError, proto.repeated_int32.__getitem__, 'foo')
+ self.assertRaises(TypeError, proto.repeated_int32.__getitem__, None)
+
+ # Test single assignment.
+ proto.repeated_int32[1] = 20
+ self.assertEqual([5, 20, 15], proto.repeated_int32)
+
+ # Test insertion.
+ proto.repeated_int32.insert(1, 25)
+ self.assertEqual([5, 25, 20, 15], proto.repeated_int32)
+
+ # Test slice retrieval.
+ proto.repeated_int32.append(30)
+ self.assertEqual([25, 20, 15], proto.repeated_int32[1:4])
+ self.assertEqual([5, 25, 20, 15, 30], proto.repeated_int32[:])
+
+ # Test slice assignment with an iterator
+ proto.repeated_int32[1:4] = (i for i in xrange(3))
+ self.assertEqual([5, 0, 1, 2, 30], proto.repeated_int32)
+
+ # Test slice assignment.
+ proto.repeated_int32[1:4] = [35, 40, 45]
+ self.assertEqual([5, 35, 40, 45, 30], proto.repeated_int32)
+
+ # Test that we can use the field as an iterator.
+ result = []
+ for i in proto.repeated_int32:
+ result.append(i)
+ self.assertEqual([5, 35, 40, 45, 30], result)
+
+ # Test single deletion.
+ del proto.repeated_int32[2]
+ self.assertEqual([5, 35, 45, 30], proto.repeated_int32)
+
+ # Test slice deletion.
+ del proto.repeated_int32[2:]
+ self.assertEqual([5, 35], proto.repeated_int32)
+
+ # Test extending.
+ proto.repeated_int32.extend([3, 13])
+ self.assertEqual([5, 35, 3, 13], proto.repeated_int32)
+
+ # Test clearing.
+ proto.ClearField('repeated_int32')
+ self.assertTrue(not proto.repeated_int32)
+ self.assertEqual(0, len(proto.repeated_int32))
+
+ proto.repeated_int32.append(1)
+ self.assertEqual(1, proto.repeated_int32[-1])
+ # Test assignment to a negative index.
+ proto.repeated_int32[-1] = 2
+ self.assertEqual(2, proto.repeated_int32[-1])
+
+ # Test deletion at negative indices.
+ proto.repeated_int32[:] = [0, 1, 2, 3]
+ del proto.repeated_int32[-1]
+ self.assertEqual([0, 1, 2], proto.repeated_int32)
+
+ del proto.repeated_int32[-2]
+ self.assertEqual([0, 2], proto.repeated_int32)
+
+ self.assertRaises(IndexError, proto.repeated_int32.__delitem__, -3)
+ self.assertRaises(IndexError, proto.repeated_int32.__delitem__, 300)
+
+ del proto.repeated_int32[-2:-1]
+ self.assertEqual([2], proto.repeated_int32)
+
+ del proto.repeated_int32[100:10000]
+ self.assertEqual([2], proto.repeated_int32)
+
+ def testRepeatedScalarsRemove(self):
+ proto = unittest_pb2.TestAllTypes()
+
+ self.assertTrue(not proto.repeated_int32)
+ self.assertEqual(0, len(proto.repeated_int32))
+ proto.repeated_int32.append(5)
+ proto.repeated_int32.append(10)
+ proto.repeated_int32.append(5)
+ proto.repeated_int32.append(5)
+
+ self.assertEqual(4, len(proto.repeated_int32))
+ proto.repeated_int32.remove(5)
+ self.assertEqual(3, len(proto.repeated_int32))
+ self.assertEqual(10, proto.repeated_int32[0])
+ self.assertEqual(5, proto.repeated_int32[1])
+ self.assertEqual(5, proto.repeated_int32[2])
+
+ proto.repeated_int32.remove(5)
+ self.assertEqual(2, len(proto.repeated_int32))
+ self.assertEqual(10, proto.repeated_int32[0])
+ self.assertEqual(5, proto.repeated_int32[1])
+
+ proto.repeated_int32.remove(10)
+ self.assertEqual(1, len(proto.repeated_int32))
+ self.assertEqual(5, proto.repeated_int32[0])
+
+ # Remove a non-existent element.
+ self.assertRaises(ValueError, proto.repeated_int32.remove, 123)
+
+ def testRepeatedComposites(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertTrue(not proto.repeated_nested_message)
+ self.assertEqual(0, len(proto.repeated_nested_message))
+ m0 = proto.repeated_nested_message.add()
+ m1 = proto.repeated_nested_message.add()
+ self.assertTrue(proto.repeated_nested_message)
+ self.assertEqual(2, len(proto.repeated_nested_message))
+ self.assertListsEqual([m0, m1], proto.repeated_nested_message)
+ self.assertTrue(isinstance(m0, unittest_pb2.TestAllTypes.NestedMessage))
+
+ # Test out-of-bounds indices.
+ self.assertRaises(IndexError, proto.repeated_nested_message.__getitem__,
+ 1234)
+ self.assertRaises(IndexError, proto.repeated_nested_message.__getitem__,
+ -1234)
+
+ # Test incorrect types passed to __getitem__.
+ self.assertRaises(TypeError, proto.repeated_nested_message.__getitem__,
+ 'foo')
+ self.assertRaises(TypeError, proto.repeated_nested_message.__getitem__,
+ None)
+
+ # Test slice retrieval.
+ m2 = proto.repeated_nested_message.add()
+ m3 = proto.repeated_nested_message.add()
+ m4 = proto.repeated_nested_message.add()
+ self.assertListsEqual(
+ [m1, m2, m3], proto.repeated_nested_message[1:4])
+ self.assertListsEqual(
+ [m0, m1, m2, m3, m4], proto.repeated_nested_message[:])
+ self.assertListsEqual(
+ [m0, m1], proto.repeated_nested_message[:2])
+ self.assertListsEqual(
+ [m2, m3, m4], proto.repeated_nested_message[2:])
+ self.assertEqual(
+ m0, proto.repeated_nested_message[0])
+ self.assertListsEqual(
+ [m0], proto.repeated_nested_message[:1])
+
+ # Test that we can use the field as an iterator.
+ result = []
+ for i in proto.repeated_nested_message:
+ result.append(i)
+ self.assertListsEqual([m0, m1, m2, m3, m4], result)
+
+ # Test single deletion.
+ del proto.repeated_nested_message[2]
+ self.assertListsEqual([m0, m1, m3, m4], proto.repeated_nested_message)
+
+ # Test slice deletion.
+ del proto.repeated_nested_message[2:]
+ self.assertListsEqual([m0, m1], proto.repeated_nested_message)
+
+ # Test extending.
+ n1 = unittest_pb2.TestAllTypes.NestedMessage(bb=1)
+ n2 = unittest_pb2.TestAllTypes.NestedMessage(bb=2)
+ proto.repeated_nested_message.extend([n1,n2])
+ self.assertEqual(4, len(proto.repeated_nested_message))
+ self.assertEqual(n1, proto.repeated_nested_message[2])
+ self.assertEqual(n2, proto.repeated_nested_message[3])
+
+ # Test clearing.
+ proto.ClearField('repeated_nested_message')
+ self.assertTrue(not proto.repeated_nested_message)
+ self.assertEqual(0, len(proto.repeated_nested_message))
+
+ # Test constructing an element while adding it.
+ proto.repeated_nested_message.add(bb=23)
+ self.assertEqual(1, len(proto.repeated_nested_message))
+ self.assertEqual(23, proto.repeated_nested_message[0].bb)
+
+ def testHandWrittenReflection(self):
+ # Hand written extensions are only supported by the pure-Python
+ # implementation of the API.
+ if api_implementation.Type() != 'python':
+ return
+
+ FieldDescriptor = descriptor.FieldDescriptor
+ foo_field_descriptor = FieldDescriptor(
+ name='foo_field', full_name='MyProto.foo_field',
+ index=0, number=1, type=FieldDescriptor.TYPE_INT64,
+ cpp_type=FieldDescriptor.CPPTYPE_INT64,
+ label=FieldDescriptor.LABEL_OPTIONAL, default_value=0,
+ containing_type=None, message_type=None, enum_type=None,
+ is_extension=False, extension_scope=None,
+ options=descriptor_pb2.FieldOptions())
+ mydescriptor = descriptor.Descriptor(
+ name='MyProto', full_name='MyProto', filename='ignored',
+ containing_type=None, nested_types=[], enum_types=[],
+ fields=[foo_field_descriptor], extensions=[],
+ options=descriptor_pb2.MessageOptions())
+ class MyProtoClass(message.Message):
+ DESCRIPTOR = mydescriptor
+ __metaclass__ = reflection.GeneratedProtocolMessageType
+ myproto_instance = MyProtoClass()
+ self.assertEqual(0, myproto_instance.foo_field)
+ self.assertTrue(not myproto_instance.HasField('foo_field'))
+ myproto_instance.foo_field = 23
+ self.assertEqual(23, myproto_instance.foo_field)
+ self.assertTrue(myproto_instance.HasField('foo_field'))
+
+ def testTopLevelExtensionsForOptionalScalar(self):
+ extendee_proto = unittest_pb2.TestAllExtensions()
+ extension = unittest_pb2.optional_int32_extension
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+ self.assertEqual(0, extendee_proto.Extensions[extension])
+ # As with normal scalar fields, just doing a read doesn't actually set the
+ # "has" bit.
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+ # Actually set the thing.
+ extendee_proto.Extensions[extension] = 23
+ self.assertEqual(23, extendee_proto.Extensions[extension])
+ self.assertTrue(extendee_proto.HasExtension(extension))
+ # Ensure that clearing works as well.
+ extendee_proto.ClearExtension(extension)
+ self.assertEqual(0, extendee_proto.Extensions[extension])
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+
+ def testTopLevelExtensionsForRepeatedScalar(self):
+ extendee_proto = unittest_pb2.TestAllExtensions()
+ extension = unittest_pb2.repeated_string_extension
+ self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+ extendee_proto.Extensions[extension].append('foo')
+ self.assertEqual(['foo'], extendee_proto.Extensions[extension])
+ string_list = extendee_proto.Extensions[extension]
+ extendee_proto.ClearExtension(extension)
+ self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+ self.assertTrue(string_list is not extendee_proto.Extensions[extension])
+ # Shouldn't be allowed to do Extensions[extension] = 'a'
+ self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+ extension, 'a')
+
+ def testTopLevelExtensionsForOptionalMessage(self):
+ extendee_proto = unittest_pb2.TestAllExtensions()
+ extension = unittest_pb2.optional_foreign_message_extension
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+ self.assertEqual(0, extendee_proto.Extensions[extension].c)
+ # As with normal (non-extension) fields, merely reading from the
+ # thing shouldn't set the "has" bit.
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+ extendee_proto.Extensions[extension].c = 23
+ self.assertEqual(23, extendee_proto.Extensions[extension].c)
+ self.assertTrue(extendee_proto.HasExtension(extension))
+ # Save a reference here.
+ foreign_message = extendee_proto.Extensions[extension]
+ extendee_proto.ClearExtension(extension)
+ self.assertTrue(foreign_message is not extendee_proto.Extensions[extension])
+ # Setting a field on foreign_message now shouldn't set
+ # any "has" bits on extendee_proto.
+ foreign_message.c = 42
+ self.assertEqual(42, foreign_message.c)
+ self.assertTrue(foreign_message.HasField('c'))
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+ # Shouldn't be allowed to do Extensions[extension] = 'a'
+ self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+ extension, 'a')
+
+ def testTopLevelExtensionsForRepeatedMessage(self):
+ extendee_proto = unittest_pb2.TestAllExtensions()
+ extension = unittest_pb2.repeatedgroup_extension
+ self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+ group = extendee_proto.Extensions[extension].add()
+ group.a = 23
+ self.assertEqual(23, extendee_proto.Extensions[extension][0].a)
+ group.a = 42
+ self.assertEqual(42, extendee_proto.Extensions[extension][0].a)
+ group_list = extendee_proto.Extensions[extension]
+ extendee_proto.ClearExtension(extension)
+ self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+ self.assertTrue(group_list is not extendee_proto.Extensions[extension])
+ # Shouldn't be allowed to do Extensions[extension] = 'a'
+ self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+ extension, 'a')
+
+ def testNestedExtensions(self):
+ extendee_proto = unittest_pb2.TestAllExtensions()
+ extension = unittest_pb2.TestRequired.single
+
+ # We just test the non-repeated case.
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+ required = extendee_proto.Extensions[extension]
+ self.assertEqual(0, required.a)
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+ required.a = 23
+ self.assertEqual(23, extendee_proto.Extensions[extension].a)
+ self.assertTrue(extendee_proto.HasExtension(extension))
+ extendee_proto.ClearExtension(extension)
+ self.assertTrue(required is not extendee_proto.Extensions[extension])
+ self.assertTrue(not extendee_proto.HasExtension(extension))
+
+ # If message A directly contains message B, and
+ # a.HasField('b') is currently False, then mutating any
+ # extension in B should change a.HasField('b') to True
+ # (and so on up the object tree).
+ def testHasBitsForAncestorsOfExtendedMessage(self):
+ # Optional scalar extension.
+ toplevel = more_extensions_pb2.TopLevelMessage()
+ self.assertTrue(not toplevel.HasField('submessage'))
+ self.assertEqual(0, toplevel.submessage.Extensions[
+ more_extensions_pb2.optional_int_extension])
+ self.assertTrue(not toplevel.HasField('submessage'))
+ toplevel.submessage.Extensions[
+ more_extensions_pb2.optional_int_extension] = 23
+ self.assertEqual(23, toplevel.submessage.Extensions[
+ more_extensions_pb2.optional_int_extension])
+ self.assertTrue(toplevel.HasField('submessage'))
+
+ # Repeated scalar extension.
+ toplevel = more_extensions_pb2.TopLevelMessage()
+ self.assertTrue(not toplevel.HasField('submessage'))
+ self.assertEqual([], toplevel.submessage.Extensions[
+ more_extensions_pb2.repeated_int_extension])
+ self.assertTrue(not toplevel.HasField('submessage'))
+ toplevel.submessage.Extensions[
+ more_extensions_pb2.repeated_int_extension].append(23)
+ self.assertEqual([23], toplevel.submessage.Extensions[
+ more_extensions_pb2.repeated_int_extension])
+ self.assertTrue(toplevel.HasField('submessage'))
+
+ # Optional message extension.
+ toplevel = more_extensions_pb2.TopLevelMessage()
+ self.assertTrue(not toplevel.HasField('submessage'))
+ self.assertEqual(0, toplevel.submessage.Extensions[
+ more_extensions_pb2.optional_message_extension].foreign_message_int)
+ self.assertTrue(not toplevel.HasField('submessage'))
+ toplevel.submessage.Extensions[
+ more_extensions_pb2.optional_message_extension].foreign_message_int = 23
+ self.assertEqual(23, toplevel.submessage.Extensions[
+ more_extensions_pb2.optional_message_extension].foreign_message_int)
+ self.assertTrue(toplevel.HasField('submessage'))
+
+ # Repeated message extension.
+ toplevel = more_extensions_pb2.TopLevelMessage()
+ self.assertTrue(not toplevel.HasField('submessage'))
+ self.assertEqual(0, len(toplevel.submessage.Extensions[
+ more_extensions_pb2.repeated_message_extension]))
+ self.assertTrue(not toplevel.HasField('submessage'))
+ foreign = toplevel.submessage.Extensions[
+ more_extensions_pb2.repeated_message_extension].add()
+ self.assertEqual(foreign, toplevel.submessage.Extensions[
+ more_extensions_pb2.repeated_message_extension][0])
+ self.assertTrue(toplevel.HasField('submessage'))
+
+ def testDisconnectionAfterClearingEmptyMessage(self):
+ toplevel = more_extensions_pb2.TopLevelMessage()
+ extendee_proto = toplevel.submessage
+ extension = more_extensions_pb2.optional_message_extension
+ extension_proto = extendee_proto.Extensions[extension]
+ extendee_proto.ClearExtension(extension)
+ extension_proto.foreign_message_int = 23
+
+ self.assertTrue(extension_proto is not extendee_proto.Extensions[extension])
+
+ def testExtensionFailureModes(self):
+ extendee_proto = unittest_pb2.TestAllExtensions()
+
+ # Try non-extension-handle arguments to HasExtension,
+ # ClearExtension(), and Extensions[]...
+ self.assertRaises(KeyError, extendee_proto.HasExtension, 1234)
+ self.assertRaises(KeyError, extendee_proto.ClearExtension, 1234)
+ self.assertRaises(KeyError, extendee_proto.Extensions.__getitem__, 1234)
+ self.assertRaises(KeyError, extendee_proto.Extensions.__setitem__, 1234, 5)
+
+ # Try something that *is* an extension handle, just not for
+ # this message...
+ unknown_handle = more_extensions_pb2.optional_int_extension
+ self.assertRaises(KeyError, extendee_proto.HasExtension,
+ unknown_handle)
+ self.assertRaises(KeyError, extendee_proto.ClearExtension,
+ unknown_handle)
+ self.assertRaises(KeyError, extendee_proto.Extensions.__getitem__,
+ unknown_handle)
+ self.assertRaises(KeyError, extendee_proto.Extensions.__setitem__,
+ unknown_handle, 5)
+
+ # Try call HasExtension() with a valid handle, but for a
+ # *repeated* field. (Just as with non-extension repeated
+ # fields, Has*() isn't supported for extension repeated fields).
+ self.assertRaises(KeyError, extendee_proto.HasExtension,
+ unittest_pb2.repeated_string_extension)
+
+ def testStaticParseFrom(self):
+ proto1 = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(proto1)
+
+ string1 = proto1.SerializeToString()
+ proto2 = unittest_pb2.TestAllTypes.FromString(string1)
+
+ # Messages should be equal.
+ self.assertEqual(proto2, proto1)
+
+ def testMergeFromSingularField(self):
+ # Test merge with just a singular field.
+ proto1 = unittest_pb2.TestAllTypes()
+ proto1.optional_int32 = 1
+
+ proto2 = unittest_pb2.TestAllTypes()
+ # This shouldn't get overwritten.
+ proto2.optional_string = 'value'
+
+ proto2.MergeFrom(proto1)
+ self.assertEqual(1, proto2.optional_int32)
+ self.assertEqual('value', proto2.optional_string)
+
+ def testMergeFromRepeatedField(self):
+ # Test merge with just a repeated field.
+ proto1 = unittest_pb2.TestAllTypes()
+ proto1.repeated_int32.append(1)
+ proto1.repeated_int32.append(2)
+
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.repeated_int32.append(0)
+ proto2.MergeFrom(proto1)
+
+ self.assertEqual(0, proto2.repeated_int32[0])
+ self.assertEqual(1, proto2.repeated_int32[1])
+ self.assertEqual(2, proto2.repeated_int32[2])
+
+ def testMergeFromOptionalGroup(self):
+ # Test merge with an optional group.
+ proto1 = unittest_pb2.TestAllTypes()
+ proto1.optionalgroup.a = 12
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.MergeFrom(proto1)
+ self.assertEqual(12, proto2.optionalgroup.a)
+
+ def testMergeFromRepeatedNestedMessage(self):
+ # Test merge with a repeated nested message.
+ proto1 = unittest_pb2.TestAllTypes()
+ m = proto1.repeated_nested_message.add()
+ m.bb = 123
+ m = proto1.repeated_nested_message.add()
+ m.bb = 321
+
+ proto2 = unittest_pb2.TestAllTypes()
+ m = proto2.repeated_nested_message.add()
+ m.bb = 999
+ proto2.MergeFrom(proto1)
+ self.assertEqual(999, proto2.repeated_nested_message[0].bb)
+ self.assertEqual(123, proto2.repeated_nested_message[1].bb)
+ self.assertEqual(321, proto2.repeated_nested_message[2].bb)
+
+ proto3 = unittest_pb2.TestAllTypes()
+ proto3.repeated_nested_message.MergeFrom(proto2.repeated_nested_message)
+ self.assertEqual(999, proto3.repeated_nested_message[0].bb)
+ self.assertEqual(123, proto3.repeated_nested_message[1].bb)
+ self.assertEqual(321, proto3.repeated_nested_message[2].bb)
+
+ def testMergeFromAllFields(self):
+ # With all fields set.
+ proto1 = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(proto1)
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.MergeFrom(proto1)
+
+ # Messages should be equal.
+ self.assertEqual(proto2, proto1)
+
+ # Serialized string should be equal too.
+ string1 = proto1.SerializeToString()
+ string2 = proto2.SerializeToString()
+ self.assertEqual(string1, string2)
+
+ def testMergeFromExtensionsSingular(self):
+ proto1 = unittest_pb2.TestAllExtensions()
+ proto1.Extensions[unittest_pb2.optional_int32_extension] = 1
+
+ proto2 = unittest_pb2.TestAllExtensions()
+ proto2.MergeFrom(proto1)
+ self.assertEqual(
+ 1, proto2.Extensions[unittest_pb2.optional_int32_extension])
+
+ def testMergeFromExtensionsRepeated(self):
+ proto1 = unittest_pb2.TestAllExtensions()
+ proto1.Extensions[unittest_pb2.repeated_int32_extension].append(1)
+ proto1.Extensions[unittest_pb2.repeated_int32_extension].append(2)
+
+ proto2 = unittest_pb2.TestAllExtensions()
+ proto2.Extensions[unittest_pb2.repeated_int32_extension].append(0)
+ proto2.MergeFrom(proto1)
+ self.assertEqual(
+ 3, len(proto2.Extensions[unittest_pb2.repeated_int32_extension]))
+ self.assertEqual(
+ 0, proto2.Extensions[unittest_pb2.repeated_int32_extension][0])
+ self.assertEqual(
+ 1, proto2.Extensions[unittest_pb2.repeated_int32_extension][1])
+ self.assertEqual(
+ 2, proto2.Extensions[unittest_pb2.repeated_int32_extension][2])
+
+ def testMergeFromExtensionsNestedMessage(self):
+ proto1 = unittest_pb2.TestAllExtensions()
+ ext1 = proto1.Extensions[
+ unittest_pb2.repeated_nested_message_extension]
+ m = ext1.add()
+ m.bb = 222
+ m = ext1.add()
+ m.bb = 333
+
+ proto2 = unittest_pb2.TestAllExtensions()
+ ext2 = proto2.Extensions[
+ unittest_pb2.repeated_nested_message_extension]
+ m = ext2.add()
+ m.bb = 111
+
+ proto2.MergeFrom(proto1)
+ ext2 = proto2.Extensions[
+ unittest_pb2.repeated_nested_message_extension]
+ self.assertEqual(3, len(ext2))
+ self.assertEqual(111, ext2[0].bb)
+ self.assertEqual(222, ext2[1].bb)
+ self.assertEqual(333, ext2[2].bb)
+
+ def testMergeFromBug(self):
+ message1 = unittest_pb2.TestAllTypes()
+ message2 = unittest_pb2.TestAllTypes()
+
+ # Cause optional_nested_message to be instantiated within message1, even
+ # though it is not considered to be "present".
+ message1.optional_nested_message
+ self.assertFalse(message1.HasField('optional_nested_message'))
+
+ # Merge into message2. This should not instantiate the field is message2.
+ message2.MergeFrom(message1)
+ self.assertFalse(message2.HasField('optional_nested_message'))
+
+ def testCopyFromSingularField(self):
+ # Test copy with just a singular field.
+ proto1 = unittest_pb2.TestAllTypes()
+ proto1.optional_int32 = 1
+ proto1.optional_string = 'important-text'
+
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.optional_string = 'value'
+
+ proto2.CopyFrom(proto1)
+ self.assertEqual(1, proto2.optional_int32)
+ self.assertEqual('important-text', proto2.optional_string)
+
+ def testCopyFromRepeatedField(self):
+ # Test copy with a repeated field.
+ proto1 = unittest_pb2.TestAllTypes()
+ proto1.repeated_int32.append(1)
+ proto1.repeated_int32.append(2)
+
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.repeated_int32.append(0)
+ proto2.CopyFrom(proto1)
+
+ self.assertEqual(1, proto2.repeated_int32[0])
+ self.assertEqual(2, proto2.repeated_int32[1])
+
+ def testCopyFromAllFields(self):
+ # With all fields set.
+ proto1 = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(proto1)
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.CopyFrom(proto1)
+
+ # Messages should be equal.
+ self.assertEqual(proto2, proto1)
+
+ # Serialized string should be equal too.
+ string1 = proto1.SerializeToString()
+ string2 = proto2.SerializeToString()
+ self.assertEqual(string1, string2)
+
+ def testCopyFromSelf(self):
+ proto1 = unittest_pb2.TestAllTypes()
+ proto1.repeated_int32.append(1)
+ proto1.optional_int32 = 2
+ proto1.optional_string = 'important-text'
+
+ proto1.CopyFrom(proto1)
+ self.assertEqual(1, proto1.repeated_int32[0])
+ self.assertEqual(2, proto1.optional_int32)
+ self.assertEqual('important-text', proto1.optional_string)
+
+ def testCopyFromBadType(self):
+ # The python implementation doesn't raise an exception in this
+ # case. In theory it should.
+ if api_implementation.Type() == 'python':
+ return
+ proto1 = unittest_pb2.TestAllTypes()
+ proto2 = unittest_pb2.TestAllExtensions()
+ self.assertRaises(TypeError, proto1.CopyFrom, proto2)
+
+ def testClear(self):
+ proto = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(proto)
+ # Clear the message.
+ proto.Clear()
+ self.assertEquals(proto.ByteSize(), 0)
+ empty_proto = unittest_pb2.TestAllTypes()
+ self.assertEquals(proto, empty_proto)
+
+ # Test if extensions which were set are cleared.
+ proto = unittest_pb2.TestAllExtensions()
+ test_util.SetAllExtensions(proto)
+ # Clear the message.
+ proto.Clear()
+ self.assertEquals(proto.ByteSize(), 0)
+ empty_proto = unittest_pb2.TestAllExtensions()
+ self.assertEquals(proto, empty_proto)
+
+ def assertInitialized(self, proto):
+ self.assertTrue(proto.IsInitialized())
+ # Neither method should raise an exception.
+ proto.SerializeToString()
+ proto.SerializePartialToString()
+
+ def assertNotInitialized(self, proto):
+ self.assertFalse(proto.IsInitialized())
+ self.assertRaises(message.EncodeError, proto.SerializeToString)
+ # "Partial" serialization doesn't care if message is uninitialized.
+ proto.SerializePartialToString()
+
+ def testIsInitialized(self):
+ # Trivial cases - all optional fields and extensions.
+ proto = unittest_pb2.TestAllTypes()
+ self.assertInitialized(proto)
+ proto = unittest_pb2.TestAllExtensions()
+ self.assertInitialized(proto)
+
+ # The case of uninitialized required fields.
+ proto = unittest_pb2.TestRequired()
+ self.assertNotInitialized(proto)
+ proto.a = proto.b = proto.c = 2
+ self.assertInitialized(proto)
+
+ # The case of uninitialized submessage.
+ proto = unittest_pb2.TestRequiredForeign()
+ self.assertInitialized(proto)
+ proto.optional_message.a = 1
+ self.assertNotInitialized(proto)
+ proto.optional_message.b = 0
+ proto.optional_message.c = 0
+ self.assertInitialized(proto)
+
+ # Uninitialized repeated submessage.
+ message1 = proto.repeated_message.add()
+ self.assertNotInitialized(proto)
+ message1.a = message1.b = message1.c = 0
+ self.assertInitialized(proto)
+
+ # Uninitialized repeated group in an extension.
+ proto = unittest_pb2.TestAllExtensions()
+ extension = unittest_pb2.TestRequired.multi
+ message1 = proto.Extensions[extension].add()
+ message2 = proto.Extensions[extension].add()
+ self.assertNotInitialized(proto)
+ message1.a = 1
+ message1.b = 1
+ message1.c = 1
+ self.assertNotInitialized(proto)
+ message2.a = 2
+ message2.b = 2
+ message2.c = 2
+ self.assertInitialized(proto)
+
+ # Uninitialized nonrepeated message in an extension.
+ proto = unittest_pb2.TestAllExtensions()
+ extension = unittest_pb2.TestRequired.single
+ proto.Extensions[extension].a = 1
+ self.assertNotInitialized(proto)
+ proto.Extensions[extension].b = 2
+ proto.Extensions[extension].c = 3
+ self.assertInitialized(proto)
+
+ # Try passing an errors list.
+ errors = []
+ proto = unittest_pb2.TestRequired()
+ self.assertFalse(proto.IsInitialized(errors))
+ self.assertEqual(errors, ['a', 'b', 'c'])
+
+ def testStringUTF8Encoding(self):
+ proto = unittest_pb2.TestAllTypes()
+
+ # Assignment of a unicode object to a field of type 'bytes' is not allowed.
+ self.assertRaises(TypeError,
+ setattr, proto, 'optional_bytes', u'unicode object')
+
+ # Check that the default value is of python's 'unicode' type.
+ self.assertEqual(type(proto.optional_string), unicode)
+
+ proto.optional_string = unicode('Testing')
+ self.assertEqual(proto.optional_string, str('Testing'))
+
+ # Assign a value of type 'str' which can be encoded in UTF-8.
+ proto.optional_string = str('Testing')
+ self.assertEqual(proto.optional_string, unicode('Testing'))
+
+ if api_implementation.Type() == 'python':
+ # Values of type 'str' are also accepted as long as they can be
+ # encoded in UTF-8.
+ self.assertEqual(type(proto.optional_string), str)
+
+ # Try to assign a 'str' value which contains bytes that aren't 7-bit ASCII.
+ self.assertRaises(ValueError,
+ setattr, proto, 'optional_string', str('a\x80a'))
+ # Assign a 'str' object which contains a UTF-8 encoded string.
+ self.assertRaises(ValueError,
+ setattr, proto, 'optional_string', 'Тест')
+ # No exception thrown.
+ proto.optional_string = 'abc'
+
+ def testStringUTF8Serialization(self):
+ proto = unittest_mset_pb2.TestMessageSet()
+ extension_message = unittest_mset_pb2.TestMessageSetExtension2
+ extension = extension_message.message_set_extension
+
+ test_utf8 = u'Тест'
+ test_utf8_bytes = test_utf8.encode('utf-8')
+
+ # 'Test' in another language, using UTF-8 charset.
+ proto.Extensions[extension].str = test_utf8
+
+ # Serialize using the MessageSet wire format (this is specified in the
+ # .proto file).
+ serialized = proto.SerializeToString()
+
+ # Check byte size.
+ self.assertEqual(proto.ByteSize(), len(serialized))
+
+ raw = unittest_mset_pb2.RawMessageSet()
+ raw.MergeFromString(serialized)
+
+ message2 = unittest_mset_pb2.TestMessageSetExtension2()
+
+ self.assertEqual(1, len(raw.item))
+ # Check that the type_id is the same as the tag ID in the .proto file.
+ self.assertEqual(raw.item[0].type_id, 1547769)
+
+ # Check the actual bytes on the wire.
+ self.assertTrue(
+ raw.item[0].message.endswith(test_utf8_bytes))
+ message2.MergeFromString(raw.item[0].message)
+
+ self.assertEqual(type(message2.str), unicode)
+ self.assertEqual(message2.str, test_utf8)
+
+ # The pure Python API throws an exception on MergeFromString(),
+ # if any of the string fields of the message can't be UTF-8 decoded.
+ # The C++ implementation of the API has no way to check that on
+ # MergeFromString and thus has no way to throw the exception.
+ #
+ # The pure Python API always returns objects of type 'unicode' (UTF-8
+ # encoded), or 'str' (in 7 bit ASCII).
+ bytes = raw.item[0].message.replace(
+ test_utf8_bytes, len(test_utf8_bytes) * '\xff')
+
+ unicode_decode_failed = False
+ try:
+ message2.MergeFromString(bytes)
+ except UnicodeDecodeError, e:
+ unicode_decode_failed = True
+ string_field = message2.str
+ self.assertTrue(unicode_decode_failed or type(string_field) == str)
+
+ def testEmptyNestedMessage(self):
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_nested_message.MergeFrom(
+ unittest_pb2.TestAllTypes.NestedMessage())
+ self.assertTrue(proto.HasField('optional_nested_message'))
+
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_nested_message.CopyFrom(
+ unittest_pb2.TestAllTypes.NestedMessage())
+ self.assertTrue(proto.HasField('optional_nested_message'))
+
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_nested_message.MergeFromString('')
+ self.assertTrue(proto.HasField('optional_nested_message'))
+
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_nested_message.ParseFromString('')
+ self.assertTrue(proto.HasField('optional_nested_message'))
+
+ serialized = proto.SerializeToString()
+ proto2 = unittest_pb2.TestAllTypes()
+ proto2.MergeFromString(serialized)
+ self.assertTrue(proto2.HasField('optional_nested_message'))
+
+ def testSetInParent(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertFalse(proto.HasField('optionalgroup'))
+ proto.optionalgroup.SetInParent()
+ self.assertTrue(proto.HasField('optionalgroup'))
+
+
+# Since we had so many tests for protocol buffer equality, we broke these out
+# into separate TestCase classes.
+
+
+class TestAllTypesEqualityTest(unittest.TestCase):
+
+ def setUp(self):
+ self.first_proto = unittest_pb2.TestAllTypes()
+ self.second_proto = unittest_pb2.TestAllTypes()
+
+ def testNotHashable(self):
+ self.assertRaises(TypeError, hash, self.first_proto)
+
+ def testSelfEquality(self):
+ self.assertEqual(self.first_proto, self.first_proto)
+
+ def testEmptyProtosEqual(self):
+ self.assertEqual(self.first_proto, self.second_proto)
+
+
+class FullProtosEqualityTest(unittest.TestCase):
+
+ """Equality tests using completely-full protos as a starting point."""
+
+ def setUp(self):
+ self.first_proto = unittest_pb2.TestAllTypes()
+ self.second_proto = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(self.first_proto)
+ test_util.SetAllFields(self.second_proto)
+
+ def testNotHashable(self):
+ self.assertRaises(TypeError, hash, self.first_proto)
+
+ def testNoneNotEqual(self):
+ self.assertNotEqual(self.first_proto, None)
+ self.assertNotEqual(None, self.second_proto)
+
+ def testNotEqualToOtherMessage(self):
+ third_proto = unittest_pb2.TestRequired()
+ self.assertNotEqual(self.first_proto, third_proto)
+ self.assertNotEqual(third_proto, self.second_proto)
+
+ def testAllFieldsFilledEquality(self):
+ self.assertEqual(self.first_proto, self.second_proto)
+
+ def testNonRepeatedScalar(self):
+ # Nonrepeated scalar field change should cause inequality.
+ self.first_proto.optional_int32 += 1
+ self.assertNotEqual(self.first_proto, self.second_proto)
+ # ...as should clearing a field.
+ self.first_proto.ClearField('optional_int32')
+ self.assertNotEqual(self.first_proto, self.second_proto)
+
+ def testNonRepeatedComposite(self):
+ # Change a nonrepeated composite field.
+ self.first_proto.optional_nested_message.bb += 1
+ self.assertNotEqual(self.first_proto, self.second_proto)
+ self.first_proto.optional_nested_message.bb -= 1
+ self.assertEqual(self.first_proto, self.second_proto)
+ # Clear a field in the nested message.
+ self.first_proto.optional_nested_message.ClearField('bb')
+ self.assertNotEqual(self.first_proto, self.second_proto)
+ self.first_proto.optional_nested_message.bb = (
+ self.second_proto.optional_nested_message.bb)
+ self.assertEqual(self.first_proto, self.second_proto)
+ # Remove the nested message entirely.
+ self.first_proto.ClearField('optional_nested_message')
+ self.assertNotEqual(self.first_proto, self.second_proto)
+
+ def testRepeatedScalar(self):
+ # Change a repeated scalar field.
+ self.first_proto.repeated_int32.append(5)
+ self.assertNotEqual(self.first_proto, self.second_proto)
+ self.first_proto.ClearField('repeated_int32')
+ self.assertNotEqual(self.first_proto, self.second_proto)
+
+ def testRepeatedComposite(self):
+ # Change value within a repeated composite field.
+ self.first_proto.repeated_nested_message[0].bb += 1
+ self.assertNotEqual(self.first_proto, self.second_proto)
+ self.first_proto.repeated_nested_message[0].bb -= 1
+ self.assertEqual(self.first_proto, self.second_proto)
+ # Add a value to a repeated composite field.
+ self.first_proto.repeated_nested_message.add()
+ self.assertNotEqual(self.first_proto, self.second_proto)
+ self.second_proto.repeated_nested_message.add()
+ self.assertEqual(self.first_proto, self.second_proto)
+
+ def testNonRepeatedScalarHasBits(self):
+ # Ensure that we test "has" bits as well as value for
+ # nonrepeated scalar field.
+ self.first_proto.ClearField('optional_int32')
+ self.second_proto.optional_int32 = 0
+ self.assertNotEqual(self.first_proto, self.second_proto)
+
+ def testNonRepeatedCompositeHasBits(self):
+ # Ensure that we test "has" bits as well as value for
+ # nonrepeated composite field.
+ self.first_proto.ClearField('optional_nested_message')
+ self.second_proto.optional_nested_message.ClearField('bb')
+ self.assertNotEqual(self.first_proto, self.second_proto)
+ self.first_proto.optional_nested_message.bb = 0
+ self.first_proto.optional_nested_message.ClearField('bb')
+ self.assertEqual(self.first_proto, self.second_proto)
+
+
+class ExtensionEqualityTest(unittest.TestCase):
+
+ def testExtensionEquality(self):
+ first_proto = unittest_pb2.TestAllExtensions()
+ second_proto = unittest_pb2.TestAllExtensions()
+ self.assertEqual(first_proto, second_proto)
+ test_util.SetAllExtensions(first_proto)
+ self.assertNotEqual(first_proto, second_proto)
+ test_util.SetAllExtensions(second_proto)
+ self.assertEqual(first_proto, second_proto)
+
+ # Ensure that we check value equality.
+ first_proto.Extensions[unittest_pb2.optional_int32_extension] += 1
+ self.assertNotEqual(first_proto, second_proto)
+ first_proto.Extensions[unittest_pb2.optional_int32_extension] -= 1
+ self.assertEqual(first_proto, second_proto)
+
+ # Ensure that we also look at "has" bits.
+ first_proto.ClearExtension(unittest_pb2.optional_int32_extension)
+ second_proto.Extensions[unittest_pb2.optional_int32_extension] = 0
+ self.assertNotEqual(first_proto, second_proto)
+ first_proto.Extensions[unittest_pb2.optional_int32_extension] = 0
+ self.assertEqual(first_proto, second_proto)
+
+ # Ensure that differences in cached values
+ # don't matter if "has" bits are both false.
+ first_proto = unittest_pb2.TestAllExtensions()
+ second_proto = unittest_pb2.TestAllExtensions()
+ self.assertEqual(
+ 0, first_proto.Extensions[unittest_pb2.optional_int32_extension])
+ self.assertEqual(first_proto, second_proto)
+
+
+class MutualRecursionEqualityTest(unittest.TestCase):
+
+ def testEqualityWithMutualRecursion(self):
+ first_proto = unittest_pb2.TestMutualRecursionA()
+ second_proto = unittest_pb2.TestMutualRecursionA()
+ self.assertEqual(first_proto, second_proto)
+ first_proto.bb.a.bb.optional_int32 = 23
+ self.assertNotEqual(first_proto, second_proto)
+ second_proto.bb.a.bb.optional_int32 = 23
+ self.assertEqual(first_proto, second_proto)
+
+
+class ByteSizeTest(unittest.TestCase):
+
+ def setUp(self):
+ self.proto = unittest_pb2.TestAllTypes()
+ self.extended_proto = more_extensions_pb2.ExtendedMessage()
+ self.packed_proto = unittest_pb2.TestPackedTypes()
+ self.packed_extended_proto = unittest_pb2.TestPackedExtensions()
+
+ def Size(self):
+ return self.proto.ByteSize()
+
+ def testEmptyMessage(self):
+ self.assertEqual(0, self.proto.ByteSize())
+
+ def testSizedOnKwargs(self):
+ # Use a separate message to ensure testing right after creation.
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(0, proto.ByteSize())
+ proto_kwargs = unittest_pb2.TestAllTypes(optional_int64 = 1)
+ # One byte for the tag, one to encode varint 1.
+ self.assertEqual(2, proto_kwargs.ByteSize())
+
+ def testVarints(self):
+ def Test(i, expected_varint_size):
+ self.proto.Clear()
+ self.proto.optional_int64 = i
+ # Add one to the varint size for the tag info
+ # for tag 1.
+ self.assertEqual(expected_varint_size + 1, self.Size())
+ Test(0, 1)
+ Test(1, 1)
+ for i, num_bytes in zip(range(7, 63, 7), range(1, 10000)):
+ Test((1 << i) - 1, num_bytes)
+ Test(-1, 10)
+ Test(-2, 10)
+ Test(-(1 << 63), 10)
+
+ def testStrings(self):
+ self.proto.optional_string = ''
+ # Need one byte for tag info (tag #14), and one byte for length.
+ self.assertEqual(2, self.Size())
+
+ self.proto.optional_string = 'abc'
+ # Need one byte for tag info (tag #14), and one byte for length.
+ self.assertEqual(2 + len(self.proto.optional_string), self.Size())
+
+ self.proto.optional_string = 'x' * 128
+ # Need one byte for tag info (tag #14), and TWO bytes for length.
+ self.assertEqual(3 + len(self.proto.optional_string), self.Size())
+
+ def testOtherNumerics(self):
+ self.proto.optional_fixed32 = 1234
+ # One byte for tag and 4 bytes for fixed32.
+ self.assertEqual(5, self.Size())
+ self.proto = unittest_pb2.TestAllTypes()
+
+ self.proto.optional_fixed64 = 1234
+ # One byte for tag and 8 bytes for fixed64.
+ self.assertEqual(9, self.Size())
+ self.proto = unittest_pb2.TestAllTypes()
+
+ self.proto.optional_float = 1.234
+ # One byte for tag and 4 bytes for float.
+ self.assertEqual(5, self.Size())
+ self.proto = unittest_pb2.TestAllTypes()
+
+ self.proto.optional_double = 1.234
+ # One byte for tag and 8 bytes for float.
+ self.assertEqual(9, self.Size())
+ self.proto = unittest_pb2.TestAllTypes()
+
+ self.proto.optional_sint32 = 64
+ # One byte for tag and 2 bytes for zig-zag-encoded 64.
+ self.assertEqual(3, self.Size())
+ self.proto = unittest_pb2.TestAllTypes()
+
+ def testComposites(self):
+ # 3 bytes.
+ self.proto.optional_nested_message.bb = (1 << 14)
+ # Plus one byte for bb tag.
+ # Plus 1 byte for optional_nested_message serialized size.
+ # Plus two bytes for optional_nested_message tag.
+ self.assertEqual(3 + 1 + 1 + 2, self.Size())
+
+ def testGroups(self):
+ # 4 bytes.
+ self.proto.optionalgroup.a = (1 << 21)
+ # Plus two bytes for |a| tag.
+ # Plus 2 * two bytes for START_GROUP and END_GROUP tags.
+ self.assertEqual(4 + 2 + 2*2, self.Size())
+
+ def testRepeatedScalars(self):
+ self.proto.repeated_int32.append(10) # 1 byte.
+ self.proto.repeated_int32.append(128) # 2 bytes.
+ # Also need 2 bytes for each entry for tag.
+ self.assertEqual(1 + 2 + 2*2, self.Size())
+
+ def testRepeatedScalarsExtend(self):
+ self.proto.repeated_int32.extend([10, 128]) # 3 bytes.
+ # Also need 2 bytes for each entry for tag.
+ self.assertEqual(1 + 2 + 2*2, self.Size())
+
+ def testRepeatedScalarsRemove(self):
+ self.proto.repeated_int32.append(10) # 1 byte.
+ self.proto.repeated_int32.append(128) # 2 bytes.
+ # Also need 2 bytes for each entry for tag.
+ self.assertEqual(1 + 2 + 2*2, self.Size())
+ self.proto.repeated_int32.remove(128)
+ self.assertEqual(1 + 2, self.Size())
+
+ def testRepeatedComposites(self):
+ # Empty message. 2 bytes tag plus 1 byte length.
+ foreign_message_0 = self.proto.repeated_nested_message.add()
+ # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+ foreign_message_1 = self.proto.repeated_nested_message.add()
+ foreign_message_1.bb = 7
+ self.assertEqual(2 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+ def testRepeatedCompositesDelete(self):
+ # Empty message. 2 bytes tag plus 1 byte length.
+ foreign_message_0 = self.proto.repeated_nested_message.add()
+ # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+ foreign_message_1 = self.proto.repeated_nested_message.add()
+ foreign_message_1.bb = 9
+ self.assertEqual(2 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+ # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+ del self.proto.repeated_nested_message[0]
+ self.assertEqual(2 + 1 + 1 + 1, self.Size())
+
+ # Now add a new message.
+ foreign_message_2 = self.proto.repeated_nested_message.add()
+ foreign_message_2.bb = 12
+
+ # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+ # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+ self.assertEqual(2 + 1 + 1 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+ # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+ del self.proto.repeated_nested_message[1]
+ self.assertEqual(2 + 1 + 1 + 1, self.Size())
+
+ del self.proto.repeated_nested_message[0]
+ self.assertEqual(0, self.Size())
+
+ def testRepeatedGroups(self):
+ # 2-byte START_GROUP plus 2-byte END_GROUP.
+ group_0 = self.proto.repeatedgroup.add()
+ # 2-byte START_GROUP plus 2-byte |a| tag + 1-byte |a|
+ # plus 2-byte END_GROUP.
+ group_1 = self.proto.repeatedgroup.add()
+ group_1.a = 7
+ self.assertEqual(2 + 2 + 2 + 2 + 1 + 2, self.Size())
+
+ def testExtensions(self):
+ proto = unittest_pb2.TestAllExtensions()
+ self.assertEqual(0, proto.ByteSize())
+ extension = unittest_pb2.optional_int32_extension # Field #1, 1 byte.
+ proto.Extensions[extension] = 23
+ # 1 byte for tag, 1 byte for value.
+ self.assertEqual(2, proto.ByteSize())
+
+ def testCacheInvalidationForNonrepeatedScalar(self):
+ # Test non-extension.
+ self.proto.optional_int32 = 1
+ self.assertEqual(2, self.proto.ByteSize())
+ self.proto.optional_int32 = 128
+ self.assertEqual(3, self.proto.ByteSize())
+ self.proto.ClearField('optional_int32')
+ self.assertEqual(0, self.proto.ByteSize())
+
+ # Test within extension.
+ extension = more_extensions_pb2.optional_int_extension
+ self.extended_proto.Extensions[extension] = 1
+ self.assertEqual(2, self.extended_proto.ByteSize())
+ self.extended_proto.Extensions[extension] = 128
+ self.assertEqual(3, self.extended_proto.ByteSize())
+ self.extended_proto.ClearExtension(extension)
+ self.assertEqual(0, self.extended_proto.ByteSize())
+
+ def testCacheInvalidationForRepeatedScalar(self):
+ # Test non-extension.
+ self.proto.repeated_int32.append(1)
+ self.assertEqual(3, self.proto.ByteSize())
+ self.proto.repeated_int32.append(1)
+ self.assertEqual(6, self.proto.ByteSize())
+ self.proto.repeated_int32[1] = 128
+ self.assertEqual(7, self.proto.ByteSize())
+ self.proto.ClearField('repeated_int32')
+ self.assertEqual(0, self.proto.ByteSize())
+
+ # Test within extension.
+ extension = more_extensions_pb2.repeated_int_extension
+ repeated = self.extended_proto.Extensions[extension]
+ repeated.append(1)
+ self.assertEqual(2, self.extended_proto.ByteSize())
+ repeated.append(1)
+ self.assertEqual(4, self.extended_proto.ByteSize())
+ repeated[1] = 128
+ self.assertEqual(5, self.extended_proto.ByteSize())
+ self.extended_proto.ClearExtension(extension)
+ self.assertEqual(0, self.extended_proto.ByteSize())
+
+ def testCacheInvalidationForNonrepeatedMessage(self):
+ # Test non-extension.
+ self.proto.optional_foreign_message.c = 1
+ self.assertEqual(5, self.proto.ByteSize())
+ self.proto.optional_foreign_message.c = 128
+ self.assertEqual(6, self.proto.ByteSize())
+ self.proto.optional_foreign_message.ClearField('c')
+ self.assertEqual(3, self.proto.ByteSize())
+ self.proto.ClearField('optional_foreign_message')
+ self.assertEqual(0, self.proto.ByteSize())
+
+ if api_implementation.Type() == 'python':
+ # This is only possible in pure-Python implementation of the API.
+ child = self.proto.optional_foreign_message
+ self.proto.ClearField('optional_foreign_message')
+ child.c = 128
+ self.assertEqual(0, self.proto.ByteSize())
+
+ # Test within extension.
+ extension = more_extensions_pb2.optional_message_extension
+ child = self.extended_proto.Extensions[extension]
+ self.assertEqual(0, self.extended_proto.ByteSize())
+ child.foreign_message_int = 1
+ self.assertEqual(4, self.extended_proto.ByteSize())
+ child.foreign_message_int = 128
+ self.assertEqual(5, self.extended_proto.ByteSize())
+ self.extended_proto.ClearExtension(extension)
+ self.assertEqual(0, self.extended_proto.ByteSize())
+
+ def testCacheInvalidationForRepeatedMessage(self):
+ # Test non-extension.
+ child0 = self.proto.repeated_foreign_message.add()
+ self.assertEqual(3, self.proto.ByteSize())
+ self.proto.repeated_foreign_message.add()
+ self.assertEqual(6, self.proto.ByteSize())
+ child0.c = 1
+ self.assertEqual(8, self.proto.ByteSize())
+ self.proto.ClearField('repeated_foreign_message')
+ self.assertEqual(0, self.proto.ByteSize())
+
+ # Test within extension.
+ extension = more_extensions_pb2.repeated_message_extension
+ child_list = self.extended_proto.Extensions[extension]
+ child0 = child_list.add()
+ self.assertEqual(2, self.extended_proto.ByteSize())
+ child_list.add()
+ self.assertEqual(4, self.extended_proto.ByteSize())
+ child0.foreign_message_int = 1
+ self.assertEqual(6, self.extended_proto.ByteSize())
+ child0.ClearField('foreign_message_int')
+ self.assertEqual(4, self.extended_proto.ByteSize())
+ self.extended_proto.ClearExtension(extension)
+ self.assertEqual(0, self.extended_proto.ByteSize())
+
+ def testPackedRepeatedScalars(self):
+ self.assertEqual(0, self.packed_proto.ByteSize())
+
+ self.packed_proto.packed_int32.append(10) # 1 byte.
+ self.packed_proto.packed_int32.append(128) # 2 bytes.
+ # The tag is 2 bytes (the field number is 90), and the varint
+ # storing the length is 1 byte.
+ int_size = 1 + 2 + 3
+ self.assertEqual(int_size, self.packed_proto.ByteSize())
+
+ self.packed_proto.packed_double.append(4.2) # 8 bytes
+ self.packed_proto.packed_double.append(3.25) # 8 bytes
+ # 2 more tag bytes, 1 more length byte.
+ double_size = 8 + 8 + 3
+ self.assertEqual(int_size+double_size, self.packed_proto.ByteSize())
+
+ self.packed_proto.ClearField('packed_int32')
+ self.assertEqual(double_size, self.packed_proto.ByteSize())
+
+ def testPackedExtensions(self):
+ self.assertEqual(0, self.packed_extended_proto.ByteSize())
+ extension = self.packed_extended_proto.Extensions[
+ unittest_pb2.packed_fixed32_extension]
+ extension.extend([1, 2, 3, 4]) # 16 bytes
+ # Tag is 3 bytes.
+ self.assertEqual(19, self.packed_extended_proto.ByteSize())
+
+
+# Issues to be sure to cover include:
+# * Handling of unrecognized tags ("uninterpreted_bytes").
+# * Handling of MessageSets.
+# * Consistent ordering of tags in the wire format,
+# including ordering between extensions and non-extension
+# fields.
+# * Consistent serialization of negative numbers, especially
+# negative int32s.
+# * Handling of empty submessages (with and without "has"
+# bits set).
+
+class SerializationTest(unittest.TestCase):
+
+ def testSerializeEmtpyMessage(self):
+ first_proto = unittest_pb2.TestAllTypes()
+ second_proto = unittest_pb2.TestAllTypes()
+ serialized = first_proto.SerializeToString()
+ self.assertEqual(first_proto.ByteSize(), len(serialized))
+ second_proto.MergeFromString(serialized)
+ self.assertEqual(first_proto, second_proto)
+
+ def testSerializeAllFields(self):
+ first_proto = unittest_pb2.TestAllTypes()
+ second_proto = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(first_proto)
+ serialized = first_proto.SerializeToString()
+ self.assertEqual(first_proto.ByteSize(), len(serialized))
+ second_proto.MergeFromString(serialized)
+ self.assertEqual(first_proto, second_proto)
+
+ def testSerializeAllExtensions(self):
+ first_proto = unittest_pb2.TestAllExtensions()
+ second_proto = unittest_pb2.TestAllExtensions()
+ test_util.SetAllExtensions(first_proto)
+ serialized = first_proto.SerializeToString()
+ second_proto.MergeFromString(serialized)
+ self.assertEqual(first_proto, second_proto)
+
+ def testSerializeNegativeValues(self):
+ first_proto = unittest_pb2.TestAllTypes()
+
+ first_proto.optional_int32 = -1
+ first_proto.optional_int64 = -(2 << 40)
+ first_proto.optional_sint32 = -3
+ first_proto.optional_sint64 = -(4 << 40)
+ first_proto.optional_sfixed32 = -5
+ first_proto.optional_sfixed64 = -(6 << 40)
+
+ second_proto = unittest_pb2.TestAllTypes.FromString(
+ first_proto.SerializeToString())
+
+ self.assertEqual(first_proto, second_proto)
+
+ def testParseTruncated(self):
+ # This test is only applicable for the Python implementation of the API.
+ if api_implementation.Type() != 'python':
+ return
+
+ first_proto = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(first_proto)
+ serialized = first_proto.SerializeToString()
+
+ for truncation_point in xrange(len(serialized) + 1):
+ try:
+ second_proto = unittest_pb2.TestAllTypes()
+ unknown_fields = unittest_pb2.TestEmptyMessage()
+ pos = second_proto._InternalParse(serialized, 0, truncation_point)
+ # If we didn't raise an error then we read exactly the amount expected.
+ self.assertEqual(truncation_point, pos)
+
+ # Parsing to unknown fields should not throw if parsing to known fields
+ # did not.
+ try:
+ pos2 = unknown_fields._InternalParse(serialized, 0, truncation_point)
+ self.assertEqual(truncation_point, pos2)
+ except message.DecodeError:
+ self.fail('Parsing unknown fields failed when parsing known fields '
+ 'did not.')
+ except message.DecodeError:
+ # Parsing unknown fields should also fail.
+ self.assertRaises(message.DecodeError, unknown_fields._InternalParse,
+ serialized, 0, truncation_point)
+
+ def testCanonicalSerializationOrder(self):
+ proto = more_messages_pb2.OutOfOrderFields()
+ # These are also their tag numbers. Even though we're setting these in
+ # reverse-tag order AND they're listed in reverse tag-order in the .proto
+ # file, they should nonetheless be serialized in tag order.
+ proto.optional_sint32 = 5
+ proto.Extensions[more_messages_pb2.optional_uint64] = 4
+ proto.optional_uint32 = 3
+ proto.Extensions[more_messages_pb2.optional_int64] = 2
+ proto.optional_int32 = 1
+ serialized = proto.SerializeToString()
+ self.assertEqual(proto.ByteSize(), len(serialized))
+ d = _MiniDecoder(serialized)
+ ReadTag = d.ReadFieldNumberAndWireType
+ self.assertEqual((1, wire_format.WIRETYPE_VARINT), ReadTag())
+ self.assertEqual(1, d.ReadInt32())
+ self.assertEqual((2, wire_format.WIRETYPE_VARINT), ReadTag())
+ self.assertEqual(2, d.ReadInt64())
+ self.assertEqual((3, wire_format.WIRETYPE_VARINT), ReadTag())
+ self.assertEqual(3, d.ReadUInt32())
+ self.assertEqual((4, wire_format.WIRETYPE_VARINT), ReadTag())
+ self.assertEqual(4, d.ReadUInt64())
+ self.assertEqual((5, wire_format.WIRETYPE_VARINT), ReadTag())
+ self.assertEqual(5, d.ReadSInt32())
+
+ def testCanonicalSerializationOrderSameAsCpp(self):
+ # Copy of the same test we use for C++.
+ proto = unittest_pb2.TestFieldOrderings()
+ test_util.SetAllFieldsAndExtensions(proto)
+ serialized = proto.SerializeToString()
+ test_util.ExpectAllFieldsAndExtensionsInOrder(serialized)
+
+ def testMergeFromStringWhenFieldsAlreadySet(self):
+ first_proto = unittest_pb2.TestAllTypes()
+ first_proto.repeated_string.append('foobar')
+ first_proto.optional_int32 = 23
+ first_proto.optional_nested_message.bb = 42
+ serialized = first_proto.SerializeToString()
+
+ second_proto = unittest_pb2.TestAllTypes()
+ second_proto.repeated_string.append('baz')
+ second_proto.optional_int32 = 100
+ second_proto.optional_nested_message.bb = 999
+
+ second_proto.MergeFromString(serialized)
+ # Ensure that we append to repeated fields.
+ self.assertEqual(['baz', 'foobar'], list(second_proto.repeated_string))
+ # Ensure that we overwrite nonrepeatd scalars.
+ self.assertEqual(23, second_proto.optional_int32)
+ # Ensure that we recursively call MergeFromString() on
+ # submessages.
+ self.assertEqual(42, second_proto.optional_nested_message.bb)
+
+ def testMessageSetWireFormat(self):
+ proto = unittest_mset_pb2.TestMessageSet()
+ extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
+ extension_message2 = unittest_mset_pb2.TestMessageSetExtension2
+ extension1 = extension_message1.message_set_extension
+ extension2 = extension_message2.message_set_extension
+ proto.Extensions[extension1].i = 123
+ proto.Extensions[extension2].str = 'foo'
+
+ # Serialize using the MessageSet wire format (this is specified in the
+ # .proto file).
+ serialized = proto.SerializeToString()
+
+ raw = unittest_mset_pb2.RawMessageSet()
+ self.assertEqual(False,
+ raw.DESCRIPTOR.GetOptions().message_set_wire_format)
+ raw.MergeFromString(serialized)
+ self.assertEqual(2, len(raw.item))
+
+ message1 = unittest_mset_pb2.TestMessageSetExtension1()
+ message1.MergeFromString(raw.item[0].message)
+ self.assertEqual(123, message1.i)
+
+ message2 = unittest_mset_pb2.TestMessageSetExtension2()
+ message2.MergeFromString(raw.item[1].message)
+ self.assertEqual('foo', message2.str)
+
+ # Deserialize using the MessageSet wire format.
+ proto2 = unittest_mset_pb2.TestMessageSet()
+ proto2.MergeFromString(serialized)
+ self.assertEqual(123, proto2.Extensions[extension1].i)
+ self.assertEqual('foo', proto2.Extensions[extension2].str)
+
+ # Check byte size.
+ self.assertEqual(proto2.ByteSize(), len(serialized))
+ self.assertEqual(proto.ByteSize(), len(serialized))
+
+ def testMessageSetWireFormatUnknownExtension(self):
+ # Create a message using the message set wire format with an unknown
+ # message.
+ raw = unittest_mset_pb2.RawMessageSet()
+
+ # Add an item.
+ item = raw.item.add()
+ item.type_id = 1545008
+ extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
+ message1 = unittest_mset_pb2.TestMessageSetExtension1()
+ message1.i = 12345
+ item.message = message1.SerializeToString()
+
+ # Add a second, unknown extension.
+ item = raw.item.add()
+ item.type_id = 1545009
+ extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
+ message1 = unittest_mset_pb2.TestMessageSetExtension1()
+ message1.i = 12346
+ item.message = message1.SerializeToString()
+
+ # Add another unknown extension.
+ item = raw.item.add()
+ item.type_id = 1545010
+ message1 = unittest_mset_pb2.TestMessageSetExtension2()
+ message1.str = 'foo'
+ item.message = message1.SerializeToString()
+
+ serialized = raw.SerializeToString()
+
+ # Parse message using the message set wire format.
+ proto = unittest_mset_pb2.TestMessageSet()
+ proto.MergeFromString(serialized)
+
+ # Check that the message parsed well.
+ extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
+ extension1 = extension_message1.message_set_extension
+ self.assertEquals(12345, proto.Extensions[extension1].i)
+
+ def testUnknownFields(self):
+ proto = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(proto)
+
+ serialized = proto.SerializeToString()
+
+ # The empty message should be parsable with all of the fields
+ # unknown.
+ proto2 = unittest_pb2.TestEmptyMessage()
+
+ # Parsing this message should succeed.
+ proto2.MergeFromString(serialized)
+
+ # Now test with a int64 field set.
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_int64 = 0x0fffffffffffffff
+ serialized = proto.SerializeToString()
+ # The empty message should be parsable with all of the fields
+ # unknown.
+ proto2 = unittest_pb2.TestEmptyMessage()
+ # Parsing this message should succeed.
+ proto2.MergeFromString(serialized)
+
+ def _CheckRaises(self, exc_class, callable_obj, exception):
+ """This method checks if the excpetion type and message are as expected."""
+ try:
+ callable_obj()
+ except exc_class, ex:
+ # Check if the exception message is the right one.
+ self.assertEqual(exception, str(ex))
+ return
+ else:
+ raise self.failureException('%s not raised' % str(exc_class))
+
+ def testSerializeUninitialized(self):
+ proto = unittest_pb2.TestRequired()
+ self._CheckRaises(
+ message.EncodeError,
+ proto.SerializeToString,
+ 'Message is missing required fields: a,b,c')
+ # Shouldn't raise exceptions.
+ partial = proto.SerializePartialToString()
+
+ proto.a = 1
+ self._CheckRaises(
+ message.EncodeError,
+ proto.SerializeToString,
+ 'Message is missing required fields: b,c')
+ # Shouldn't raise exceptions.
+ partial = proto.SerializePartialToString()
+
+ proto.b = 2
+ self._CheckRaises(
+ message.EncodeError,
+ proto.SerializeToString,
+ 'Message is missing required fields: c')
+ # Shouldn't raise exceptions.
+ partial = proto.SerializePartialToString()
+
+ proto.c = 3
+ serialized = proto.SerializeToString()
+ # Shouldn't raise exceptions.
+ partial = proto.SerializePartialToString()
+
+ proto2 = unittest_pb2.TestRequired()
+ proto2.MergeFromString(serialized)
+ self.assertEqual(1, proto2.a)
+ self.assertEqual(2, proto2.b)
+ self.assertEqual(3, proto2.c)
+ proto2.ParseFromString(partial)
+ self.assertEqual(1, proto2.a)
+ self.assertEqual(2, proto2.b)
+ self.assertEqual(3, proto2.c)
+
+ def testSerializeUninitializedSubMessage(self):
+ proto = unittest_pb2.TestRequiredForeign()
+
+ # Sub-message doesn't exist yet, so this succeeds.
+ proto.SerializeToString()
+
+ proto.optional_message.a = 1
+ self._CheckRaises(
+ message.EncodeError,
+ proto.SerializeToString,
+ 'Message is missing required fields: '
+ 'optional_message.b,optional_message.c')
+
+ proto.optional_message.b = 2
+ proto.optional_message.c = 3
+ proto.SerializeToString()
+
+ proto.repeated_message.add().a = 1
+ proto.repeated_message.add().b = 2
+ self._CheckRaises(
+ message.EncodeError,
+ proto.SerializeToString,
+ 'Message is missing required fields: '
+ 'repeated_message[0].b,repeated_message[0].c,'
+ 'repeated_message[1].a,repeated_message[1].c')
+
+ proto.repeated_message[0].b = 2
+ proto.repeated_message[0].c = 3
+ proto.repeated_message[1].a = 1
+ proto.repeated_message[1].c = 3
+ proto.SerializeToString()
+
+ def testSerializeAllPackedFields(self):
+ first_proto = unittest_pb2.TestPackedTypes()
+ second_proto = unittest_pb2.TestPackedTypes()
+ test_util.SetAllPackedFields(first_proto)
+ serialized = first_proto.SerializeToString()
+ self.assertEqual(first_proto.ByteSize(), len(serialized))
+ bytes_read = second_proto.MergeFromString(serialized)
+ self.assertEqual(second_proto.ByteSize(), bytes_read)
+ self.assertEqual(first_proto, second_proto)
+
+ def testSerializeAllPackedExtensions(self):
+ first_proto = unittest_pb2.TestPackedExtensions()
+ second_proto = unittest_pb2.TestPackedExtensions()
+ test_util.SetAllPackedExtensions(first_proto)
+ serialized = first_proto.SerializeToString()
+ bytes_read = second_proto.MergeFromString(serialized)
+ self.assertEqual(second_proto.ByteSize(), bytes_read)
+ self.assertEqual(first_proto, second_proto)
+
+ def testMergePackedFromStringWhenSomeFieldsAlreadySet(self):
+ first_proto = unittest_pb2.TestPackedTypes()
+ first_proto.packed_int32.extend([1, 2])
+ first_proto.packed_double.append(3.0)
+ serialized = first_proto.SerializeToString()
+
+ second_proto = unittest_pb2.TestPackedTypes()
+ second_proto.packed_int32.append(3)
+ second_proto.packed_double.extend([1.0, 2.0])
+ second_proto.packed_sint32.append(4)
+
+ second_proto.MergeFromString(serialized)
+ self.assertEqual([3, 1, 2], second_proto.packed_int32)
+ self.assertEqual([1.0, 2.0, 3.0], second_proto.packed_double)
+ self.assertEqual([4], second_proto.packed_sint32)
+
+ def testPackedFieldsWireFormat(self):
+ proto = unittest_pb2.TestPackedTypes()
+ proto.packed_int32.extend([1, 2, 150, 3]) # 1 + 1 + 2 + 1 bytes
+ proto.packed_double.extend([1.0, 1000.0]) # 8 + 8 bytes
+ proto.packed_float.append(2.0) # 4 bytes, will be before double
+ serialized = proto.SerializeToString()
+ self.assertEqual(proto.ByteSize(), len(serialized))
+ d = _MiniDecoder(serialized)
+ ReadTag = d.ReadFieldNumberAndWireType
+ self.assertEqual((90, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+ self.assertEqual(1+1+1+2, d.ReadInt32())
+ self.assertEqual(1, d.ReadInt32())
+ self.assertEqual(2, d.ReadInt32())
+ self.assertEqual(150, d.ReadInt32())
+ self.assertEqual(3, d.ReadInt32())
+ self.assertEqual((100, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+ self.assertEqual(4, d.ReadInt32())
+ self.assertEqual(2.0, d.ReadFloat())
+ self.assertEqual((101, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+ self.assertEqual(8+8, d.ReadInt32())
+ self.assertEqual(1.0, d.ReadDouble())
+ self.assertEqual(1000.0, d.ReadDouble())
+ self.assertTrue(d.EndOfStream())
+
+ def testParsePackedFromUnpacked(self):
+ unpacked = unittest_pb2.TestUnpackedTypes()
+ test_util.SetAllUnpackedFields(unpacked)
+ packed = unittest_pb2.TestPackedTypes()
+ packed.MergeFromString(unpacked.SerializeToString())
+ expected = unittest_pb2.TestPackedTypes()
+ test_util.SetAllPackedFields(expected)
+ self.assertEqual(expected, packed)
+
+ def testParseUnpackedFromPacked(self):
+ packed = unittest_pb2.TestPackedTypes()
+ test_util.SetAllPackedFields(packed)
+ unpacked = unittest_pb2.TestUnpackedTypes()
+ unpacked.MergeFromString(packed.SerializeToString())
+ expected = unittest_pb2.TestUnpackedTypes()
+ test_util.SetAllUnpackedFields(expected)
+ self.assertEqual(expected, unpacked)
+
+ def testFieldNumbers(self):
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(unittest_pb2.TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1)
+ self.assertEqual(unittest_pb2.TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1)
+ self.assertEqual(unittest_pb2.TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21)
+ self.assertEqual(unittest_pb2.TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31)
+ self.assertEqual(unittest_pb2.TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48)
+ self.assertEqual(
+ unittest_pb2.TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51)
+
+ def testExtensionFieldNumbers(self):
+ self.assertEqual(unittest_pb2.TestRequired.single.number, 1000)
+ self.assertEqual(unittest_pb2.TestRequired.SINGLE_FIELD_NUMBER, 1000)
+ self.assertEqual(unittest_pb2.TestRequired.multi.number, 1001)
+ self.assertEqual(unittest_pb2.TestRequired.MULTI_FIELD_NUMBER, 1001)
+ self.assertEqual(unittest_pb2.optional_int32_extension.number, 1)
+ self.assertEqual(unittest_pb2.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1)
+ self.assertEqual(unittest_pb2.optionalgroup_extension.number, 16)
+ self.assertEqual(unittest_pb2.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16)
+ self.assertEqual(unittest_pb2.optional_nested_message_extension.number, 18)
+ self.assertEqual(
+ unittest_pb2.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18)
+ self.assertEqual(unittest_pb2.optional_nested_enum_extension.number, 21)
+ self.assertEqual(unittest_pb2.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
+ 21)
+ self.assertEqual(unittest_pb2.repeated_int32_extension.number, 31)
+ self.assertEqual(unittest_pb2.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31)
+ self.assertEqual(unittest_pb2.repeatedgroup_extension.number, 46)
+ self.assertEqual(unittest_pb2.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46)
+ self.assertEqual(unittest_pb2.repeated_nested_message_extension.number, 48)
+ self.assertEqual(
+ unittest_pb2.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48)
+ self.assertEqual(unittest_pb2.repeated_nested_enum_extension.number, 51)
+ self.assertEqual(unittest_pb2.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
+ 51)
+
+ def testInitKwargs(self):
+ proto = unittest_pb2.TestAllTypes(
+ optional_int32=1,
+ optional_string='foo',
+ optional_bool=True,
+ optional_bytes='bar',
+ optional_nested_message=unittest_pb2.TestAllTypes.NestedMessage(bb=1),
+ optional_foreign_message=unittest_pb2.ForeignMessage(c=1),
+ optional_nested_enum=unittest_pb2.TestAllTypes.FOO,
+ optional_foreign_enum=unittest_pb2.FOREIGN_FOO,
+ repeated_int32=[1, 2, 3])
+ self.assertTrue(proto.IsInitialized())
+ self.assertTrue(proto.HasField('optional_int32'))
+ self.assertTrue(proto.HasField('optional_string'))
+ self.assertTrue(proto.HasField('optional_bool'))
+ self.assertTrue(proto.HasField('optional_bytes'))
+ self.assertTrue(proto.HasField('optional_nested_message'))
+ self.assertTrue(proto.HasField('optional_foreign_message'))
+ self.assertTrue(proto.HasField('optional_nested_enum'))
+ self.assertTrue(proto.HasField('optional_foreign_enum'))
+ self.assertEqual(1, proto.optional_int32)
+ self.assertEqual('foo', proto.optional_string)
+ self.assertEqual(True, proto.optional_bool)
+ self.assertEqual('bar', proto.optional_bytes)
+ self.assertEqual(1, proto.optional_nested_message.bb)
+ self.assertEqual(1, proto.optional_foreign_message.c)
+ self.assertEqual(unittest_pb2.TestAllTypes.FOO,
+ proto.optional_nested_enum)
+ self.assertEqual(unittest_pb2.FOREIGN_FOO, proto.optional_foreign_enum)
+ self.assertEqual([1, 2, 3], proto.repeated_int32)
+
+ def testInitArgsUnknownFieldName(self):
+ def InitalizeEmptyMessageWithExtraKeywordArg():
+ unused_proto = unittest_pb2.TestEmptyMessage(unknown='unknown')
+ self._CheckRaises(ValueError,
+ InitalizeEmptyMessageWithExtraKeywordArg,
+ 'Protocol message has no "unknown" field.')
+
+ def testInitRequiredKwargs(self):
+ proto = unittest_pb2.TestRequired(a=1, b=1, c=1)
+ self.assertTrue(proto.IsInitialized())
+ self.assertTrue(proto.HasField('a'))
+ self.assertTrue(proto.HasField('b'))
+ self.assertTrue(proto.HasField('c'))
+ self.assertTrue(not proto.HasField('dummy2'))
+ self.assertEqual(1, proto.a)
+ self.assertEqual(1, proto.b)
+ self.assertEqual(1, proto.c)
+
+ def testInitRequiredForeignKwargs(self):
+ proto = unittest_pb2.TestRequiredForeign(
+ optional_message=unittest_pb2.TestRequired(a=1, b=1, c=1))
+ self.assertTrue(proto.IsInitialized())
+ self.assertTrue(proto.HasField('optional_message'))
+ self.assertTrue(proto.optional_message.IsInitialized())
+ self.assertTrue(proto.optional_message.HasField('a'))
+ self.assertTrue(proto.optional_message.HasField('b'))
+ self.assertTrue(proto.optional_message.HasField('c'))
+ self.assertTrue(not proto.optional_message.HasField('dummy2'))
+ self.assertEqual(unittest_pb2.TestRequired(a=1, b=1, c=1),
+ proto.optional_message)
+ self.assertEqual(1, proto.optional_message.a)
+ self.assertEqual(1, proto.optional_message.b)
+ self.assertEqual(1, proto.optional_message.c)
+
+ def testInitRepeatedKwargs(self):
+ proto = unittest_pb2.TestAllTypes(repeated_int32=[1, 2, 3])
+ self.assertTrue(proto.IsInitialized())
+ self.assertEqual(1, proto.repeated_int32[0])
+ self.assertEqual(2, proto.repeated_int32[1])
+ self.assertEqual(3, proto.repeated_int32[2])
+
+
+class OptionsTest(unittest.TestCase):
+
+ def testMessageOptions(self):
+ proto = unittest_mset_pb2.TestMessageSet()
+ self.assertEqual(True,
+ proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+ proto = unittest_pb2.TestAllTypes()
+ self.assertEqual(False,
+ proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+
+ def testPackedOptions(self):
+ proto = unittest_pb2.TestAllTypes()
+ proto.optional_int32 = 1
+ proto.optional_double = 3.0
+ for field_descriptor, _ in proto.ListFields():
+ self.assertEqual(False, field_descriptor.GetOptions().packed)
+
+ proto = unittest_pb2.TestPackedTypes()
+ proto.packed_int32.append(1)
+ proto.packed_double.append(3.0)
+ for field_descriptor, _ in proto.ListFields():
+ self.assertEqual(True, field_descriptor.GetOptions().packed)
+ self.assertEqual(reflection._FieldDescriptor.LABEL_REPEATED,
+ field_descriptor.label)
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/service_reflection_test.py b/src/third_party/protobuf/python/google/protobuf/internal/service_reflection_test.py
new file mode 100755
index 0000000..e04f825
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/service_reflection_test.py
@@ -0,0 +1,136 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.internal.service_reflection."""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+import unittest
+from google.protobuf import unittest_pb2
+from google.protobuf import service_reflection
+from google.protobuf import service
+
+
+class FooUnitTest(unittest.TestCase):
+
+ def testService(self):
+ class MockRpcChannel(service.RpcChannel):
+ def CallMethod(self, method, controller, request, response, callback):
+ self.method = method
+ self.controller = controller
+ self.request = request
+ callback(response)
+
+ class MockRpcController(service.RpcController):
+ def SetFailed(self, msg):
+ self.failure_message = msg
+
+ self.callback_response = None
+
+ class MyService(unittest_pb2.TestService):
+ pass
+
+ self.callback_response = None
+
+ def MyCallback(response):
+ self.callback_response = response
+
+ rpc_controller = MockRpcController()
+ channel = MockRpcChannel()
+ srvc = MyService()
+ srvc.Foo(rpc_controller, unittest_pb2.FooRequest(), MyCallback)
+ self.assertEqual('Method Foo not implemented.',
+ rpc_controller.failure_message)
+ self.assertEqual(None, self.callback_response)
+
+ rpc_controller.failure_message = None
+
+ service_descriptor = unittest_pb2.TestService.GetDescriptor()
+ srvc.CallMethod(service_descriptor.methods[1], rpc_controller,
+ unittest_pb2.BarRequest(), MyCallback)
+ self.assertEqual('Method Bar not implemented.',
+ rpc_controller.failure_message)
+ self.assertEqual(None, self.callback_response)
+
+ class MyServiceImpl(unittest_pb2.TestService):
+ def Foo(self, rpc_controller, request, done):
+ self.foo_called = True
+ def Bar(self, rpc_controller, request, done):
+ self.bar_called = True
+
+ srvc = MyServiceImpl()
+ rpc_controller.failure_message = None
+ srvc.Foo(rpc_controller, unittest_pb2.FooRequest(), MyCallback)
+ self.assertEqual(None, rpc_controller.failure_message)
+ self.assertEqual(True, srvc.foo_called)
+
+ rpc_controller.failure_message = None
+ srvc.CallMethod(service_descriptor.methods[1], rpc_controller,
+ unittest_pb2.BarRequest(), MyCallback)
+ self.assertEqual(None, rpc_controller.failure_message)
+ self.assertEqual(True, srvc.bar_called)
+
+ def testServiceStub(self):
+ class MockRpcChannel(service.RpcChannel):
+ def CallMethod(self, method, controller, request,
+ response_class, callback):
+ self.method = method
+ self.controller = controller
+ self.request = request
+ callback(response_class())
+
+ self.callback_response = None
+
+ def MyCallback(response):
+ self.callback_response = response
+
+ channel = MockRpcChannel()
+ stub = unittest_pb2.TestService_Stub(channel)
+ rpc_controller = 'controller'
+ request = 'request'
+
+ # GetDescriptor now static, still works as instance method for compatability
+ self.assertEqual(unittest_pb2.TestService_Stub.GetDescriptor(),
+ stub.GetDescriptor())
+
+ # Invoke method.
+ stub.Foo(rpc_controller, request, MyCallback)
+
+ self.assertTrue(isinstance(self.callback_response,
+ unittest_pb2.FooResponse))
+ self.assertEqual(request, channel.request)
+ self.assertEqual(rpc_controller, channel.controller)
+ self.assertEqual(stub.GetDescriptor().methods[0], channel.method)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/test_util.py b/src/third_party/protobuf/python/google/protobuf/internal/test_util.py
new file mode 100755
index 0000000..1df1619
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/test_util.py
@@ -0,0 +1,635 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Utilities for Python proto2 tests.
+
+This is intentionally modeled on C++ code in
+//google/protobuf/test_util.*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import os.path
+
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+
+
+def SetAllFields(message):
+ """Sets every field in the message to a unique value.
+
+ Args:
+ message: A unittest_pb2.TestAllTypes instance.
+ """
+
+ #
+ # Optional fields.
+ #
+
+ message.optional_int32 = 101
+ message.optional_int64 = 102
+ message.optional_uint32 = 103
+ message.optional_uint64 = 104
+ message.optional_sint32 = 105
+ message.optional_sint64 = 106
+ message.optional_fixed32 = 107
+ message.optional_fixed64 = 108
+ message.optional_sfixed32 = 109
+ message.optional_sfixed64 = 110
+ message.optional_float = 111
+ message.optional_double = 112
+ message.optional_bool = True
+ # TODO(robinson): Firmly spec out and test how
+ # protos interact with unicode. One specific example:
+ # what happens if we change the literal below to
+ # u'115'? What *should* happen? Still some discussion
+ # to finish with Kenton about bytes vs. strings
+ # and forcing everything to be utf8. :-/
+ message.optional_string = '115'
+ message.optional_bytes = '116'
+
+ message.optionalgroup.a = 117
+ message.optional_nested_message.bb = 118
+ message.optional_foreign_message.c = 119
+ message.optional_import_message.d = 120
+
+ message.optional_nested_enum = unittest_pb2.TestAllTypes.BAZ
+ message.optional_foreign_enum = unittest_pb2.FOREIGN_BAZ
+ message.optional_import_enum = unittest_import_pb2.IMPORT_BAZ
+
+ message.optional_string_piece = '124'
+ message.optional_cord = '125'
+
+ #
+ # Repeated fields.
+ #
+
+ message.repeated_int32.append(201)
+ message.repeated_int64.append(202)
+ message.repeated_uint32.append(203)
+ message.repeated_uint64.append(204)
+ message.repeated_sint32.append(205)
+ message.repeated_sint64.append(206)
+ message.repeated_fixed32.append(207)
+ message.repeated_fixed64.append(208)
+ message.repeated_sfixed32.append(209)
+ message.repeated_sfixed64.append(210)
+ message.repeated_float.append(211)
+ message.repeated_double.append(212)
+ message.repeated_bool.append(True)
+ message.repeated_string.append('215')
+ message.repeated_bytes.append('216')
+
+ message.repeatedgroup.add().a = 217
+ message.repeated_nested_message.add().bb = 218
+ message.repeated_foreign_message.add().c = 219
+ message.repeated_import_message.add().d = 220
+
+ message.repeated_nested_enum.append(unittest_pb2.TestAllTypes.BAR)
+ message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAR)
+ message.repeated_import_enum.append(unittest_import_pb2.IMPORT_BAR)
+
+ message.repeated_string_piece.append('224')
+ message.repeated_cord.append('225')
+
+ # Add a second one of each field.
+ message.repeated_int32.append(301)
+ message.repeated_int64.append(302)
+ message.repeated_uint32.append(303)
+ message.repeated_uint64.append(304)
+ message.repeated_sint32.append(305)
+ message.repeated_sint64.append(306)
+ message.repeated_fixed32.append(307)
+ message.repeated_fixed64.append(308)
+ message.repeated_sfixed32.append(309)
+ message.repeated_sfixed64.append(310)
+ message.repeated_float.append(311)
+ message.repeated_double.append(312)
+ message.repeated_bool.append(False)
+ message.repeated_string.append('315')
+ message.repeated_bytes.append('316')
+
+ message.repeatedgroup.add().a = 317
+ message.repeated_nested_message.add().bb = 318
+ message.repeated_foreign_message.add().c = 319
+ message.repeated_import_message.add().d = 320
+
+ message.repeated_nested_enum.append(unittest_pb2.TestAllTypes.BAZ)
+ message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAZ)
+ message.repeated_import_enum.append(unittest_import_pb2.IMPORT_BAZ)
+
+ message.repeated_string_piece.append('324')
+ message.repeated_cord.append('325')
+
+ #
+ # Fields that have defaults.
+ #
+
+ message.default_int32 = 401
+ message.default_int64 = 402
+ message.default_uint32 = 403
+ message.default_uint64 = 404
+ message.default_sint32 = 405
+ message.default_sint64 = 406
+ message.default_fixed32 = 407
+ message.default_fixed64 = 408
+ message.default_sfixed32 = 409
+ message.default_sfixed64 = 410
+ message.default_float = 411
+ message.default_double = 412
+ message.default_bool = False
+ message.default_string = '415'
+ message.default_bytes = '416'
+
+ message.default_nested_enum = unittest_pb2.TestAllTypes.FOO
+ message.default_foreign_enum = unittest_pb2.FOREIGN_FOO
+ message.default_import_enum = unittest_import_pb2.IMPORT_FOO
+
+ message.default_string_piece = '424'
+ message.default_cord = '425'
+
+
+def SetAllExtensions(message):
+ """Sets every extension in the message to a unique value.
+
+ Args:
+ message: A unittest_pb2.TestAllExtensions instance.
+ """
+
+ extensions = message.Extensions
+ pb2 = unittest_pb2
+ import_pb2 = unittest_import_pb2
+
+ #
+ # Optional fields.
+ #
+
+ extensions[pb2.optional_int32_extension] = 101
+ extensions[pb2.optional_int64_extension] = 102
+ extensions[pb2.optional_uint32_extension] = 103
+ extensions[pb2.optional_uint64_extension] = 104
+ extensions[pb2.optional_sint32_extension] = 105
+ extensions[pb2.optional_sint64_extension] = 106
+ extensions[pb2.optional_fixed32_extension] = 107
+ extensions[pb2.optional_fixed64_extension] = 108
+ extensions[pb2.optional_sfixed32_extension] = 109
+ extensions[pb2.optional_sfixed64_extension] = 110
+ extensions[pb2.optional_float_extension] = 111
+ extensions[pb2.optional_double_extension] = 112
+ extensions[pb2.optional_bool_extension] = True
+ extensions[pb2.optional_string_extension] = '115'
+ extensions[pb2.optional_bytes_extension] = '116'
+
+ extensions[pb2.optionalgroup_extension].a = 117
+ extensions[pb2.optional_nested_message_extension].bb = 118
+ extensions[pb2.optional_foreign_message_extension].c = 119
+ extensions[pb2.optional_import_message_extension].d = 120
+
+ extensions[pb2.optional_nested_enum_extension] = pb2.TestAllTypes.BAZ
+ extensions[pb2.optional_nested_enum_extension] = pb2.TestAllTypes.BAZ
+ extensions[pb2.optional_foreign_enum_extension] = pb2.FOREIGN_BAZ
+ extensions[pb2.optional_import_enum_extension] = import_pb2.IMPORT_BAZ
+
+ extensions[pb2.optional_string_piece_extension] = '124'
+ extensions[pb2.optional_cord_extension] = '125'
+
+ #
+ # Repeated fields.
+ #
+
+ extensions[pb2.repeated_int32_extension].append(201)
+ extensions[pb2.repeated_int64_extension].append(202)
+ extensions[pb2.repeated_uint32_extension].append(203)
+ extensions[pb2.repeated_uint64_extension].append(204)
+ extensions[pb2.repeated_sint32_extension].append(205)
+ extensions[pb2.repeated_sint64_extension].append(206)
+ extensions[pb2.repeated_fixed32_extension].append(207)
+ extensions[pb2.repeated_fixed64_extension].append(208)
+ extensions[pb2.repeated_sfixed32_extension].append(209)
+ extensions[pb2.repeated_sfixed64_extension].append(210)
+ extensions[pb2.repeated_float_extension].append(211)
+ extensions[pb2.repeated_double_extension].append(212)
+ extensions[pb2.repeated_bool_extension].append(True)
+ extensions[pb2.repeated_string_extension].append('215')
+ extensions[pb2.repeated_bytes_extension].append('216')
+
+ extensions[pb2.repeatedgroup_extension].add().a = 217
+ extensions[pb2.repeated_nested_message_extension].add().bb = 218
+ extensions[pb2.repeated_foreign_message_extension].add().c = 219
+ extensions[pb2.repeated_import_message_extension].add().d = 220
+
+ extensions[pb2.repeated_nested_enum_extension].append(pb2.TestAllTypes.BAR)
+ extensions[pb2.repeated_foreign_enum_extension].append(pb2.FOREIGN_BAR)
+ extensions[pb2.repeated_import_enum_extension].append(import_pb2.IMPORT_BAR)
+
+ extensions[pb2.repeated_string_piece_extension].append('224')
+ extensions[pb2.repeated_cord_extension].append('225')
+
+ # Append a second one of each field.
+ extensions[pb2.repeated_int32_extension].append(301)
+ extensions[pb2.repeated_int64_extension].append(302)
+ extensions[pb2.repeated_uint32_extension].append(303)
+ extensions[pb2.repeated_uint64_extension].append(304)
+ extensions[pb2.repeated_sint32_extension].append(305)
+ extensions[pb2.repeated_sint64_extension].append(306)
+ extensions[pb2.repeated_fixed32_extension].append(307)
+ extensions[pb2.repeated_fixed64_extension].append(308)
+ extensions[pb2.repeated_sfixed32_extension].append(309)
+ extensions[pb2.repeated_sfixed64_extension].append(310)
+ extensions[pb2.repeated_float_extension].append(311)
+ extensions[pb2.repeated_double_extension].append(312)
+ extensions[pb2.repeated_bool_extension].append(False)
+ extensions[pb2.repeated_string_extension].append('315')
+ extensions[pb2.repeated_bytes_extension].append('316')
+
+ extensions[pb2.repeatedgroup_extension].add().a = 317
+ extensions[pb2.repeated_nested_message_extension].add().bb = 318
+ extensions[pb2.repeated_foreign_message_extension].add().c = 319
+ extensions[pb2.repeated_import_message_extension].add().d = 320
+
+ extensions[pb2.repeated_nested_enum_extension].append(pb2.TestAllTypes.BAZ)
+ extensions[pb2.repeated_foreign_enum_extension].append(pb2.FOREIGN_BAZ)
+ extensions[pb2.repeated_import_enum_extension].append(import_pb2.IMPORT_BAZ)
+
+ extensions[pb2.repeated_string_piece_extension].append('324')
+ extensions[pb2.repeated_cord_extension].append('325')
+
+ #
+ # Fields with defaults.
+ #
+
+ extensions[pb2.default_int32_extension] = 401
+ extensions[pb2.default_int64_extension] = 402
+ extensions[pb2.default_uint32_extension] = 403
+ extensions[pb2.default_uint64_extension] = 404
+ extensions[pb2.default_sint32_extension] = 405
+ extensions[pb2.default_sint64_extension] = 406
+ extensions[pb2.default_fixed32_extension] = 407
+ extensions[pb2.default_fixed64_extension] = 408
+ extensions[pb2.default_sfixed32_extension] = 409
+ extensions[pb2.default_sfixed64_extension] = 410
+ extensions[pb2.default_float_extension] = 411
+ extensions[pb2.default_double_extension] = 412
+ extensions[pb2.default_bool_extension] = False
+ extensions[pb2.default_string_extension] = '415'
+ extensions[pb2.default_bytes_extension] = '416'
+
+ extensions[pb2.default_nested_enum_extension] = pb2.TestAllTypes.FOO
+ extensions[pb2.default_foreign_enum_extension] = pb2.FOREIGN_FOO
+ extensions[pb2.default_import_enum_extension] = import_pb2.IMPORT_FOO
+
+ extensions[pb2.default_string_piece_extension] = '424'
+ extensions[pb2.default_cord_extension] = '425'
+
+
+def SetAllFieldsAndExtensions(message):
+ """Sets every field and extension in the message to a unique value.
+
+ Args:
+ message: A unittest_pb2.TestAllExtensions message.
+ """
+ message.my_int = 1
+ message.my_string = 'foo'
+ message.my_float = 1.0
+ message.Extensions[unittest_pb2.my_extension_int] = 23
+ message.Extensions[unittest_pb2.my_extension_string] = 'bar'
+
+
+def ExpectAllFieldsAndExtensionsInOrder(serialized):
+ """Ensures that serialized is the serialization we expect for a message
+ filled with SetAllFieldsAndExtensions(). (Specifically, ensures that the
+ serialization is in canonical, tag-number order).
+ """
+ my_extension_int = unittest_pb2.my_extension_int
+ my_extension_string = unittest_pb2.my_extension_string
+ expected_strings = []
+ message = unittest_pb2.TestFieldOrderings()
+ message.my_int = 1 # Field 1.
+ expected_strings.append(message.SerializeToString())
+ message.Clear()
+ message.Extensions[my_extension_int] = 23 # Field 5.
+ expected_strings.append(message.SerializeToString())
+ message.Clear()
+ message.my_string = 'foo' # Field 11.
+ expected_strings.append(message.SerializeToString())
+ message.Clear()
+ message.Extensions[my_extension_string] = 'bar' # Field 50.
+ expected_strings.append(message.SerializeToString())
+ message.Clear()
+ message.my_float = 1.0
+ expected_strings.append(message.SerializeToString())
+ message.Clear()
+ expected = ''.join(expected_strings)
+
+ if expected != serialized:
+ raise ValueError('Expected %r, found %r' % (expected, serialized))
+
+
+def ExpectAllFieldsSet(test_case, message):
+ """Check all fields for correct values have after Set*Fields() is called."""
+ test_case.assertTrue(message.HasField('optional_int32'))
+ test_case.assertTrue(message.HasField('optional_int64'))
+ test_case.assertTrue(message.HasField('optional_uint32'))
+ test_case.assertTrue(message.HasField('optional_uint64'))
+ test_case.assertTrue(message.HasField('optional_sint32'))
+ test_case.assertTrue(message.HasField('optional_sint64'))
+ test_case.assertTrue(message.HasField('optional_fixed32'))
+ test_case.assertTrue(message.HasField('optional_fixed64'))
+ test_case.assertTrue(message.HasField('optional_sfixed32'))
+ test_case.assertTrue(message.HasField('optional_sfixed64'))
+ test_case.assertTrue(message.HasField('optional_float'))
+ test_case.assertTrue(message.HasField('optional_double'))
+ test_case.assertTrue(message.HasField('optional_bool'))
+ test_case.assertTrue(message.HasField('optional_string'))
+ test_case.assertTrue(message.HasField('optional_bytes'))
+
+ test_case.assertTrue(message.HasField('optionalgroup'))
+ test_case.assertTrue(message.HasField('optional_nested_message'))
+ test_case.assertTrue(message.HasField('optional_foreign_message'))
+ test_case.assertTrue(message.HasField('optional_import_message'))
+
+ test_case.assertTrue(message.optionalgroup.HasField('a'))
+ test_case.assertTrue(message.optional_nested_message.HasField('bb'))
+ test_case.assertTrue(message.optional_foreign_message.HasField('c'))
+ test_case.assertTrue(message.optional_import_message.HasField('d'))
+
+ test_case.assertTrue(message.HasField('optional_nested_enum'))
+ test_case.assertTrue(message.HasField('optional_foreign_enum'))
+ test_case.assertTrue(message.HasField('optional_import_enum'))
+
+ test_case.assertTrue(message.HasField('optional_string_piece'))
+ test_case.assertTrue(message.HasField('optional_cord'))
+
+ test_case.assertEqual(101, message.optional_int32)
+ test_case.assertEqual(102, message.optional_int64)
+ test_case.assertEqual(103, message.optional_uint32)
+ test_case.assertEqual(104, message.optional_uint64)
+ test_case.assertEqual(105, message.optional_sint32)
+ test_case.assertEqual(106, message.optional_sint64)
+ test_case.assertEqual(107, message.optional_fixed32)
+ test_case.assertEqual(108, message.optional_fixed64)
+ test_case.assertEqual(109, message.optional_sfixed32)
+ test_case.assertEqual(110, message.optional_sfixed64)
+ test_case.assertEqual(111, message.optional_float)
+ test_case.assertEqual(112, message.optional_double)
+ test_case.assertEqual(True, message.optional_bool)
+ test_case.assertEqual('115', message.optional_string)
+ test_case.assertEqual('116', message.optional_bytes)
+
+ test_case.assertEqual(117, message.optionalgroup.a)
+ test_case.assertEqual(118, message.optional_nested_message.bb)
+ test_case.assertEqual(119, message.optional_foreign_message.c)
+ test_case.assertEqual(120, message.optional_import_message.d)
+
+ test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ,
+ message.optional_nested_enum)
+ test_case.assertEqual(unittest_pb2.FOREIGN_BAZ,
+ message.optional_foreign_enum)
+ test_case.assertEqual(unittest_import_pb2.IMPORT_BAZ,
+ message.optional_import_enum)
+
+ # -----------------------------------------------------------------
+
+ test_case.assertEqual(2, len(message.repeated_int32))
+ test_case.assertEqual(2, len(message.repeated_int64))
+ test_case.assertEqual(2, len(message.repeated_uint32))
+ test_case.assertEqual(2, len(message.repeated_uint64))
+ test_case.assertEqual(2, len(message.repeated_sint32))
+ test_case.assertEqual(2, len(message.repeated_sint64))
+ test_case.assertEqual(2, len(message.repeated_fixed32))
+ test_case.assertEqual(2, len(message.repeated_fixed64))
+ test_case.assertEqual(2, len(message.repeated_sfixed32))
+ test_case.assertEqual(2, len(message.repeated_sfixed64))
+ test_case.assertEqual(2, len(message.repeated_float))
+ test_case.assertEqual(2, len(message.repeated_double))
+ test_case.assertEqual(2, len(message.repeated_bool))
+ test_case.assertEqual(2, len(message.repeated_string))
+ test_case.assertEqual(2, len(message.repeated_bytes))
+
+ test_case.assertEqual(2, len(message.repeatedgroup))
+ test_case.assertEqual(2, len(message.repeated_nested_message))
+ test_case.assertEqual(2, len(message.repeated_foreign_message))
+ test_case.assertEqual(2, len(message.repeated_import_message))
+ test_case.assertEqual(2, len(message.repeated_nested_enum))
+ test_case.assertEqual(2, len(message.repeated_foreign_enum))
+ test_case.assertEqual(2, len(message.repeated_import_enum))
+
+ test_case.assertEqual(2, len(message.repeated_string_piece))
+ test_case.assertEqual(2, len(message.repeated_cord))
+
+ test_case.assertEqual(201, message.repeated_int32[0])
+ test_case.assertEqual(202, message.repeated_int64[0])
+ test_case.assertEqual(203, message.repeated_uint32[0])
+ test_case.assertEqual(204, message.repeated_uint64[0])
+ test_case.assertEqual(205, message.repeated_sint32[0])
+ test_case.assertEqual(206, message.repeated_sint64[0])
+ test_case.assertEqual(207, message.repeated_fixed32[0])
+ test_case.assertEqual(208, message.repeated_fixed64[0])
+ test_case.assertEqual(209, message.repeated_sfixed32[0])
+ test_case.assertEqual(210, message.repeated_sfixed64[0])
+ test_case.assertEqual(211, message.repeated_float[0])
+ test_case.assertEqual(212, message.repeated_double[0])
+ test_case.assertEqual(True, message.repeated_bool[0])
+ test_case.assertEqual('215', message.repeated_string[0])
+ test_case.assertEqual('216', message.repeated_bytes[0])
+
+ test_case.assertEqual(217, message.repeatedgroup[0].a)
+ test_case.assertEqual(218, message.repeated_nested_message[0].bb)
+ test_case.assertEqual(219, message.repeated_foreign_message[0].c)
+ test_case.assertEqual(220, message.repeated_import_message[0].d)
+
+ test_case.assertEqual(unittest_pb2.TestAllTypes.BAR,
+ message.repeated_nested_enum[0])
+ test_case.assertEqual(unittest_pb2.FOREIGN_BAR,
+ message.repeated_foreign_enum[0])
+ test_case.assertEqual(unittest_import_pb2.IMPORT_BAR,
+ message.repeated_import_enum[0])
+
+ test_case.assertEqual(301, message.repeated_int32[1])
+ test_case.assertEqual(302, message.repeated_int64[1])
+ test_case.assertEqual(303, message.repeated_uint32[1])
+ test_case.assertEqual(304, message.repeated_uint64[1])
+ test_case.assertEqual(305, message.repeated_sint32[1])
+ test_case.assertEqual(306, message.repeated_sint64[1])
+ test_case.assertEqual(307, message.repeated_fixed32[1])
+ test_case.assertEqual(308, message.repeated_fixed64[1])
+ test_case.assertEqual(309, message.repeated_sfixed32[1])
+ test_case.assertEqual(310, message.repeated_sfixed64[1])
+ test_case.assertEqual(311, message.repeated_float[1])
+ test_case.assertEqual(312, message.repeated_double[1])
+ test_case.assertEqual(False, message.repeated_bool[1])
+ test_case.assertEqual('315', message.repeated_string[1])
+ test_case.assertEqual('316', message.repeated_bytes[1])
+
+ test_case.assertEqual(317, message.repeatedgroup[1].a)
+ test_case.assertEqual(318, message.repeated_nested_message[1].bb)
+ test_case.assertEqual(319, message.repeated_foreign_message[1].c)
+ test_case.assertEqual(320, message.repeated_import_message[1].d)
+
+ test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ,
+ message.repeated_nested_enum[1])
+ test_case.assertEqual(unittest_pb2.FOREIGN_BAZ,
+ message.repeated_foreign_enum[1])
+ test_case.assertEqual(unittest_import_pb2.IMPORT_BAZ,
+ message.repeated_import_enum[1])
+
+ # -----------------------------------------------------------------
+
+ test_case.assertTrue(message.HasField('default_int32'))
+ test_case.assertTrue(message.HasField('default_int64'))
+ test_case.assertTrue(message.HasField('default_uint32'))
+ test_case.assertTrue(message.HasField('default_uint64'))
+ test_case.assertTrue(message.HasField('default_sint32'))
+ test_case.assertTrue(message.HasField('default_sint64'))
+ test_case.assertTrue(message.HasField('default_fixed32'))
+ test_case.assertTrue(message.HasField('default_fixed64'))
+ test_case.assertTrue(message.HasField('default_sfixed32'))
+ test_case.assertTrue(message.HasField('default_sfixed64'))
+ test_case.assertTrue(message.HasField('default_float'))
+ test_case.assertTrue(message.HasField('default_double'))
+ test_case.assertTrue(message.HasField('default_bool'))
+ test_case.assertTrue(message.HasField('default_string'))
+ test_case.assertTrue(message.HasField('default_bytes'))
+
+ test_case.assertTrue(message.HasField('default_nested_enum'))
+ test_case.assertTrue(message.HasField('default_foreign_enum'))
+ test_case.assertTrue(message.HasField('default_import_enum'))
+
+ test_case.assertEqual(401, message.default_int32)
+ test_case.assertEqual(402, message.default_int64)
+ test_case.assertEqual(403, message.default_uint32)
+ test_case.assertEqual(404, message.default_uint64)
+ test_case.assertEqual(405, message.default_sint32)
+ test_case.assertEqual(406, message.default_sint64)
+ test_case.assertEqual(407, message.default_fixed32)
+ test_case.assertEqual(408, message.default_fixed64)
+ test_case.assertEqual(409, message.default_sfixed32)
+ test_case.assertEqual(410, message.default_sfixed64)
+ test_case.assertEqual(411, message.default_float)
+ test_case.assertEqual(412, message.default_double)
+ test_case.assertEqual(False, message.default_bool)
+ test_case.assertEqual('415', message.default_string)
+ test_case.assertEqual('416', message.default_bytes)
+
+ test_case.assertEqual(unittest_pb2.TestAllTypes.FOO,
+ message.default_nested_enum)
+ test_case.assertEqual(unittest_pb2.FOREIGN_FOO,
+ message.default_foreign_enum)
+ test_case.assertEqual(unittest_import_pb2.IMPORT_FOO,
+ message.default_import_enum)
+
+def GoldenFile(filename):
+ """Finds the given golden file and returns a file object representing it."""
+
+ # Search up the directory tree looking for the C++ protobuf source code.
+ path = '.'
+ while os.path.exists(path):
+ if os.path.exists(os.path.join(path, 'src/google/protobuf')):
+ # Found it. Load the golden file from the testdata directory.
+ full_path = os.path.join(path, 'src/google/protobuf/testdata', filename)
+ return open(full_path, 'rb')
+ path = os.path.join(path, '..')
+
+ raise RuntimeError(
+ 'Could not find golden files. This test must be run from within the '
+ 'protobuf source package so that it can read test data files from the '
+ 'C++ source tree.')
+
+
+def SetAllPackedFields(message):
+ """Sets every field in the message to a unique value.
+
+ Args:
+ message: A unittest_pb2.TestPackedTypes instance.
+ """
+ message.packed_int32.extend([601, 701])
+ message.packed_int64.extend([602, 702])
+ message.packed_uint32.extend([603, 703])
+ message.packed_uint64.extend([604, 704])
+ message.packed_sint32.extend([605, 705])
+ message.packed_sint64.extend([606, 706])
+ message.packed_fixed32.extend([607, 707])
+ message.packed_fixed64.extend([608, 708])
+ message.packed_sfixed32.extend([609, 709])
+ message.packed_sfixed64.extend([610, 710])
+ message.packed_float.extend([611.0, 711.0])
+ message.packed_double.extend([612.0, 712.0])
+ message.packed_bool.extend([True, False])
+ message.packed_enum.extend([unittest_pb2.FOREIGN_BAR,
+ unittest_pb2.FOREIGN_BAZ])
+
+
+def SetAllPackedExtensions(message):
+ """Sets every extension in the message to a unique value.
+
+ Args:
+ message: A unittest_pb2.TestPackedExtensions instance.
+ """
+ extensions = message.Extensions
+ pb2 = unittest_pb2
+
+ extensions[pb2.packed_int32_extension].extend([601, 701])
+ extensions[pb2.packed_int64_extension].extend([602, 702])
+ extensions[pb2.packed_uint32_extension].extend([603, 703])
+ extensions[pb2.packed_uint64_extension].extend([604, 704])
+ extensions[pb2.packed_sint32_extension].extend([605, 705])
+ extensions[pb2.packed_sint64_extension].extend([606, 706])
+ extensions[pb2.packed_fixed32_extension].extend([607, 707])
+ extensions[pb2.packed_fixed64_extension].extend([608, 708])
+ extensions[pb2.packed_sfixed32_extension].extend([609, 709])
+ extensions[pb2.packed_sfixed64_extension].extend([610, 710])
+ extensions[pb2.packed_float_extension].extend([611.0, 711.0])
+ extensions[pb2.packed_double_extension].extend([612.0, 712.0])
+ extensions[pb2.packed_bool_extension].extend([True, False])
+ extensions[pb2.packed_enum_extension].extend([unittest_pb2.FOREIGN_BAR,
+ unittest_pb2.FOREIGN_BAZ])
+
+
+def SetAllUnpackedFields(message):
+ """Sets every field in the message to a unique value.
+
+ Args:
+ message: A unittest_pb2.TestUnpackedTypes instance.
+ """
+ message.unpacked_int32.extend([601, 701])
+ message.unpacked_int64.extend([602, 702])
+ message.unpacked_uint32.extend([603, 703])
+ message.unpacked_uint64.extend([604, 704])
+ message.unpacked_sint32.extend([605, 705])
+ message.unpacked_sint64.extend([606, 706])
+ message.unpacked_fixed32.extend([607, 707])
+ message.unpacked_fixed64.extend([608, 708])
+ message.unpacked_sfixed32.extend([609, 709])
+ message.unpacked_sfixed64.extend([610, 710])
+ message.unpacked_float.extend([611.0, 711.0])
+ message.unpacked_double.extend([612.0, 712.0])
+ message.unpacked_bool.extend([True, False])
+ message.unpacked_enum.extend([unittest_pb2.FOREIGN_BAR,
+ unittest_pb2.FOREIGN_BAZ])
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/text_format_test.py b/src/third_party/protobuf/python/google/protobuf/internal/text_format_test.py
new file mode 100755
index 0000000..73d97d1
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/text_format_test.py
@@ -0,0 +1,571 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Test for google.protobuf.text_format."""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import difflib
+import re
+
+import unittest
+from google.protobuf import text_format
+from google.protobuf.internal import test_util
+from google.protobuf import unittest_pb2
+from google.protobuf import unittest_mset_pb2
+
+
+class TextFormatTest(unittest.TestCase):
+ def ReadGolden(self, golden_filename):
+ f = test_util.GoldenFile(golden_filename)
+ golden_lines = f.readlines()
+ f.close()
+ return golden_lines
+
+ def CompareToGoldenFile(self, text, golden_filename):
+ golden_lines = self.ReadGolden(golden_filename)
+ self.CompareToGoldenLines(text, golden_lines)
+
+ def CompareToGoldenText(self, text, golden_text):
+ self.CompareToGoldenLines(text, golden_text.splitlines(1))
+
+ def CompareToGoldenLines(self, text, golden_lines):
+ actual_lines = text.splitlines(1)
+ self.assertEqual(golden_lines, actual_lines,
+ "Text doesn't match golden. Diff:\n" +
+ ''.join(difflib.ndiff(golden_lines, actual_lines)))
+
+ def testPrintAllFields(self):
+ message = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(message)
+ self.CompareToGoldenFile(
+ self.RemoveRedundantZeros(text_format.MessageToString(message)),
+ 'text_format_unittest_data.txt')
+
+ def testPrintAllExtensions(self):
+ message = unittest_pb2.TestAllExtensions()
+ test_util.SetAllExtensions(message)
+ self.CompareToGoldenFile(
+ self.RemoveRedundantZeros(text_format.MessageToString(message)),
+ 'text_format_unittest_extensions_data.txt')
+
+ def testPrintMessageSet(self):
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+ ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+ message.message_set.Extensions[ext1].i = 23
+ message.message_set.Extensions[ext2].str = 'foo'
+ self.CompareToGoldenText(text_format.MessageToString(message),
+ 'message_set {\n'
+ ' [protobuf_unittest.TestMessageSetExtension1] {\n'
+ ' i: 23\n'
+ ' }\n'
+ ' [protobuf_unittest.TestMessageSetExtension2] {\n'
+ ' str: \"foo\"\n'
+ ' }\n'
+ '}\n')
+
+ def testPrintExotic(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_int64.append(-9223372036854775808)
+ message.repeated_uint64.append(18446744073709551615)
+ message.repeated_double.append(123.456)
+ message.repeated_double.append(1.23e22)
+ message.repeated_double.append(1.23e-18)
+ message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+ message.repeated_string.append(u'\u00fc\ua71f')
+ self.CompareToGoldenText(
+ self.RemoveRedundantZeros(text_format.MessageToString(message)),
+ 'repeated_int64: -9223372036854775808\n'
+ 'repeated_uint64: 18446744073709551615\n'
+ 'repeated_double: 123.456\n'
+ 'repeated_double: 1.23e+22\n'
+ 'repeated_double: 1.23e-18\n'
+ 'repeated_string: '
+ '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
+ 'repeated_string: "\\303\\274\\352\\234\\237"\n')
+
+ def testPrintNestedMessageAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ msg = message.repeated_nested_message.add()
+ msg.bb = 42;
+ self.CompareToGoldenText(
+ text_format.MessageToString(message, as_one_line=True),
+ 'repeated_nested_message { bb: 42 }')
+
+ def testPrintRepeatedFieldsAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_int32.append(1)
+ message.repeated_int32.append(1)
+ message.repeated_int32.append(3)
+ message.repeated_string.append("Google")
+ message.repeated_string.append("Zurich")
+ self.CompareToGoldenText(
+ text_format.MessageToString(message, as_one_line=True),
+ 'repeated_int32: 1 repeated_int32: 1 repeated_int32: 3 '
+ 'repeated_string: "Google" repeated_string: "Zurich"')
+
+ def testPrintNestedNewLineInStringAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ message.optional_string = "a\nnew\nline"
+ self.CompareToGoldenText(
+ text_format.MessageToString(message, as_one_line=True),
+ 'optional_string: "a\\nnew\\nline"')
+
+ def testPrintMessageSetAsOneLine(self):
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+ ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+ message.message_set.Extensions[ext1].i = 23
+ message.message_set.Extensions[ext2].str = 'foo'
+ self.CompareToGoldenText(
+ text_format.MessageToString(message, as_one_line=True),
+ 'message_set {'
+ ' [protobuf_unittest.TestMessageSetExtension1] {'
+ ' i: 23'
+ ' }'
+ ' [protobuf_unittest.TestMessageSetExtension2] {'
+ ' str: \"foo\"'
+ ' }'
+ ' }')
+
+ def testPrintExoticAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_int64.append(-9223372036854775808)
+ message.repeated_uint64.append(18446744073709551615)
+ message.repeated_double.append(123.456)
+ message.repeated_double.append(1.23e22)
+ message.repeated_double.append(1.23e-18)
+ message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+ message.repeated_string.append(u'\u00fc\ua71f')
+ self.CompareToGoldenText(
+ self.RemoveRedundantZeros(
+ text_format.MessageToString(message, as_one_line=True)),
+ 'repeated_int64: -9223372036854775808'
+ ' repeated_uint64: 18446744073709551615'
+ ' repeated_double: 123.456'
+ ' repeated_double: 1.23e+22'
+ ' repeated_double: 1.23e-18'
+ ' repeated_string: '
+ '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""'
+ ' repeated_string: "\\303\\274\\352\\234\\237"')
+
+ def testRoundTripExoticAsOneLine(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_int64.append(-9223372036854775808)
+ message.repeated_uint64.append(18446744073709551615)
+ message.repeated_double.append(123.456)
+ message.repeated_double.append(1.23e22)
+ message.repeated_double.append(1.23e-18)
+ message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+ message.repeated_string.append(u'\u00fc\ua71f')
+
+ # Test as_utf8 = False.
+ wire_text = text_format.MessageToString(
+ message, as_one_line=True, as_utf8=False)
+ parsed_message = unittest_pb2.TestAllTypes()
+ text_format.Merge(wire_text, parsed_message)
+ self.assertEquals(message, parsed_message)
+
+ # Test as_utf8 = True.
+ wire_text = text_format.MessageToString(
+ message, as_one_line=True, as_utf8=True)
+ parsed_message = unittest_pb2.TestAllTypes()
+ text_format.Merge(wire_text, parsed_message)
+ self.assertEquals(message, parsed_message)
+
+ def testPrintRawUtf8String(self):
+ message = unittest_pb2.TestAllTypes()
+ message.repeated_string.append(u'\u00fc\ua71f')
+ text = text_format.MessageToString(message, as_utf8 = True)
+ self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n')
+ parsed_message = unittest_pb2.TestAllTypes()
+ text_format.Merge(text, parsed_message)
+ self.assertEquals(message, parsed_message)
+
+ def testMessageToString(self):
+ message = unittest_pb2.ForeignMessage()
+ message.c = 123
+ self.assertEqual('c: 123\n', str(message))
+
+ def RemoveRedundantZeros(self, text):
+ # Some platforms print 1e+5 as 1e+005. This is fine, but we need to remove
+ # these zeros in order to match the golden file.
+ text = text.replace('e+0','e+').replace('e+0','e+') \
+ .replace('e-0','e-').replace('e-0','e-')
+ # Floating point fields are printed with .0 suffix even if they are
+ # actualy integer numbers.
+ text = re.compile('\.0$', re.MULTILINE).sub('', text)
+ return text
+
+ def testMergeGolden(self):
+ golden_text = '\n'.join(self.ReadGolden('text_format_unittest_data.txt'))
+ parsed_message = unittest_pb2.TestAllTypes()
+ text_format.Merge(golden_text, parsed_message)
+
+ message = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(message)
+ self.assertEquals(message, parsed_message)
+
+ def testMergeGoldenExtensions(self):
+ golden_text = '\n'.join(self.ReadGolden(
+ 'text_format_unittest_extensions_data.txt'))
+ parsed_message = unittest_pb2.TestAllExtensions()
+ text_format.Merge(golden_text, parsed_message)
+
+ message = unittest_pb2.TestAllExtensions()
+ test_util.SetAllExtensions(message)
+ self.assertEquals(message, parsed_message)
+
+ def testMergeAllFields(self):
+ message = unittest_pb2.TestAllTypes()
+ test_util.SetAllFields(message)
+ ascii_text = text_format.MessageToString(message)
+
+ parsed_message = unittest_pb2.TestAllTypes()
+ text_format.Merge(ascii_text, parsed_message)
+ self.assertEqual(message, parsed_message)
+ test_util.ExpectAllFieldsSet(self, message)
+
+ def testMergeAllExtensions(self):
+ message = unittest_pb2.TestAllExtensions()
+ test_util.SetAllExtensions(message)
+ ascii_text = text_format.MessageToString(message)
+
+ parsed_message = unittest_pb2.TestAllExtensions()
+ text_format.Merge(ascii_text, parsed_message)
+ self.assertEqual(message, parsed_message)
+
+ def testMergeMessageSet(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ('repeated_uint64: 1\n'
+ 'repeated_uint64: 2\n')
+ text_format.Merge(text, message)
+ self.assertEqual(1, message.repeated_uint64[0])
+ self.assertEqual(2, message.repeated_uint64[1])
+
+ message = unittest_mset_pb2.TestMessageSetContainer()
+ text = ('message_set {\n'
+ ' [protobuf_unittest.TestMessageSetExtension1] {\n'
+ ' i: 23\n'
+ ' }\n'
+ ' [protobuf_unittest.TestMessageSetExtension2] {\n'
+ ' str: \"foo\"\n'
+ ' }\n'
+ '}\n')
+ text_format.Merge(text, message)
+ ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+ ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+ self.assertEquals(23, message.message_set.Extensions[ext1].i)
+ self.assertEquals('foo', message.message_set.Extensions[ext2].str)
+
+ def testMergeExotic(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ('repeated_int64: -9223372036854775808\n'
+ 'repeated_uint64: 18446744073709551615\n'
+ 'repeated_double: 123.456\n'
+ 'repeated_double: 1.23e+22\n'
+ 'repeated_double: 1.23e-18\n'
+ 'repeated_string: \n'
+ '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
+ 'repeated_string: "foo" \'corge\' "grault"\n'
+ 'repeated_string: "\\303\\274\\352\\234\\237"\n'
+ 'repeated_string: "\\xc3\\xbc"\n'
+ 'repeated_string: "\xc3\xbc"\n')
+ text_format.Merge(text, message)
+
+ self.assertEqual(-9223372036854775808, message.repeated_int64[0])
+ self.assertEqual(18446744073709551615, message.repeated_uint64[0])
+ self.assertEqual(123.456, message.repeated_double[0])
+ self.assertEqual(1.23e22, message.repeated_double[1])
+ self.assertEqual(1.23e-18, message.repeated_double[2])
+ self.assertEqual(
+ '\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0])
+ self.assertEqual('foocorgegrault', message.repeated_string[1])
+ self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2])
+ self.assertEqual(u'\u00fc', message.repeated_string[3])
+
+ def testMergeEmptyText(self):
+ message = unittest_pb2.TestAllTypes()
+ text = ''
+ text_format.Merge(text, message)
+ self.assertEquals(unittest_pb2.TestAllTypes(), message)
+
+ def testMergeInvalidUtf8(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'repeated_string: "\\xc3\\xc3"'
+ self.assertRaises(text_format.ParseError, text_format.Merge, text, message)
+
+ def testMergeSingleWord(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'foo'
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ ('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named '
+ '"foo".'),
+ text_format.Merge, text, message)
+
+ def testMergeUnknownField(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'unknown_field: 8\n'
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ ('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named '
+ '"unknown_field".'),
+ text_format.Merge, text, message)
+
+ def testMergeBadExtension(self):
+ message = unittest_pb2.TestAllExtensions()
+ text = '[unknown_extension]: 8\n'
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ '1:2 : Extension "unknown_extension" not registered.',
+ text_format.Merge, text, message)
+ message = unittest_pb2.TestAllTypes()
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ ('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have '
+ 'extensions.'),
+ text_format.Merge, text, message)
+
+ def testMergeGroupNotClosed(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'RepeatedGroup: <'
+ self.assertRaisesWithMessage(
+ text_format.ParseError, '1:16 : Expected ">".',
+ text_format.Merge, text, message)
+
+ text = 'RepeatedGroup: {'
+ self.assertRaisesWithMessage(
+ text_format.ParseError, '1:16 : Expected "}".',
+ text_format.Merge, text, message)
+
+ def testMergeEmptyGroup(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'OptionalGroup: {}'
+ text_format.Merge(text, message)
+ self.assertTrue(message.HasField('optionalgroup'))
+
+ message.Clear()
+
+ message = unittest_pb2.TestAllTypes()
+ text = 'OptionalGroup: <>'
+ text_format.Merge(text, message)
+ self.assertTrue(message.HasField('optionalgroup'))
+
+ def testMergeBadEnumValue(self):
+ message = unittest_pb2.TestAllTypes()
+ text = 'optional_nested_enum: BARR'
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
+ 'has no value named BARR.'),
+ text_format.Merge, text, message)
+
+ message = unittest_pb2.TestAllTypes()
+ text = 'optional_nested_enum: 100'
+ self.assertRaisesWithMessage(
+ text_format.ParseError,
+ ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
+ 'has no value with number 100.'),
+ text_format.Merge, text, message)
+
+ def assertRaisesWithMessage(self, e_class, e, func, *args, **kwargs):
+ """Same as assertRaises, but also compares the exception message."""
+ if hasattr(e_class, '__name__'):
+ exc_name = e_class.__name__
+ else:
+ exc_name = str(e_class)
+
+ try:
+ func(*args, **kwargs)
+ except e_class, expr:
+ if str(expr) != e:
+ msg = '%s raised, but with wrong message: "%s" instead of "%s"'
+ raise self.failureException(msg % (exc_name,
+ str(expr).encode('string_escape'),
+ e.encode('string_escape')))
+ return
+ else:
+ raise self.failureException('%s not raised' % exc_name)
+
+
+class TokenizerTest(unittest.TestCase):
+
+ def testSimpleTokenCases(self):
+ text = ('identifier1:"string1"\n \n\n'
+ 'identifier2 : \n \n123 \n identifier3 :\'string\'\n'
+ 'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n'
+ 'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n'
+ 'ID9: 22 ID10: -111111111111111111 ID11: -22\n'
+ 'ID12: 2222222222222222222 '
+ 'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ' )
+ tokenizer = text_format._Tokenizer(text)
+ methods = [(tokenizer.ConsumeIdentifier, 'identifier1'),
+ ':',
+ (tokenizer.ConsumeString, 'string1'),
+ (tokenizer.ConsumeIdentifier, 'identifier2'),
+ ':',
+ (tokenizer.ConsumeInt32, 123),
+ (tokenizer.ConsumeIdentifier, 'identifier3'),
+ ':',
+ (tokenizer.ConsumeString, 'string'),
+ (tokenizer.ConsumeIdentifier, 'identifiER_4'),
+ ':',
+ (tokenizer.ConsumeFloat, 1.1e+2),
+ (tokenizer.ConsumeIdentifier, 'ID5'),
+ ':',
+ (tokenizer.ConsumeFloat, -0.23),
+ (tokenizer.ConsumeIdentifier, 'ID6'),
+ ':',
+ (tokenizer.ConsumeString, 'aaaa\'bbbb'),
+ (tokenizer.ConsumeIdentifier, 'ID7'),
+ ':',
+ (tokenizer.ConsumeString, 'aa\"bb'),
+ (tokenizer.ConsumeIdentifier, 'ID8'),
+ ':',
+ '{',
+ (tokenizer.ConsumeIdentifier, 'A'),
+ ':',
+ (tokenizer.ConsumeFloat, text_format._INFINITY),
+ (tokenizer.ConsumeIdentifier, 'B'),
+ ':',
+ (tokenizer.ConsumeFloat, -text_format._INFINITY),
+ (tokenizer.ConsumeIdentifier, 'C'),
+ ':',
+ (tokenizer.ConsumeBool, True),
+ (tokenizer.ConsumeIdentifier, 'D'),
+ ':',
+ (tokenizer.ConsumeBool, False),
+ '}',
+ (tokenizer.ConsumeIdentifier, 'ID9'),
+ ':',
+ (tokenizer.ConsumeUint32, 22),
+ (tokenizer.ConsumeIdentifier, 'ID10'),
+ ':',
+ (tokenizer.ConsumeInt64, -111111111111111111),
+ (tokenizer.ConsumeIdentifier, 'ID11'),
+ ':',
+ (tokenizer.ConsumeInt32, -22),
+ (tokenizer.ConsumeIdentifier, 'ID12'),
+ ':',
+ (tokenizer.ConsumeUint64, 2222222222222222222),
+ (tokenizer.ConsumeIdentifier, 'false_bool'),
+ ':',
+ (tokenizer.ConsumeBool, False),
+ (tokenizer.ConsumeIdentifier, 'true_BOOL'),
+ ':',
+ (tokenizer.ConsumeBool, True),
+ (tokenizer.ConsumeIdentifier, 'true_bool1'),
+ ':',
+ (tokenizer.ConsumeBool, True),
+ (tokenizer.ConsumeIdentifier, 'false_BOOL1'),
+ ':',
+ (tokenizer.ConsumeBool, False)]
+
+ i = 0
+ while not tokenizer.AtEnd():
+ m = methods[i]
+ if type(m) == str:
+ token = tokenizer.token
+ self.assertEqual(token, m)
+ tokenizer.NextToken()
+ else:
+ self.assertEqual(m[1], m[0]())
+ i += 1
+
+ def testConsumeIntegers(self):
+ # This test only tests the failures in the integer parsing methods as well
+ # as the '0' special cases.
+ int64_max = (1 << 63) - 1
+ uint32_max = (1 << 32) - 1
+ text = '-1 %d %d' % (uint32_max + 1, int64_max + 1)
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint64)
+ self.assertEqual(-1, tokenizer.ConsumeInt32())
+
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt32)
+ self.assertEqual(uint32_max + 1, tokenizer.ConsumeInt64())
+
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt64)
+ self.assertEqual(int64_max + 1, tokenizer.ConsumeUint64())
+ self.assertTrue(tokenizer.AtEnd())
+
+ text = '-0 -0 0 0'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertEqual(0, tokenizer.ConsumeUint32())
+ self.assertEqual(0, tokenizer.ConsumeUint64())
+ self.assertEqual(0, tokenizer.ConsumeUint32())
+ self.assertEqual(0, tokenizer.ConsumeUint64())
+ self.assertTrue(tokenizer.AtEnd())
+
+ def testConsumeByteString(self):
+ text = '"string1\''
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ text = 'string1"'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ text = '\n"\\xt"'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ text = '\n"\\"'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ text = '\n"\\x"'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+ def testConsumeBool(self):
+ text = 'not-a-bool'
+ tokenizer = text_format._Tokenizer(text)
+ self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool)
+
+ def testInfNan(self):
+ # Make sure our infinity and NaN definitions are sound.
+ self.assertEquals(float, type(text_format._INFINITY))
+ self.assertEquals(float, type(text_format._NAN))
+ self.assertTrue(text_format._NAN != text_format._NAN)
+
+ inf_times_zero = text_format._INFINITY * 0
+ self.assertTrue(inf_times_zero != inf_times_zero)
+ self.assertTrue(text_format._INFINITY > 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/type_checkers.py b/src/third_party/protobuf/python/google/protobuf/internal/type_checkers.py
new file mode 100755
index 0000000..2b3cd4d
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/type_checkers.py
@@ -0,0 +1,286 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Provides type checking routines.
+
+This module defines type checking utilities in the forms of dictionaries:
+
+VALUE_CHECKERS: A dictionary of field types and a value validation object.
+TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing
+ function.
+TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization
+ function.
+FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their
+ coresponding wire types.
+TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
+ function.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+from google.protobuf.internal import decoder
+from google.protobuf.internal import encoder
+from google.protobuf.internal import wire_format
+from google.protobuf import descriptor
+
+_FieldDescriptor = descriptor.FieldDescriptor
+
+
+def GetTypeChecker(cpp_type, field_type):
+ """Returns a type checker for a message field of the specified types.
+
+ Args:
+ cpp_type: C++ type of the field (see descriptor.py).
+ field_type: Protocol message field type (see descriptor.py).
+
+ Returns:
+ An instance of TypeChecker which can be used to verify the types
+ of values assigned to a field of the specified type.
+ """
+ if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and
+ field_type == _FieldDescriptor.TYPE_STRING):
+ return UnicodeValueChecker()
+ return _VALUE_CHECKERS[cpp_type]
+
+
+# None of the typecheckers below make any attempt to guard against people
+# subclassing builtin types and doing weird things. We're not trying to
+# protect against malicious clients here, just people accidentally shooting
+# themselves in the foot in obvious ways.
+
+class TypeChecker(object):
+
+ """Type checker used to catch type errors as early as possible
+ when the client is setting scalar fields in protocol messages.
+ """
+
+ def __init__(self, *acceptable_types):
+ self._acceptable_types = acceptable_types
+
+ def CheckValue(self, proposed_value):
+ if not isinstance(proposed_value, self._acceptable_types):
+ message = ('%.1024r has type %s, but expected one of: %s' %
+ (proposed_value, type(proposed_value), self._acceptable_types))
+ raise TypeError(message)
+
+
+# IntValueChecker and its subclasses perform integer type-checks
+# and bounds-checks.
+class IntValueChecker(object):
+
+ """Checker used for integer fields. Performs type-check and range check."""
+
+ def CheckValue(self, proposed_value):
+ if not isinstance(proposed_value, (int, long)):
+ message = ('%.1024r has type %s, but expected one of: %s' %
+ (proposed_value, type(proposed_value), (int, long)))
+ raise TypeError(message)
+ if not self._MIN <= proposed_value <= self._MAX:
+ raise ValueError('Value out of range: %d' % proposed_value)
+
+
+class UnicodeValueChecker(object):
+
+ """Checker used for string fields."""
+
+ def CheckValue(self, proposed_value):
+ if not isinstance(proposed_value, (str, unicode)):
+ message = ('%.1024r has type %s, but expected one of: %s' %
+ (proposed_value, type(proposed_value), (str, unicode)))
+ raise TypeError(message)
+
+ # If the value is of type 'str' make sure that it is in 7-bit ASCII
+ # encoding.
+ if isinstance(proposed_value, str):
+ try:
+ unicode(proposed_value, 'ascii')
+ except UnicodeDecodeError:
+ raise ValueError('%.1024r has type str, but isn\'t in 7-bit ASCII '
+ 'encoding. Non-ASCII strings must be converted to '
+ 'unicode objects before being added.' %
+ (proposed_value))
+
+
+class Int32ValueChecker(IntValueChecker):
+ # We're sure to use ints instead of longs here since comparison may be more
+ # efficient.
+ _MIN = -2147483648
+ _MAX = 2147483647
+
+
+class Uint32ValueChecker(IntValueChecker):
+ _MIN = 0
+ _MAX = (1 << 32) - 1
+
+
+class Int64ValueChecker(IntValueChecker):
+ _MIN = -(1 << 63)
+ _MAX = (1 << 63) - 1
+
+
+class Uint64ValueChecker(IntValueChecker):
+ _MIN = 0
+ _MAX = (1 << 64) - 1
+
+
+# Type-checkers for all scalar CPPTYPEs.
+_VALUE_CHECKERS = {
+ _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(),
+ _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(),
+ _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
+ _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
+ _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker(
+ float, int, long),
+ _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker(
+ float, int, long),
+ _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int),
+ _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(),
+ _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str),
+ }
+
+
+# Map from field type to a function F, such that F(field_num, value)
+# gives the total byte size for a value of the given type. This
+# byte size includes tag information and any other additional space
+# associated with serializing "value".
+TYPE_TO_BYTE_SIZE_FN = {
+ _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize,
+ _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize,
+ _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize,
+ _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize,
+ _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize,
+ _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize,
+ _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize,
+ _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize,
+ _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize,
+ _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize,
+ _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize,
+ _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize,
+ _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize,
+ _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize,
+ _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize,
+ _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize,
+ _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize,
+ _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize
+ }
+
+
+# Maps from field types to encoder constructors.
+TYPE_TO_ENCODER = {
+ _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder,
+ _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder,
+ _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder,
+ _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder,
+ _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder,
+ _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder,
+ _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder,
+ _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder,
+ _FieldDescriptor.TYPE_STRING: encoder.StringEncoder,
+ _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder,
+ _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder,
+ _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder,
+ _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder,
+ _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder,
+ _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder,
+ _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder,
+ _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder,
+ _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder,
+ }
+
+
+# Maps from field types to sizer constructors.
+TYPE_TO_SIZER = {
+ _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer,
+ _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer,
+ _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer,
+ _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer,
+ _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer,
+ _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer,
+ _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer,
+ _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer,
+ _FieldDescriptor.TYPE_STRING: encoder.StringSizer,
+ _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer,
+ _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer,
+ _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer,
+ _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer,
+ _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer,
+ _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer,
+ _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer,
+ _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer,
+ _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer,
+ }
+
+
+# Maps from field type to a decoder constructor.
+TYPE_TO_DECODER = {
+ _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder,
+ _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder,
+ _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder,
+ _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder,
+ _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder,
+ _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder,
+ _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder,
+ _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder,
+ _FieldDescriptor.TYPE_STRING: decoder.StringDecoder,
+ _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder,
+ _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder,
+ _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder,
+ _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder,
+ _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder,
+ _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder,
+ _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder,
+ _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder,
+ _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder,
+ }
+
+# Maps from field type to expected wiretype.
+FIELD_TYPE_TO_WIRE_TYPE = {
+ _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64,
+ _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32,
+ _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64,
+ _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32,
+ _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_STRING:
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
+ _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP,
+ _FieldDescriptor.TYPE_MESSAGE:
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
+ _FieldDescriptor.TYPE_BYTES:
+ wire_format.WIRETYPE_LENGTH_DELIMITED,
+ _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32,
+ _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64,
+ _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT,
+ _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT,
+ }
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/wire_format.py b/src/third_party/protobuf/python/google/protobuf/internal/wire_format.py
new file mode 100755
index 0000000..c941fe1
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/wire_format.py
@@ -0,0 +1,268 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Constants and static functions to support protocol buffer wire format."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import struct
+from google.protobuf import descriptor
+from google.protobuf import message
+
+
+TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag.
+TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7
+
+# These numbers identify the wire type of a protocol buffer value.
+# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded
+# tag-and-type to store one of these WIRETYPE_* constants.
+# These values must match WireType enum in google/protobuf/wire_format.h.
+WIRETYPE_VARINT = 0
+WIRETYPE_FIXED64 = 1
+WIRETYPE_LENGTH_DELIMITED = 2
+WIRETYPE_START_GROUP = 3
+WIRETYPE_END_GROUP = 4
+WIRETYPE_FIXED32 = 5
+_WIRETYPE_MAX = 5
+
+
+# Bounds for various integer types.
+INT32_MAX = int((1 << 31) - 1)
+INT32_MIN = int(-(1 << 31))
+UINT32_MAX = (1 << 32) - 1
+
+INT64_MAX = (1 << 63) - 1
+INT64_MIN = -(1 << 63)
+UINT64_MAX = (1 << 64) - 1
+
+# "struct" format strings that will encode/decode the specified formats.
+FORMAT_UINT32_LITTLE_ENDIAN = '<I'
+FORMAT_UINT64_LITTLE_ENDIAN = '<Q'
+FORMAT_FLOAT_LITTLE_ENDIAN = '<f'
+FORMAT_DOUBLE_LITTLE_ENDIAN = '<d'
+
+
+# We'll have to provide alternate implementations of AppendLittleEndian*() on
+# any architectures where these checks fail.
+if struct.calcsize(FORMAT_UINT32_LITTLE_ENDIAN) != 4:
+ raise AssertionError('Format "I" is not a 32-bit number.')
+if struct.calcsize(FORMAT_UINT64_LITTLE_ENDIAN) != 8:
+ raise AssertionError('Format "Q" is not a 64-bit number.')
+
+
+def PackTag(field_number, wire_type):
+ """Returns an unsigned 32-bit integer that encodes the field number and
+ wire type information in standard protocol message wire format.
+
+ Args:
+ field_number: Expected to be an integer in the range [1, 1 << 29)
+ wire_type: One of the WIRETYPE_* constants.
+ """
+ if not 0 <= wire_type <= _WIRETYPE_MAX:
+ raise message.EncodeError('Unknown wire type: %d' % wire_type)
+ return (field_number << TAG_TYPE_BITS) | wire_type
+
+
+def UnpackTag(tag):
+ """The inverse of PackTag(). Given an unsigned 32-bit number,
+ returns a (field_number, wire_type) tuple.
+ """
+ return (tag >> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK)
+
+
+def ZigZagEncode(value):
+ """ZigZag Transform: Encodes signed integers so that they can be
+ effectively used with varint encoding. See wire_format.h for
+ more details.
+ """
+ if value >= 0:
+ return value << 1
+ return (value << 1) ^ (~0)
+
+
+def ZigZagDecode(value):
+ """Inverse of ZigZagEncode()."""
+ if not value & 0x1:
+ return value >> 1
+ return (value >> 1) ^ (~0)
+
+
+
+# The *ByteSize() functions below return the number of bytes required to
+# serialize "field number + type" information and then serialize the value.
+
+
+def Int32ByteSize(field_number, int32):
+ return Int64ByteSize(field_number, int32)
+
+
+def Int32ByteSizeNoTag(int32):
+ return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32)
+
+
+def Int64ByteSize(field_number, int64):
+ # Have to convert to uint before calling UInt64ByteSize().
+ return UInt64ByteSize(field_number, 0xffffffffffffffff & int64)
+
+
+def UInt32ByteSize(field_number, uint32):
+ return UInt64ByteSize(field_number, uint32)
+
+
+def UInt64ByteSize(field_number, uint64):
+ return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64)
+
+
+def SInt32ByteSize(field_number, int32):
+ return UInt32ByteSize(field_number, ZigZagEncode(int32))
+
+
+def SInt64ByteSize(field_number, int64):
+ return UInt64ByteSize(field_number, ZigZagEncode(int64))
+
+
+def Fixed32ByteSize(field_number, fixed32):
+ return TagByteSize(field_number) + 4
+
+
+def Fixed64ByteSize(field_number, fixed64):
+ return TagByteSize(field_number) + 8
+
+
+def SFixed32ByteSize(field_number, sfixed32):
+ return TagByteSize(field_number) + 4
+
+
+def SFixed64ByteSize(field_number, sfixed64):
+ return TagByteSize(field_number) + 8
+
+
+def FloatByteSize(field_number, flt):
+ return TagByteSize(field_number) + 4
+
+
+def DoubleByteSize(field_number, double):
+ return TagByteSize(field_number) + 8
+
+
+def BoolByteSize(field_number, b):
+ return TagByteSize(field_number) + 1
+
+
+def EnumByteSize(field_number, enum):
+ return UInt32ByteSize(field_number, enum)
+
+
+def StringByteSize(field_number, string):
+ return BytesByteSize(field_number, string.encode('utf-8'))
+
+
+def BytesByteSize(field_number, b):
+ return (TagByteSize(field_number)
+ + _VarUInt64ByteSizeNoTag(len(b))
+ + len(b))
+
+
+def GroupByteSize(field_number, message):
+ return (2 * TagByteSize(field_number) # START and END group.
+ + message.ByteSize())
+
+
+def MessageByteSize(field_number, message):
+ return (TagByteSize(field_number)
+ + _VarUInt64ByteSizeNoTag(message.ByteSize())
+ + message.ByteSize())
+
+
+def MessageSetItemByteSize(field_number, msg):
+ # First compute the sizes of the tags.
+ # There are 2 tags for the beginning and ending of the repeated group, that
+ # is field number 1, one with field number 2 (type_id) and one with field
+ # number 3 (message).
+ total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3))
+
+ # Add the number of bytes for type_id.
+ total_size += _VarUInt64ByteSizeNoTag(field_number)
+
+ message_size = msg.ByteSize()
+
+ # The number of bytes for encoding the length of the message.
+ total_size += _VarUInt64ByteSizeNoTag(message_size)
+
+ # The size of the message.
+ total_size += message_size
+ return total_size
+
+
+def TagByteSize(field_number):
+ """Returns the bytes required to serialize a tag with this field number."""
+ # Just pass in type 0, since the type won't affect the tag+type size.
+ return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0))
+
+
+# Private helper function for the *ByteSize() functions above.
+
+def _VarUInt64ByteSizeNoTag(uint64):
+ """Returns the number of bytes required to serialize a single varint
+ using boundary value comparisons. (unrolled loop optimization -WPierce)
+ uint64 must be unsigned.
+ """
+ if uint64 <= 0x7f: return 1
+ if uint64 <= 0x3fff: return 2
+ if uint64 <= 0x1fffff: return 3
+ if uint64 <= 0xfffffff: return 4
+ if uint64 <= 0x7ffffffff: return 5
+ if uint64 <= 0x3ffffffffff: return 6
+ if uint64 <= 0x1ffffffffffff: return 7
+ if uint64 <= 0xffffffffffffff: return 8
+ if uint64 <= 0x7fffffffffffffff: return 9
+ if uint64 > UINT64_MAX:
+ raise message.EncodeError('Value out of range: %d' % uint64)
+ return 10
+
+
+NON_PACKABLE_TYPES = (
+ descriptor.FieldDescriptor.TYPE_STRING,
+ descriptor.FieldDescriptor.TYPE_GROUP,
+ descriptor.FieldDescriptor.TYPE_MESSAGE,
+ descriptor.FieldDescriptor.TYPE_BYTES
+)
+
+
+def IsTypePackable(field_type):
+ """Return true iff packable = true is valid for fields of this type.
+
+ Args:
+ field_type: a FieldDescriptor::Type value.
+
+ Returns:
+ True iff fields of this type are packable.
+ """
+ return field_type not in NON_PACKABLE_TYPES
diff --git a/src/third_party/protobuf/python/google/protobuf/internal/wire_format_test.py b/src/third_party/protobuf/python/google/protobuf/internal/wire_format_test.py
new file mode 100755
index 0000000..7600778
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/internal/wire_format_test.py
@@ -0,0 +1,253 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Test for google.protobuf.internal.wire_format."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import unittest
+from google.protobuf import message
+from google.protobuf.internal import wire_format
+
+
+class WireFormatTest(unittest.TestCase):
+
+ def testPackTag(self):
+ field_number = 0xabc
+ tag_type = 2
+ self.assertEqual((field_number << 3) | tag_type,
+ wire_format.PackTag(field_number, tag_type))
+ PackTag = wire_format.PackTag
+ # Number too high.
+ self.assertRaises(message.EncodeError, PackTag, field_number, 6)
+ # Number too low.
+ self.assertRaises(message.EncodeError, PackTag, field_number, -1)
+
+ def testUnpackTag(self):
+ # Test field numbers that will require various varint sizes.
+ for expected_field_number in (1, 15, 16, 2047, 2048):
+ for expected_wire_type in range(6): # Highest-numbered wiretype is 5.
+ field_number, wire_type = wire_format.UnpackTag(
+ wire_format.PackTag(expected_field_number, expected_wire_type))
+ self.assertEqual(expected_field_number, field_number)
+ self.assertEqual(expected_wire_type, wire_type)
+
+ self.assertRaises(TypeError, wire_format.UnpackTag, None)
+ self.assertRaises(TypeError, wire_format.UnpackTag, 'abc')
+ self.assertRaises(TypeError, wire_format.UnpackTag, 0.0)
+ self.assertRaises(TypeError, wire_format.UnpackTag, object())
+
+ def testZigZagEncode(self):
+ Z = wire_format.ZigZagEncode
+ self.assertEqual(0, Z(0))
+ self.assertEqual(1, Z(-1))
+ self.assertEqual(2, Z(1))
+ self.assertEqual(3, Z(-2))
+ self.assertEqual(4, Z(2))
+ self.assertEqual(0xfffffffe, Z(0x7fffffff))
+ self.assertEqual(0xffffffff, Z(-0x80000000))
+ self.assertEqual(0xfffffffffffffffe, Z(0x7fffffffffffffff))
+ self.assertEqual(0xffffffffffffffff, Z(-0x8000000000000000))
+
+ self.assertRaises(TypeError, Z, None)
+ self.assertRaises(TypeError, Z, 'abcd')
+ self.assertRaises(TypeError, Z, 0.0)
+ self.assertRaises(TypeError, Z, object())
+
+ def testZigZagDecode(self):
+ Z = wire_format.ZigZagDecode
+ self.assertEqual(0, Z(0))
+ self.assertEqual(-1, Z(1))
+ self.assertEqual(1, Z(2))
+ self.assertEqual(-2, Z(3))
+ self.assertEqual(2, Z(4))
+ self.assertEqual(0x7fffffff, Z(0xfffffffe))
+ self.assertEqual(-0x80000000, Z(0xffffffff))
+ self.assertEqual(0x7fffffffffffffff, Z(0xfffffffffffffffe))
+ self.assertEqual(-0x8000000000000000, Z(0xffffffffffffffff))
+
+ self.assertRaises(TypeError, Z, None)
+ self.assertRaises(TypeError, Z, 'abcd')
+ self.assertRaises(TypeError, Z, 0.0)
+ self.assertRaises(TypeError, Z, object())
+
+ def NumericByteSizeTestHelper(self, byte_size_fn, value, expected_value_size):
+ # Use field numbers that cause various byte sizes for the tag information.
+ for field_number, tag_bytes in ((15, 1), (16, 2), (2047, 2), (2048, 3)):
+ expected_size = expected_value_size + tag_bytes
+ actual_size = byte_size_fn(field_number, value)
+ self.assertEqual(expected_size, actual_size,
+ 'byte_size_fn: %s, field_number: %d, value: %r\n'
+ 'Expected: %d, Actual: %d'% (
+ byte_size_fn, field_number, value, expected_size, actual_size))
+
+ def testByteSizeFunctions(self):
+ # Test all numeric *ByteSize() functions.
+ NUMERIC_ARGS = [
+ # Int32ByteSize().
+ [wire_format.Int32ByteSize, 0, 1],
+ [wire_format.Int32ByteSize, 127, 1],
+ [wire_format.Int32ByteSize, 128, 2],
+ [wire_format.Int32ByteSize, -1, 10],
+ # Int64ByteSize().
+ [wire_format.Int64ByteSize, 0, 1],
+ [wire_format.Int64ByteSize, 127, 1],
+ [wire_format.Int64ByteSize, 128, 2],
+ [wire_format.Int64ByteSize, -1, 10],
+ # UInt32ByteSize().
+ [wire_format.UInt32ByteSize, 0, 1],
+ [wire_format.UInt32ByteSize, 127, 1],
+ [wire_format.UInt32ByteSize, 128, 2],
+ [wire_format.UInt32ByteSize, wire_format.UINT32_MAX, 5],
+ # UInt64ByteSize().
+ [wire_format.UInt64ByteSize, 0, 1],
+ [wire_format.UInt64ByteSize, 127, 1],
+ [wire_format.UInt64ByteSize, 128, 2],
+ [wire_format.UInt64ByteSize, wire_format.UINT64_MAX, 10],
+ # SInt32ByteSize().
+ [wire_format.SInt32ByteSize, 0, 1],
+ [wire_format.SInt32ByteSize, -1, 1],
+ [wire_format.SInt32ByteSize, 1, 1],
+ [wire_format.SInt32ByteSize, -63, 1],
+ [wire_format.SInt32ByteSize, 63, 1],
+ [wire_format.SInt32ByteSize, -64, 1],
+ [wire_format.SInt32ByteSize, 64, 2],
+ # SInt64ByteSize().
+ [wire_format.SInt64ByteSize, 0, 1],
+ [wire_format.SInt64ByteSize, -1, 1],
+ [wire_format.SInt64ByteSize, 1, 1],
+ [wire_format.SInt64ByteSize, -63, 1],
+ [wire_format.SInt64ByteSize, 63, 1],
+ [wire_format.SInt64ByteSize, -64, 1],
+ [wire_format.SInt64ByteSize, 64, 2],
+ # Fixed32ByteSize().
+ [wire_format.Fixed32ByteSize, 0, 4],
+ [wire_format.Fixed32ByteSize, wire_format.UINT32_MAX, 4],
+ # Fixed64ByteSize().
+ [wire_format.Fixed64ByteSize, 0, 8],
+ [wire_format.Fixed64ByteSize, wire_format.UINT64_MAX, 8],
+ # SFixed32ByteSize().
+ [wire_format.SFixed32ByteSize, 0, 4],
+ [wire_format.SFixed32ByteSize, wire_format.INT32_MIN, 4],
+ [wire_format.SFixed32ByteSize, wire_format.INT32_MAX, 4],
+ # SFixed64ByteSize().
+ [wire_format.SFixed64ByteSize, 0, 8],
+ [wire_format.SFixed64ByteSize, wire_format.INT64_MIN, 8],
+ [wire_format.SFixed64ByteSize, wire_format.INT64_MAX, 8],
+ # FloatByteSize().
+ [wire_format.FloatByteSize, 0.0, 4],
+ [wire_format.FloatByteSize, 1000000000.0, 4],
+ [wire_format.FloatByteSize, -1000000000.0, 4],
+ # DoubleByteSize().
+ [wire_format.DoubleByteSize, 0.0, 8],
+ [wire_format.DoubleByteSize, 1000000000.0, 8],
+ [wire_format.DoubleByteSize, -1000000000.0, 8],
+ # BoolByteSize().
+ [wire_format.BoolByteSize, False, 1],
+ [wire_format.BoolByteSize, True, 1],
+ # EnumByteSize().
+ [wire_format.EnumByteSize, 0, 1],
+ [wire_format.EnumByteSize, 127, 1],
+ [wire_format.EnumByteSize, 128, 2],
+ [wire_format.EnumByteSize, wire_format.UINT32_MAX, 5],
+ ]
+ for args in NUMERIC_ARGS:
+ self.NumericByteSizeTestHelper(*args)
+
+ # Test strings and bytes.
+ for byte_size_fn in (wire_format.StringByteSize, wire_format.BytesByteSize):
+ # 1 byte for tag, 1 byte for length, 3 bytes for contents.
+ self.assertEqual(5, byte_size_fn(10, 'abc'))
+ # 2 bytes for tag, 1 byte for length, 3 bytes for contents.
+ self.assertEqual(6, byte_size_fn(16, 'abc'))
+ # 2 bytes for tag, 2 bytes for length, 128 bytes for contents.
+ self.assertEqual(132, byte_size_fn(16, 'a' * 128))
+
+ # Test UTF-8 string byte size calculation.
+ # 1 byte for tag, 1 byte for length, 8 bytes for content.
+ self.assertEqual(10, wire_format.StringByteSize(
+ 5, unicode('\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82', 'utf-8')))
+
+ class MockMessage(object):
+ def __init__(self, byte_size):
+ self.byte_size = byte_size
+ def ByteSize(self):
+ return self.byte_size
+
+ message_byte_size = 10
+ mock_message = MockMessage(byte_size=message_byte_size)
+ # Test groups.
+ # (2 * 1) bytes for begin and end tags, plus message_byte_size.
+ self.assertEqual(2 + message_byte_size,
+ wire_format.GroupByteSize(1, mock_message))
+ # (2 * 2) bytes for begin and end tags, plus message_byte_size.
+ self.assertEqual(4 + message_byte_size,
+ wire_format.GroupByteSize(16, mock_message))
+
+ # Test messages.
+ # 1 byte for tag, plus 1 byte for length, plus contents.
+ self.assertEqual(2 + mock_message.byte_size,
+ wire_format.MessageByteSize(1, mock_message))
+ # 2 bytes for tag, plus 1 byte for length, plus contents.
+ self.assertEqual(3 + mock_message.byte_size,
+ wire_format.MessageByteSize(16, mock_message))
+ # 2 bytes for tag, plus 2 bytes for length, plus contents.
+ mock_message.byte_size = 128
+ self.assertEqual(4 + mock_message.byte_size,
+ wire_format.MessageByteSize(16, mock_message))
+
+
+ # Test message set item byte size.
+ # 4 bytes for tags, plus 1 byte for length, plus 1 byte for type_id,
+ # plus contents.
+ mock_message.byte_size = 10
+ self.assertEqual(mock_message.byte_size + 6,
+ wire_format.MessageSetItemByteSize(1, mock_message))
+
+ # 4 bytes for tags, plus 2 bytes for length, plus 1 byte for type_id,
+ # plus contents.
+ mock_message.byte_size = 128
+ self.assertEqual(mock_message.byte_size + 7,
+ wire_format.MessageSetItemByteSize(1, mock_message))
+
+ # 4 bytes for tags, plus 2 bytes for length, plus 2 byte for type_id,
+ # plus contents.
+ self.assertEqual(mock_message.byte_size + 8,
+ wire_format.MessageSetItemByteSize(128, mock_message))
+
+ # Too-long varint.
+ self.assertRaises(message.EncodeError,
+ wire_format.UInt64ByteSize, 1, 1 << 128)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/third_party/protobuf/python/google/protobuf/message.py b/src/third_party/protobuf/python/google/protobuf/message.py
new file mode 100755
index 0000000..6f19f85
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/message.py
@@ -0,0 +1,268 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# TODO(robinson): We should just make these methods all "pure-virtual" and move
+# all implementation out, into reflection.py for now.
+
+
+"""Contains an abstract base class for protocol messages."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+class Error(Exception): pass
+class DecodeError(Error): pass
+class EncodeError(Error): pass
+
+
+class Message(object):
+
+ """Abstract base class for protocol messages.
+
+ Protocol message classes are almost always generated by the protocol
+ compiler. These generated types subclass Message and implement the methods
+ shown below.
+
+ TODO(robinson): Link to an HTML document here.
+
+ TODO(robinson): Document that instances of this class will also
+ have an Extensions attribute with __getitem__ and __setitem__.
+ Again, not sure how to best convey this.
+
+ TODO(robinson): Document that the class must also have a static
+ RegisterExtension(extension_field) method.
+ Not sure how to best express at this point.
+ """
+
+ # TODO(robinson): Document these fields and methods.
+
+ __slots__ = []
+
+ DESCRIPTOR = None
+
+ def __deepcopy__(self, memo=None):
+ clone = type(self)()
+ clone.MergeFrom(self)
+ return clone
+
+ def __eq__(self, other_msg):
+ raise NotImplementedError
+
+ def __ne__(self, other_msg):
+ # Can't just say self != other_msg, since that would infinitely recurse. :)
+ return not self == other_msg
+
+ def __hash__(self):
+ raise TypeError('unhashable object')
+
+ def __str__(self):
+ raise NotImplementedError
+
+ def __unicode__(self):
+ raise NotImplementedError
+
+ def MergeFrom(self, other_msg):
+ """Merges the contents of the specified message into current message.
+
+ This method merges the contents of the specified message into the current
+ message. Singular fields that are set in the specified message overwrite
+ the corresponding fields in the current message. Repeated fields are
+ appended. Singular sub-messages and groups are recursively merged.
+
+ Args:
+ other_msg: Message to merge into the current message.
+ """
+ raise NotImplementedError
+
+ def CopyFrom(self, other_msg):
+ """Copies the content of the specified message into the current message.
+
+ The method clears the current message and then merges the specified
+ message using MergeFrom.
+
+ Args:
+ other_msg: Message to copy into the current one.
+ """
+ if self is other_msg:
+ return
+ self.Clear()
+ self.MergeFrom(other_msg)
+
+ def Clear(self):
+ """Clears all data that was set in the message."""
+ raise NotImplementedError
+
+ def SetInParent(self):
+ """Mark this as present in the parent.
+
+ This normally happens automatically when you assign a field of a
+ sub-message, but sometimes you want to make the sub-message
+ present while keeping it empty. If you find yourself using this,
+ you may want to reconsider your design."""
+ raise NotImplementedError
+
+ def IsInitialized(self):
+ """Checks if the message is initialized.
+
+ Returns:
+ The method returns True if the message is initialized (i.e. all of its
+ required fields are set).
+ """
+ raise NotImplementedError
+
+ # TODO(robinson): MergeFromString() should probably return None and be
+ # implemented in terms of a helper that returns the # of bytes read. Our
+ # deserialization routines would use the helper when recursively
+ # deserializing, but the end user would almost always just want the no-return
+ # MergeFromString().
+
+ def MergeFromString(self, serialized):
+ """Merges serialized protocol buffer data into this message.
+
+ When we find a field in |serialized| that is already present
+ in this message:
+ - If it's a "repeated" field, we append to the end of our list.
+ - Else, if it's a scalar, we overwrite our field.
+ - Else, (it's a nonrepeated composite), we recursively merge
+ into the existing composite.
+
+ TODO(robinson): Document handling of unknown fields.
+
+ Args:
+ serialized: Any object that allows us to call buffer(serialized)
+ to access a string of bytes using the buffer interface.
+
+ TODO(robinson): When we switch to a helper, this will return None.
+
+ Returns:
+ The number of bytes read from |serialized|.
+ For non-group messages, this will always be len(serialized),
+ but for messages which are actually groups, this will
+ generally be less than len(serialized), since we must
+ stop when we reach an END_GROUP tag. Note that if
+ we *do* stop because of an END_GROUP tag, the number
+ of bytes returned does not include the bytes
+ for the END_GROUP tag information.
+ """
+ raise NotImplementedError
+
+ def ParseFromString(self, serialized):
+ """Like MergeFromString(), except we clear the object first."""
+ self.Clear()
+ self.MergeFromString(serialized)
+
+ def SerializeToString(self):
+ """Serializes the protocol message to a binary string.
+
+ Returns:
+ A binary string representation of the message if all of the required
+ fields in the message are set (i.e. the message is initialized).
+
+ Raises:
+ message.EncodeError if the message isn't initialized.
+ """
+ raise NotImplementedError
+
+ def SerializePartialToString(self):
+ """Serializes the protocol message to a binary string.
+
+ This method is similar to SerializeToString but doesn't check if the
+ message is initialized.
+
+ Returns:
+ A string representation of the partial message.
+ """
+ raise NotImplementedError
+
+ # TODO(robinson): Decide whether we like these better
+ # than auto-generated has_foo() and clear_foo() methods
+ # on the instances themselves. This way is less consistent
+ # with C++, but it makes reflection-type access easier and
+ # reduces the number of magically autogenerated things.
+ #
+ # TODO(robinson): Be sure to document (and test) exactly
+ # which field names are accepted here. Are we case-sensitive?
+ # What do we do with fields that share names with Python keywords
+ # like 'lambda' and 'yield'?
+ #
+ # nnorwitz says:
+ # """
+ # Typically (in python), an underscore is appended to names that are
+ # keywords. So they would become lambda_ or yield_.
+ # """
+ def ListFields(self):
+ """Returns a list of (FieldDescriptor, value) tuples for all
+ fields in the message which are not empty. A singular field is non-empty
+ if HasField() would return true, and a repeated field is non-empty if
+ it contains at least one element. The fields are ordered by field
+ number"""
+ raise NotImplementedError
+
+ def HasField(self, field_name):
+ """Checks if a certain field is set for the message. Note if the
+ field_name is not defined in the message descriptor, ValueError will be
+ raised."""
+ raise NotImplementedError
+
+ def ClearField(self, field_name):
+ raise NotImplementedError
+
+ def HasExtension(self, extension_handle):
+ raise NotImplementedError
+
+ def ClearExtension(self, extension_handle):
+ raise NotImplementedError
+
+ def ByteSize(self):
+ """Returns the serialized size of this message.
+ Recursively calls ByteSize() on all contained messages.
+ """
+ raise NotImplementedError
+
+ def _SetListener(self, message_listener):
+ """Internal method used by the protocol message implementation.
+ Clients should not call this directly.
+
+ Sets a listener that this message will call on certain state transitions.
+
+ The purpose of this method is to register back-edges from children to
+ parents at runtime, for the purpose of setting "has" bits and
+ byte-size-dirty bits in the parent and ancestor objects whenever a child or
+ descendant object is modified.
+
+ If the client wants to disconnect this Message from the object tree, she
+ explicitly sets callback to None.
+
+ If message_listener is None, unregisters any existing listener. Otherwise,
+ message_listener must implement the MessageListener interface in
+ internal/message_listener.py, and we discard any listener registered
+ via a previous _SetListener() call.
+ """
+ raise NotImplementedError
diff --git a/src/third_party/protobuf/python/google/protobuf/pyext/python-proto2.cc b/src/third_party/protobuf/python/google/protobuf/pyext/python-proto2.cc
new file mode 100644
index 0000000..181d7e9
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/pyext/python-proto2.cc
@@ -0,0 +1,1660 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: petar@google.com (Petar Petrov)
+
+#include <Python.h>
+#include <map>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/pyext/python_descriptor.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/pyext/python_protobuf.h>
+
+/* Is 64bit */
+#define IS_64BIT (SIZEOF_LONG == 8)
+
+#define FIELD_BELONGS_TO_MESSAGE(field_descriptor, message) \
+ ((message)->GetDescriptor() == (field_descriptor)->containing_type())
+
+#define FIELD_IS_REPEATED(field_descriptor) \
+ ((field_descriptor)->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED)
+
+#define GOOGLE_CHECK_GET_INT32(arg, value) \
+ int32 value; \
+ if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \
+ return NULL; \
+ }
+
+#define GOOGLE_CHECK_GET_INT64(arg, value) \
+ int64 value; \
+ if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \
+ return NULL; \
+ }
+
+#define GOOGLE_CHECK_GET_UINT32(arg, value) \
+ uint32 value; \
+ if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \
+ return NULL; \
+ }
+
+#define GOOGLE_CHECK_GET_UINT64(arg, value) \
+ uint64 value; \
+ if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \
+ return NULL; \
+ }
+
+#define GOOGLE_CHECK_GET_FLOAT(arg, value) \
+ float value; \
+ if (!CheckAndGetFloat(arg, &value)) { \
+ return NULL; \
+ } \
+
+#define GOOGLE_CHECK_GET_DOUBLE(arg, value) \
+ double value; \
+ if (!CheckAndGetDouble(arg, &value)) { \
+ return NULL; \
+ }
+
+#define GOOGLE_CHECK_GET_BOOL(arg, value) \
+ bool value; \
+ if (!CheckAndGetBool(arg, &value)) { \
+ return NULL; \
+ }
+
+#define C(str) const_cast<char*>(str)
+
+// --- Globals:
+
+// Constants used for integer type range checking.
+static PyObject* kPythonZero;
+static PyObject* kint32min_py;
+static PyObject* kint32max_py;
+static PyObject* kuint32max_py;
+static PyObject* kint64min_py;
+static PyObject* kint64max_py;
+static PyObject* kuint64max_py;
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+// --- Support Routines:
+
+static void AddConstants(PyObject* module) {
+ struct NameValue {
+ char* name;
+ int32 value;
+ } constants[] = {
+ // Labels:
+ {"LABEL_OPTIONAL", google::protobuf::FieldDescriptor::LABEL_OPTIONAL},
+ {"LABEL_REQUIRED", google::protobuf::FieldDescriptor::LABEL_REQUIRED},
+ {"LABEL_REPEATED", google::protobuf::FieldDescriptor::LABEL_REPEATED},
+ // CPP types:
+ {"CPPTYPE_MESSAGE", google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE},
+ // Field Types:
+ {"TYPE_MESSAGE", google::protobuf::FieldDescriptor::TYPE_MESSAGE},
+ // End.
+ {NULL, 0}
+ };
+
+ for (NameValue* constant = constants;
+ constant->name != NULL; constant++) {
+ PyModule_AddIntConstant(module, constant->name, constant->value);
+ }
+}
+
+// --- CMessage Custom Type:
+
+// ------ Type Forward Declaration:
+
+struct CMessage;
+struct CMessage_Type;
+
+static void CMessageDealloc(CMessage* self);
+static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds);
+static PyObject* CMessageStr(CMessage* self);
+
+static PyObject* CMessage_AddMessage(CMessage* self, PyObject* args);
+static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args);
+static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args);
+static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args);
+static PyObject* CMessage_Clear(CMessage* self, PyObject* args);
+static PyObject* CMessage_ClearField(CMessage* self, PyObject* args);
+static PyObject* CMessage_ClearFieldByDescriptor(
+ CMessage* self, PyObject* args);
+static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* args);
+static PyObject* CMessage_DebugString(CMessage* self, PyObject* args);
+static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args);
+static PyObject* CMessage_Equals(CMessage* self, PyObject* args);
+static PyObject* CMessage_FieldLength(CMessage* self, PyObject* args);
+static PyObject* CMessage_FindInitializationErrors(CMessage* self);
+static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args);
+static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args);
+static PyObject* CMessage_GetScalar(CMessage* self, PyObject* args);
+static PyObject* CMessage_HasField(CMessage* self, PyObject* args);
+static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* args);
+static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args);
+static PyObject* CMessage_ListFields(CMessage* self, PyObject* args);
+static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* args);
+static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* args);
+static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* args);
+static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* args);
+static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args);
+static PyObject* CMessage_SerializePartialToString(
+ CMessage* self, PyObject* args);
+static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args);
+static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args);
+static PyObject* CMessage_SwapRepeatedFieldElements(
+ CMessage* self, PyObject* args);
+
+// ------ Object Definition:
+
+typedef struct CMessage {
+ PyObject_HEAD
+
+ struct CMessage* parent; // NULL if wasn't created from another message.
+ CFieldDescriptor* parent_field;
+ const char* full_name;
+ google::protobuf::Message* message;
+ bool free_message;
+ bool read_only;
+} CMessage;
+
+// ------ Method Table:
+
+#define CMETHOD(name, args, doc) \
+ { C(#name), (PyCFunction)CMessage_##name, args, C(doc) }
+static PyMethodDef CMessageMethods[] = {
+ CMETHOD(AddMessage, METH_O,
+ "Adds a new message to a repeated composite field."),
+ CMETHOD(AddRepeatedScalar, METH_VARARGS,
+ "Adds a scalar to a repeated scalar field."),
+ CMETHOD(AssignRepeatedScalar, METH_VARARGS,
+ "Clears and sets the values of a repeated scalar field."),
+ CMETHOD(ByteSize, METH_NOARGS,
+ "Returns the size of the message in bytes."),
+ CMETHOD(Clear, METH_NOARGS,
+ "Clears a protocol message."),
+ CMETHOD(ClearField, METH_O,
+ "Clears a protocol message field by name."),
+ CMETHOD(ClearFieldByDescriptor, METH_O,
+ "Clears a protocol message field by descriptor."),
+ CMETHOD(CopyFrom, METH_O,
+ "Copies a protocol message into the current message."),
+ CMETHOD(DebugString, METH_NOARGS,
+ "Returns the debug string of a protocol message."),
+ CMETHOD(DeleteRepeatedField, METH_VARARGS,
+ "Deletes a slice of values from a repeated field."),
+ CMETHOD(Equals, METH_O,
+ "Checks if two protocol messages are equal (by identity)."),
+ CMETHOD(FieldLength, METH_O,
+ "Returns the number of elements in a repeated field."),
+ CMETHOD(FindInitializationErrors, METH_NOARGS,
+ "Returns the initialization errors of a message."),
+ CMETHOD(GetRepeatedMessage, METH_VARARGS,
+ "Returns a message from a repeated composite field."),
+ CMETHOD(GetRepeatedScalar, METH_VARARGS,
+ "Returns a scalar value from a repeated scalar field."),
+ CMETHOD(GetScalar, METH_O,
+ "Returns the scalar value of a field."),
+ CMETHOD(HasField, METH_O,
+ "Checks if a message field is set."),
+ CMETHOD(HasFieldByDescriptor, METH_O,
+ "Checks if a message field is set by given its descriptor"),
+ CMETHOD(IsInitialized, METH_NOARGS,
+ "Checks if all required fields of a protocol message are set."),
+ CMETHOD(ListFields, METH_NOARGS,
+ "Lists all set fields of a message."),
+ CMETHOD(MergeFrom, METH_O,
+ "Merges a protocol message into the current message."),
+ CMETHOD(MergeFromString, METH_O,
+ "Merges a serialized message into the current message."),
+ CMETHOD(MutableMessage, METH_O,
+ "Returns a new instance of a nested protocol message."),
+ CMETHOD(NewSubMessage, METH_O,
+ "Creates and returns a python message given the descriptor of a "
+ "composite field of the current message."),
+ CMETHOD(SetScalar, METH_VARARGS,
+ "Sets the value of a singular scalar field."),
+ CMETHOD(SerializePartialToString, METH_VARARGS,
+ "Serializes the message to a string, even if it isn't initialized."),
+ CMETHOD(SerializeToString, METH_NOARGS,
+ "Serializes the message to a string, only for initialized messages."),
+ CMETHOD(SetInParent, METH_NOARGS,
+ "Sets the has bit of the given field in its parent message."),
+ CMETHOD(SwapRepeatedFieldElements, METH_VARARGS,
+ "Swaps the elements in two positions in a repeated field."),
+ { NULL, NULL }
+};
+#undef CMETHOD
+
+static PyMemberDef CMessageMembers[] = {
+ { C("full_name"), T_STRING, offsetof(CMessage, full_name), 0, "Full name" },
+ { NULL }
+};
+
+// ------ Type Definition:
+
+// The definition for the type object that captures the type of CMessage
+// in Python.
+PyTypeObject CMessage_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ C("google3.net.google.protobuf.python.internal."
+ "_net_proto2___python."
+ "CMessage"), // tp_name
+ sizeof(CMessage), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)CMessageDealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ (reprfunc)CMessageStr, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ C("A ProtocolMessage"), // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ CMessageMethods, // tp_methods
+ CMessageMembers, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ (initproc)CMessageInit, // tp_init
+ PyType_GenericAlloc, // tp_alloc
+ PyType_GenericNew, // tp_new
+ PyObject_Del, // tp_free
+};
+
+// ------ Helper Functions:
+
+static void FormatTypeError(PyObject* arg, char* expected_types) {
+ PyObject* s = PyObject_Str(PyObject_Type(arg));
+ PyObject* repr = PyObject_Repr(PyObject_Type(arg));
+ PyErr_Format(PyExc_TypeError,
+ "%.100s has type %.100s, but expected one of: %s",
+ PyString_AS_STRING(repr),
+ PyString_AS_STRING(s),
+ expected_types);
+ Py_DECREF(s);
+ Py_DECREF(repr);
+}
+
+template <class T>
+static bool CheckAndGetInteger(
+ PyObject* arg, T* value, PyObject* min, PyObject* max) {
+ bool is_long = PyLong_Check(arg);
+ if (!PyInt_Check(arg) && !is_long) {
+ FormatTypeError(arg, "int, long");
+ return false;
+ }
+
+ if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) {
+ PyObject* s = PyObject_Str(arg);
+ PyErr_Format(PyExc_ValueError,
+ "Value out of range: %s",
+ PyString_AS_STRING(s));
+ Py_DECREF(s);
+ return false;
+ }
+ if (is_long) {
+ if (min == kPythonZero) {
+ *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg));
+ } else {
+ *value = static_cast<T>(PyLong_AsLongLong(arg));
+ }
+ } else {
+ *value = static_cast<T>(PyInt_AsLong(arg));
+ }
+ return true;
+}
+
+static bool CheckAndGetDouble(PyObject* arg, double* value) {
+ if (!PyInt_Check(arg) && !PyLong_Check(arg) &&
+ !PyFloat_Check(arg)) {
+ FormatTypeError(arg, "int, long, float");
+ return false;
+ }
+ *value = PyFloat_AsDouble(arg);
+ return true;
+}
+
+static bool CheckAndGetFloat(PyObject* arg, float* value) {
+ double double_value;
+ if (!CheckAndGetDouble(arg, &double_value)) {
+ return false;
+ }
+ *value = static_cast<float>(double_value);
+ return true;
+}
+
+static bool CheckAndGetBool(PyObject* arg, bool* value) {
+ if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) {
+ FormatTypeError(arg, "int, long, bool");
+ return false;
+ }
+ *value = static_cast<bool>(PyInt_AsLong(arg));
+ return true;
+}
+
+google::protobuf::DynamicMessageFactory* global_message_factory = NULL;
+static const google::protobuf::Message* CreateMessage(const char* message_type) {
+ string message_name(message_type);
+ const google::protobuf::Descriptor* descriptor =
+ GetDescriptorPool()->FindMessageTypeByName(message_name);
+ if (descriptor == NULL) {
+ return NULL;
+ }
+ return global_message_factory->GetPrototype(descriptor);
+}
+
+static bool CheckAndSetString(
+ PyObject* arg, google::protobuf::Message* message,
+ const google::protobuf::FieldDescriptor* descriptor,
+ const google::protobuf::Reflection* reflection,
+ bool append,
+ int index) {
+ GOOGLE_DCHECK(descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING ||
+ descriptor->type() == google::protobuf::FieldDescriptor::TYPE_BYTES);
+ if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {
+ if (!PyString_Check(arg) && !PyUnicode_Check(arg)) {
+ FormatTypeError(arg, "str, unicode");
+ return false;
+ }
+
+ if (PyString_Check(arg)) {
+ PyObject* unicode = PyUnicode_FromEncodedObject(arg, "ascii", NULL);
+ if (unicode == NULL) {
+ PyObject* repr = PyObject_Repr(arg);
+ PyErr_Format(PyExc_ValueError,
+ "%s has type str, but isn't in 7-bit ASCII "
+ "encoding. Non-ASCII strings must be converted to "
+ "unicode objects before being added.",
+ PyString_AS_STRING(repr));
+ Py_DECREF(repr);
+ return false;
+ } else {
+ Py_DECREF(unicode);
+ }
+ }
+ } else if (!PyString_Check(arg)) {
+ FormatTypeError(arg, "str");
+ return false;
+ }
+
+ PyObject* encoded_string = NULL;
+ if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {
+ if (PyString_Check(arg)) {
+ encoded_string = PyString_AsEncodedObject(arg, "utf-8", NULL);
+ } else {
+ encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL);
+ }
+ } else {
+ // In this case field type is "bytes".
+ encoded_string = arg;
+ Py_INCREF(encoded_string);
+ }
+
+ if (encoded_string == NULL) {
+ return false;
+ }
+
+ char* value;
+ Py_ssize_t value_len;
+ if (PyString_AsStringAndSize(encoded_string, &value, &value_len) < 0) {
+ Py_DECREF(encoded_string);
+ return false;
+ }
+
+ string value_string(value, value_len);
+ if (append) {
+ reflection->AddString(message, descriptor, value_string);
+ } else if (index < 0) {
+ reflection->SetString(message, descriptor, value_string);
+ } else {
+ reflection->SetRepeatedString(message, descriptor, index, value_string);
+ }
+ Py_DECREF(encoded_string);
+ return true;
+}
+
+static PyObject* ToStringObject(
+ const google::protobuf::FieldDescriptor* descriptor, string value) {
+ if (descriptor->type() != google::protobuf::FieldDescriptor::TYPE_STRING) {
+ return PyString_FromStringAndSize(value.c_str(), value.length());
+ }
+
+ PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL);
+ // If the string can't be decoded in UTF-8, just return a string object that
+ // contains the raw bytes. This can't happen if the value was assigned using
+ // the members of the Python message object, but can happen if the values were
+ // parsed from the wire (binary).
+ if (result == NULL) {
+ PyErr_Clear();
+ result = PyString_FromStringAndSize(value.c_str(), value.length());
+ }
+ return result;
+}
+
+static void AssureWritable(CMessage* self) {
+ if (self == NULL ||
+ self->parent == NULL ||
+ self->parent_field == NULL) {
+ return;
+ }
+
+ if (!self->read_only) {
+ return;
+ }
+
+ AssureWritable(self->parent);
+
+ google::protobuf::Message* message = self->parent->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ self->message = reflection->MutableMessage(
+ message, self->parent_field->descriptor, global_message_factory);
+ self->read_only = false;
+ self->parent = NULL;
+ self->parent_field = NULL;
+}
+
+static PyObject* InternalGetScalar(
+ google::protobuf::Message* message,
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(
+ PyExc_KeyError, "Field does not belong to message!");
+ return NULL;
+ }
+
+ PyObject* result = NULL;
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ int32 value = reflection->GetInt32(*message, field_descriptor);
+ result = PyInt_FromLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ int64 value = reflection->GetInt64(*message, field_descriptor);
+#if IS_64BIT
+ result = PyInt_FromLong(value);
+#else
+ result = PyLong_FromLongLong(value);
+#endif
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ uint32 value = reflection->GetUInt32(*message, field_descriptor);
+#if IS_64BIT
+ result = PyInt_FromLong(value);
+#else
+ result = PyLong_FromLongLong(value);
+#endif
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ uint64 value = reflection->GetUInt64(*message, field_descriptor);
+#if IS_64BIT
+ if (value <= static_cast<uint64>(kint64max)) {
+ result = PyInt_FromLong(static_cast<uint64>(value));
+ }
+#else
+ if (value <= static_cast<uint32>(kint32max)) {
+ result = PyInt_FromLong(static_cast<uint32>(value));
+ }
+#endif
+ else { // NOLINT
+ result = PyLong_FromUnsignedLongLong(value);
+ }
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = reflection->GetFloat(*message, field_descriptor);
+ result = PyFloat_FromDouble(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = reflection->GetDouble(*message, field_descriptor);
+ result = PyFloat_FromDouble(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ bool value = reflection->GetBool(*message, field_descriptor);
+ result = PyBool_FromLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ string value = reflection->GetString(*message, field_descriptor);
+ result = ToStringObject(field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ if (!message->GetReflection()->HasField(*message, field_descriptor)) {
+ // Look for the value in the unknown fields.
+ google::protobuf::UnknownFieldSet* unknown_field_set =
+ message->GetReflection()->MutableUnknownFields(message);
+ for (int i = 0; i < unknown_field_set->field_count(); ++i) {
+ if (unknown_field_set->field(i).number() ==
+ field_descriptor->number()) {
+ result = PyInt_FromLong(unknown_field_set->field(i).varint());
+ break;
+ }
+ }
+ }
+
+ if (result == NULL) {
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ message->GetReflection()->GetEnum(*message, field_descriptor);
+ result = PyInt_FromLong(enum_value->number());
+ }
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Getting a value from a field of unknown type %d",
+ field_descriptor->cpp_type());
+ }
+
+ return result;
+}
+
+static PyObject* InternalSetScalar(
+ google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* arg) {
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(
+ PyExc_KeyError, "Field does not belong to message!");
+ return NULL;
+ }
+
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ GOOGLE_CHECK_GET_INT32(arg, value);
+ reflection->SetInt32(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ GOOGLE_CHECK_GET_INT64(arg, value);
+ reflection->SetInt64(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ GOOGLE_CHECK_GET_UINT32(arg, value);
+ reflection->SetUInt32(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ GOOGLE_CHECK_GET_UINT64(arg, value);
+ reflection->SetUInt64(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ GOOGLE_CHECK_GET_FLOAT(arg, value);
+ reflection->SetFloat(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ GOOGLE_CHECK_GET_DOUBLE(arg, value);
+ reflection->SetDouble(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ GOOGLE_CHECK_GET_BOOL(arg, value);
+ reflection->SetBool(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ if (!CheckAndSetString(
+ arg, message, field_descriptor, reflection, false, -1)) {
+ return NULL;
+ }
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ GOOGLE_CHECK_GET_INT32(arg, value);
+ const google::protobuf::EnumDescriptor* enum_descriptor =
+ field_descriptor->enum_type();
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ enum_descriptor->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ reflection->SetEnum(message, field_descriptor, enum_value);
+ } else {
+ bool added = false;
+ // Add the value to the unknown fields.
+ google::protobuf::UnknownFieldSet* unknown_field_set =
+ message->GetReflection()->MutableUnknownFields(message);
+ for (int i = 0; i < unknown_field_set->field_count(); ++i) {
+ if (unknown_field_set->field(i).number() ==
+ field_descriptor->number()) {
+ unknown_field_set->mutable_field(i)->set_varint(value);
+ added = true;
+ break;
+ }
+ }
+
+ if (!added) {
+ unknown_field_set->AddVarint(field_descriptor->number(), value);
+ }
+ reflection->ClearField(message, field_descriptor);
+ }
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Setting value to a field of unknown type %d",
+ field_descriptor->cpp_type());
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject* InternalAddRepeatedScalar(
+ google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* arg) {
+
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(
+ PyExc_KeyError, "Field does not belong to message!");
+ return NULL;
+ }
+
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ GOOGLE_CHECK_GET_INT32(arg, value);
+ reflection->AddInt32(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ GOOGLE_CHECK_GET_INT64(arg, value);
+ reflection->AddInt64(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ GOOGLE_CHECK_GET_UINT32(arg, value);
+ reflection->AddUInt32(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ GOOGLE_CHECK_GET_UINT64(arg, value);
+ reflection->AddUInt64(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ GOOGLE_CHECK_GET_FLOAT(arg, value);
+ reflection->AddFloat(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ GOOGLE_CHECK_GET_DOUBLE(arg, value);
+ reflection->AddDouble(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ GOOGLE_CHECK_GET_BOOL(arg, value);
+ reflection->AddBool(message, field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ if (!CheckAndSetString(
+ arg, message, field_descriptor, reflection, true, -1)) {
+ return NULL;
+ }
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ GOOGLE_CHECK_GET_INT32(arg, value);
+ const google::protobuf::EnumDescriptor* enum_descriptor =
+ field_descriptor->enum_type();
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ enum_descriptor->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ reflection->AddEnum(message, field_descriptor, enum_value);
+ } else {
+ PyObject* s = PyObject_Str(arg);
+ PyErr_Format(PyExc_ValueError, "Unknown enum value: %s",
+ PyString_AS_STRING(s));
+ Py_DECREF(s);
+ return NULL;
+ }
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError, "Adding value to a field of unknown type %d",
+ field_descriptor->cpp_type());
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyObject* InternalGetRepeatedScalar(
+ CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor,
+ int index) {
+ google::protobuf::Message* message = cmessage->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+
+ int field_size = reflection->FieldSize(*message, field_descriptor);
+ if (index < 0) {
+ index = field_size + index;
+ }
+ if (index < 0 || index >= field_size) {
+ PyErr_Format(PyExc_IndexError,
+ "list assignment index (%d) out of range", index);
+ return NULL;
+ }
+
+ PyObject* result = NULL;
+ switch (field_descriptor->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+ int32 value = reflection->GetRepeatedInt32(
+ *message, field_descriptor, index);
+ result = PyInt_FromLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+ int64 value = reflection->GetRepeatedInt64(
+ *message, field_descriptor, index);
+ result = PyLong_FromLongLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+ uint32 value = reflection->GetRepeatedUInt32(
+ *message, field_descriptor, index);
+ result = PyLong_FromLongLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+ uint64 value = reflection->GetRepeatedUInt64(
+ *message, field_descriptor, index);
+ result = PyLong_FromUnsignedLongLong(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = reflection->GetRepeatedFloat(
+ *message, field_descriptor, index);
+ result = PyFloat_FromDouble(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = reflection->GetRepeatedDouble(
+ *message, field_descriptor, index);
+ result = PyFloat_FromDouble(value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+ bool value = reflection->GetRepeatedBool(
+ *message, field_descriptor, index);
+ result = PyBool_FromLong(value ? 1 : 0);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+ const google::protobuf::EnumValueDescriptor* enum_value =
+ message->GetReflection()->GetRepeatedEnum(
+ *message, field_descriptor, index);
+ result = PyInt_FromLong(enum_value->number());
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+ string value = reflection->GetRepeatedString(
+ *message, field_descriptor, index);
+ result = ToStringObject(field_descriptor, value);
+ break;
+ }
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+ CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+ const google::protobuf::Message& msg = reflection->GetRepeatedMessage(
+ *message, field_descriptor, index);
+ py_cmsg->parent = cmessage;
+ py_cmsg->full_name = field_descriptor->full_name().c_str();
+ py_cmsg->message = const_cast<google::protobuf::Message*>(&msg);
+ py_cmsg->free_message = false;
+ py_cmsg->read_only = false;
+ result = reinterpret_cast<PyObject*>(py_cmsg);
+ break;
+ }
+ default:
+ PyErr_Format(
+ PyExc_SystemError,
+ "Getting value from a repeated field of unknown type %d",
+ field_descriptor->cpp_type());
+ }
+
+ return result;
+}
+
+static PyObject* InternalGetRepeatedScalarSlice(
+ CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor,
+ PyObject* slice) {
+ Py_ssize_t from;
+ Py_ssize_t to;
+ Py_ssize_t step;
+ Py_ssize_t length;
+ bool return_list = false;
+ google::protobuf::Message* message = cmessage->message;
+
+ if (PyInt_Check(slice)) {
+ from = to = PyInt_AsLong(slice);
+ } else if (PyLong_Check(slice)) {
+ from = to = PyLong_AsLong(slice);
+ } else if (PySlice_Check(slice)) {
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ length = reflection->FieldSize(*message, field_descriptor);
+ PySlice_GetIndices(
+ reinterpret_cast<PySliceObject*>(slice), length, &from, &to, &step);
+ return_list = true;
+ } else {
+ PyErr_SetString(PyExc_TypeError, "list indices must be integers");
+ return NULL;
+ }
+
+ if (!return_list) {
+ return InternalGetRepeatedScalar(cmessage, field_descriptor, from);
+ }
+
+ PyObject* list = PyList_New(0);
+ if (list == NULL) {
+ return NULL;
+ }
+
+ if (from <= to) {
+ if (step < 0) return list;
+ for (Py_ssize_t index = from; index < to; index += step) {
+ if (index < 0 || index >= length) break;
+ PyObject* s = InternalGetRepeatedScalar(
+ cmessage, field_descriptor, index);
+ PyList_Append(list, s);
+ Py_DECREF(s);
+ }
+ } else {
+ if (step > 0) return list;
+ for (Py_ssize_t index = from; index > to; index += step) {
+ if (index < 0 || index >= length) break;
+ PyObject* s = InternalGetRepeatedScalar(
+ cmessage, field_descriptor, index);
+ PyList_Append(list, s);
+ Py_DECREF(s);
+ }
+ }
+ return list;
+}
+
+// ------ C Constructor/Destructor:
+
+static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds) {
+ self->message = NULL;
+ return 0;
+}
+
+static void CMessageDealloc(CMessage* self) {
+ if (self->free_message) {
+ if (self->read_only) {
+ PyErr_WriteUnraisable(reinterpret_cast<PyObject*>(self));
+ }
+ delete self->message;
+ }
+ self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+// ------ Methods:
+
+static PyObject* CMessage_Clear(CMessage* self, PyObject* args) {
+ AssureWritable(self);
+ self->message->Clear();
+ Py_RETURN_NONE;
+}
+
+static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args) {
+ return PyBool_FromLong(self->message->IsInitialized() ? 1 : 0);
+}
+
+static PyObject* CMessage_HasField(CMessage* self, PyObject* arg) {
+ char* field_name;
+ if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) {
+ return NULL;
+ }
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ descriptor->FindFieldByName(field_name);
+ if (field_descriptor == NULL) {
+ PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name);
+ return NULL;
+ }
+
+ bool has_field =
+ message->GetReflection()->HasField(*message, field_descriptor);
+ return PyBool_FromLong(has_field ? 1 : 0);
+}
+
+static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* arg) {
+ CFieldDescriptor* cfield_descriptor = NULL;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
+ &CFieldDescriptor_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
+ return NULL;
+ }
+ cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ cfield_descriptor->descriptor;
+
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(PyExc_KeyError,
+ "Field does not belong to message!");
+ return NULL;
+ }
+
+ if (FIELD_IS_REPEATED(field_descriptor)) {
+ PyErr_SetString(PyExc_KeyError,
+ "Field is repeated. A singular method is required.");
+ return NULL;
+ }
+
+ bool has_field =
+ message->GetReflection()->HasField(*message, field_descriptor);
+ return PyBool_FromLong(has_field ? 1 : 0);
+}
+
+static PyObject* CMessage_ClearFieldByDescriptor(
+ CMessage* self, PyObject* arg) {
+ CFieldDescriptor* cfield_descriptor = NULL;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
+ &CFieldDescriptor_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
+ return NULL;
+ }
+ cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ cfield_descriptor->descriptor;
+
+ if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+ PyErr_SetString(PyExc_KeyError,
+ "Field does not belong to message!");
+ return NULL;
+ }
+
+ message->GetReflection()->ClearField(message, field_descriptor);
+ Py_RETURN_NONE;
+}
+
+static PyObject* CMessage_ClearField(CMessage* self, PyObject* arg) {
+ char* field_name;
+ if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) {
+ return NULL;
+ }
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ descriptor->FindFieldByName(field_name);
+ if (field_descriptor == NULL) {
+ PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name);
+ return NULL;
+ }
+
+ message->GetReflection()->ClearField(message, field_descriptor);
+ Py_RETURN_NONE;
+}
+
+static PyObject* CMessage_GetScalar(CMessage* self, PyObject* arg) {
+ CFieldDescriptor* cdescriptor = NULL;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
+ &CFieldDescriptor_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
+ return NULL;
+ }
+ cdescriptor = reinterpret_cast<CFieldDescriptor*>(arg);
+
+ google::protobuf::Message* message = self->message;
+ return InternalGetScalar(message, cdescriptor->descriptor);
+}
+
+static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args) {
+ CFieldDescriptor* cfield_descriptor;
+ PyObject* slice;
+ if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedScalar"),
+ &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
+ return NULL;
+ }
+
+ return InternalGetRepeatedScalarSlice(
+ self, cfield_descriptor->descriptor, slice);
+}
+
+static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args) {
+ CFieldDescriptor* cfield_descriptor;
+ PyObject* slice;
+ if (!PyArg_ParseTuple(args, C("O!O:AssignRepeatedScalar"),
+ &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
+ return NULL;
+ }
+
+ AssureWritable(self);
+ google::protobuf::Message* message = self->message;
+ message->GetReflection()->ClearField(message, cfield_descriptor->descriptor);
+
+ PyObject* iter = PyObject_GetIter(slice);
+ PyObject* next;
+ while ((next = PyIter_Next(iter)) != NULL) {
+ if (InternalAddRepeatedScalar(
+ message, cfield_descriptor->descriptor, next) == NULL) {
+ Py_DECREF(next);
+ Py_DECREF(iter);
+ return NULL;
+ }
+ Py_DECREF(next);
+ }
+ Py_DECREF(iter);
+ Py_RETURN_NONE;
+}
+
+static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args) {
+ CFieldDescriptor* cfield_descriptor;
+ PyObject* slice;
+ if (!PyArg_ParseTuple(args, C("O!O:DeleteRepeatedField"),
+ &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
+ return NULL;
+ }
+ AssureWritable(self);
+
+ Py_ssize_t length, from, to, step, slice_length;
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ cfield_descriptor->descriptor;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ int min, max;
+ length = reflection->FieldSize(*message, field_descriptor);
+
+ if (PyInt_Check(slice) || PyLong_Check(slice)) {
+ from = to = PyLong_AsLong(slice);
+ if (from < 0) {
+ from = to = length + from;
+ }
+ step = 1;
+ min = max = from;
+
+ // Range check.
+ if (from < 0 || from >= length) {
+ PyErr_Format(PyExc_IndexError, "list assignment index out of range");
+ return NULL;
+ }
+ } else if (PySlice_Check(slice)) {
+ from = to = step = slice_length = 0;
+ PySlice_GetIndicesEx(
+ reinterpret_cast<PySliceObject*>(slice),
+ length, &from, &to, &step, &slice_length);
+ if (from < to) {
+ min = from;
+ max = to - 1;
+ } else {
+ min = to + 1;
+ max = from;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "list indices must be integers");
+ return NULL;
+ }
+
+ Py_ssize_t i = from;
+ std::vector<bool> to_delete(length, false);
+ while (i >= min && i <= max) {
+ to_delete[i] = true;
+ i += step;
+ }
+
+ to = 0;
+ for (i = 0; i < length; ++i) {
+ if (!to_delete[i]) {
+ if (i != to) {
+ reflection->SwapElements(message, field_descriptor, i, to);
+ }
+ ++to;
+ }
+ }
+
+ while (i > to) {
+ reflection->RemoveLast(message, field_descriptor);
+ --i;
+ }
+
+ Py_RETURN_NONE;
+}
+
+
+static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args) {
+ CFieldDescriptor* cfield_descriptor;
+ PyObject* arg;
+ if (!PyArg_ParseTuple(args, C("O!O:SetScalar"),
+ &CFieldDescriptor_Type, &cfield_descriptor, &arg)) {
+ return NULL;
+ }
+ AssureWritable(self);
+
+ return InternalSetScalar(self->message, cfield_descriptor->descriptor, arg);
+}
+
+static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args) {
+ CFieldDescriptor* cfield_descriptor;
+ PyObject* value;
+ if (!PyArg_ParseTuple(args, C("O!O:AddRepeatedScalar"),
+ &CFieldDescriptor_Type, &cfield_descriptor, &value)) {
+ return NULL;
+ }
+ AssureWritable(self);
+
+ return InternalAddRepeatedScalar(
+ self->message, cfield_descriptor->descriptor, value);
+}
+
+static PyObject* CMessage_FieldLength(CMessage* self, PyObject* arg) {
+ CFieldDescriptor* cfield_descriptor;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
+ &CFieldDescriptor_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
+ return NULL;
+ }
+ cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
+
+ google::protobuf::Message* message = self->message;
+ int length = message->GetReflection()->FieldSize(
+ *message, cfield_descriptor->descriptor);
+ return PyInt_FromLong(length);
+}
+
+static PyObject* CMessage_DebugString(CMessage* self, PyObject* args) {
+ return PyString_FromString(self->message->DebugString().c_str());
+}
+
+static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args) {
+ int size = self->message->ByteSize();
+ if (size <= 0) {
+ return PyString_FromString("");
+ }
+ PyObject* result = PyString_FromStringAndSize(NULL, size);
+ if (result == NULL) {
+ return NULL;
+ }
+ char* buffer = PyString_AS_STRING(result);
+ self->message->SerializeWithCachedSizesToArray(
+ reinterpret_cast<uint8*>(buffer));
+ return result;
+}
+
+static PyObject* CMessage_SerializePartialToString(
+ CMessage* self, PyObject* args) {
+ string contents;
+ self->message->SerializePartialToString(&contents);
+ return PyString_FromStringAndSize(contents.c_str(), contents.size());
+}
+
+static PyObject* CMessageStr(CMessage* self) {
+ char str[1024];
+ str[sizeof(str) - 1] = 0;
+ snprintf(str, sizeof(str) - 1, "CMessage: <%p>", self->message);
+ return PyString_FromString(str);
+}
+
+static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* arg) {
+ CMessage* other_message;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a message");
+ return NULL;
+ }
+
+ other_message = reinterpret_cast<CMessage*>(arg);
+ if (other_message->message->GetDescriptor() !=
+ self->message->GetDescriptor()) {
+ PyErr_Format(PyExc_TypeError,
+ "Tried to merge from a message with a different type. "
+ "to: %s, from: %s",
+ self->message->GetDescriptor()->full_name().c_str(),
+ other_message->message->GetDescriptor()->full_name().c_str());
+ return NULL;
+ }
+ AssureWritable(self);
+
+ self->message->MergeFrom(*other_message->message);
+ Py_RETURN_NONE;
+}
+
+static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* arg) {
+ CMessage* other_message;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a message");
+ return NULL;
+ }
+
+ other_message = reinterpret_cast<CMessage*>(arg);
+ if (other_message->message->GetDescriptor() !=
+ self->message->GetDescriptor()) {
+ PyErr_Format(PyExc_TypeError,
+ "Tried to copy from a message with a different type. "
+ "to: %s, from: %s",
+ self->message->GetDescriptor()->full_name().c_str(),
+ other_message->message->GetDescriptor()->full_name().c_str());
+ return NULL;
+ }
+
+ AssureWritable(self);
+
+ self->message->CopyFrom(*other_message->message);
+ Py_RETURN_NONE;
+}
+
+static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* arg) {
+ const void* data;
+ Py_ssize_t data_length;
+ if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
+ return NULL;
+ }
+
+ AssureWritable(self);
+ google::protobuf::io::CodedInputStream input(
+ reinterpret_cast<const uint8*>(data), data_length);
+ bool success = self->message->MergePartialFromCodedStream(&input);
+ if (success) {
+ return PyInt_FromLong(self->message->ByteSize());
+ } else {
+ return PyInt_FromLong(-1);
+ }
+}
+
+static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args) {
+ return PyLong_FromLong(self->message->ByteSize());
+}
+
+static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args) {
+ AssureWritable(self);
+ Py_RETURN_NONE;
+}
+
+static PyObject* CMessage_SwapRepeatedFieldElements(
+ CMessage* self, PyObject* args) {
+ CFieldDescriptor* cfield_descriptor;
+ int index1, index2;
+ if (!PyArg_ParseTuple(args, C("O!ii:SwapRepeatedFieldElements"),
+ &CFieldDescriptor_Type, &cfield_descriptor,
+ &index1, &index2)) {
+ return NULL;
+ }
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+
+ reflection->SwapElements(
+ message, cfield_descriptor->descriptor, index1, index2);
+ Py_RETURN_NONE;
+}
+
+static PyObject* CMessage_AddMessage(CMessage* self, PyObject* arg) {
+ CFieldDescriptor* cfield_descriptor;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
+ &CFieldDescriptor_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
+ return NULL;
+ }
+ cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
+ AssureWritable(self);
+
+ CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ google::protobuf::Message* sub_message =
+ reflection->AddMessage(message, cfield_descriptor->descriptor);
+
+ py_cmsg->parent = NULL;
+ py_cmsg->full_name = sub_message->GetDescriptor()->full_name().c_str();
+ py_cmsg->message = sub_message;
+ py_cmsg->free_message = false;
+ py_cmsg->read_only = false;
+ return reinterpret_cast<PyObject*>(py_cmsg);
+}
+
+static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args) {
+ CFieldDescriptor* cfield_descriptor;
+ PyObject* slice;
+ if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedMessage"),
+ &CFieldDescriptor_Type, &cfield_descriptor, &slice)) {
+ return NULL;
+ }
+
+ return InternalGetRepeatedScalarSlice(
+ self, cfield_descriptor->descriptor, slice);
+}
+
+static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* arg) {
+ CFieldDescriptor* cfield_descriptor;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
+ &CFieldDescriptor_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
+ return NULL;
+ }
+ cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
+
+ CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ const google::protobuf::Message& sub_message =
+ reflection->GetMessage(*message, cfield_descriptor->descriptor,
+ global_message_factory);
+
+ py_cmsg->full_name = sub_message.GetDescriptor()->full_name().c_str();
+ py_cmsg->parent = self;
+ py_cmsg->parent_field = cfield_descriptor;
+ py_cmsg->message = const_cast<google::protobuf::Message*>(&sub_message);
+ py_cmsg->free_message = false;
+ py_cmsg->read_only = true;
+ return reinterpret_cast<PyObject*>(py_cmsg);
+}
+
+static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* arg) {
+ CFieldDescriptor* cfield_descriptor;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg),
+ &CFieldDescriptor_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a field descriptor");
+ return NULL;
+ }
+ cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg);
+ AssureWritable(self);
+
+ CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ google::protobuf::Message* mutable_message =
+ reflection->MutableMessage(message, cfield_descriptor->descriptor,
+ global_message_factory);
+
+ py_cmsg->full_name = mutable_message->GetDescriptor()->full_name().c_str();
+ py_cmsg->message = mutable_message;
+ py_cmsg->free_message = false;
+ py_cmsg->read_only = false;
+ return reinterpret_cast<PyObject*>(py_cmsg);
+}
+
+static PyObject* CMessage_Equals(CMessage* self, PyObject* arg) {
+ CMessage* other_message;
+ if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Must be a message");
+ return NULL;
+ }
+ other_message = reinterpret_cast<CMessage*>(arg);
+
+ if (other_message->message == self->message) {
+ return PyBool_FromLong(1);
+ }
+
+ if (other_message->message->GetDescriptor() !=
+ self->message->GetDescriptor()) {
+ return PyBool_FromLong(0);
+ }
+
+ return PyBool_FromLong(1);
+}
+
+static PyObject* CMessage_ListFields(CMessage* self, PyObject* args) {
+ google::protobuf::Message* message = self->message;
+ const google::protobuf::Reflection* reflection = message->GetReflection();
+ vector<const google::protobuf::FieldDescriptor*> fields;
+ reflection->ListFields(*message, &fields);
+
+ PyObject* list = PyList_New(fields.size());
+ if (list == NULL) {
+ return NULL;
+ }
+
+ for (unsigned int i = 0; i < fields.size(); ++i) {
+ bool is_extension = fields[i]->is_extension();
+ PyObject* t = PyTuple_New(2);
+ if (t == NULL) {
+ Py_DECREF(list);
+ return NULL;
+ }
+
+ PyObject* is_extension_object = PyBool_FromLong(is_extension ? 1 : 0);
+
+ PyObject* field_name;
+ const string* s;
+ if (is_extension) {
+ s = &fields[i]->full_name();
+ } else {
+ s = &fields[i]->name();
+ }
+ field_name = PyString_FromStringAndSize(s->c_str(), s->length());
+ if (field_name == NULL) {
+ Py_DECREF(list);
+ Py_DECREF(t);
+ return NULL;
+ }
+
+ PyTuple_SET_ITEM(t, 0, is_extension_object);
+ PyTuple_SET_ITEM(t, 1, field_name);
+ PyList_SET_ITEM(list, i, t);
+ }
+
+ return list;
+}
+
+static PyObject* CMessage_FindInitializationErrors(CMessage* self) {
+ google::protobuf::Message* message = self->message;
+ vector<string> errors;
+ message->FindInitializationErrors(&errors);
+
+ PyObject* error_list = PyList_New(errors.size());
+ if (error_list == NULL) {
+ return NULL;
+ }
+ for (unsigned int i = 0; i < errors.size(); ++i) {
+ const string& error = errors[i];
+ PyObject* error_string = PyString_FromStringAndSize(
+ error.c_str(), error.length());
+ if (error_string == NULL) {
+ Py_DECREF(error_list);
+ return NULL;
+ }
+ PyList_SET_ITEM(error_list, i, error_string);
+ }
+ return error_list;
+}
+
+// ------ Python Constructor:
+
+PyObject* Python_NewCMessage(PyObject* ignored, PyObject* arg) {
+ const char* message_type = PyString_AsString(arg);
+ if (message_type == NULL) {
+ return NULL;
+ }
+
+ const google::protobuf::Message* message = CreateMessage(message_type);
+ if (message == NULL) {
+ PyErr_Format(PyExc_TypeError, "Couldn't create message of type %s!",
+ message_type);
+ return NULL;
+ }
+
+ CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type);
+ if (py_cmsg == NULL) {
+ return NULL;
+ }
+ py_cmsg->message = message->New();
+ py_cmsg->free_message = true;
+ py_cmsg->full_name = message->GetDescriptor()->full_name().c_str();
+ py_cmsg->read_only = false;
+ py_cmsg->parent = NULL;
+ py_cmsg->parent_field = NULL;
+ return reinterpret_cast<PyObject*>(py_cmsg);
+}
+
+// --- Module Functions (exposed to Python):
+
+PyMethodDef methods[] = {
+ { C("NewCMessage"), (PyCFunction)Python_NewCMessage,
+ METH_O,
+ C("Creates a new C++ protocol message, given its full name.") },
+ { C("NewCDescriptorPool"), (PyCFunction)Python_NewCDescriptorPool,
+ METH_NOARGS,
+ C("Creates a new C++ descriptor pool.") },
+ { C("BuildFile"), (PyCFunction)Python_BuildFile,
+ METH_O,
+ C("Registers a new protocol buffer file in the global C++ descriptor "
+ "pool.") },
+ {NULL}
+};
+
+// --- Exposing the C proto living inside Python proto to C code:
+
+extern const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg);
+extern Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg);
+
+static const google::protobuf::Message* GetCProtoInsidePyProtoImpl(PyObject* msg) {
+ PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg");
+ if (c_msg_obj == NULL) {
+ PyErr_Clear();
+ return NULL;
+ }
+ Py_DECREF(c_msg_obj);
+ if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) {
+ return NULL;
+ }
+ CMessage* c_msg = reinterpret_cast<CMessage*>(c_msg_obj);
+ return c_msg->message;
+}
+
+static google::protobuf::Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
+ PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg");
+ if (c_msg_obj == NULL) {
+ PyErr_Clear();
+ return NULL;
+ }
+ Py_DECREF(c_msg_obj);
+ if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) {
+ return NULL;
+ }
+ CMessage* c_msg = reinterpret_cast<CMessage*>(c_msg_obj);
+ AssureWritable(c_msg);
+ return c_msg->message;
+}
+
+// --- Module Init Function:
+
+static const char module_docstring[] =
+"python-proto2 is a module that can be used to enhance proto2 Python API\n"
+"performance.\n"
+"\n"
+"It provides access to the protocol buffers C++ reflection API that\n"
+"implements the basic protocol buffer functions.";
+
+extern "C" {
+ void init_net_proto2___python() {
+ // Initialize constants.
+ kPythonZero = PyInt_FromLong(0);
+ kint32min_py = PyInt_FromLong(kint32min);
+ kint32max_py = PyInt_FromLong(kint32max);
+ kuint32max_py = PyLong_FromLongLong(kuint32max);
+ kint64min_py = PyLong_FromLongLong(kint64min);
+ kint64max_py = PyLong_FromLongLong(kint64max);
+ kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max);
+
+ global_message_factory = new DynamicMessageFactory(GetDescriptorPool());
+ global_message_factory->SetDelegateToGeneratedFactory(true);
+
+ // Export our functions to Python.
+ PyObject *m;
+ m = Py_InitModule3(C("_net_proto2___python"), methods, C(module_docstring));
+ if (m == NULL) {
+ return;
+ }
+
+ AddConstants(m);
+
+ CMessage_Type.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&CMessage_Type) < 0) {
+ return;
+ }
+
+ if (!InitDescriptor()) {
+ return;
+ }
+
+ // Override {Get,Mutable}CProtoInsidePyProto.
+ GetCProtoInsidePyProtoPtr = GetCProtoInsidePyProtoImpl;
+ MutableCProtoInsidePyProtoPtr = MutableCProtoInsidePyProtoImpl;
+ }
+}
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.cc b/src/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.cc
new file mode 100644
index 0000000..fb87bad
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.cc
@@ -0,0 +1,334 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: petar@google.com (Petar Petrov)
+
+#include <Python.h>
+
+#include <google/protobuf/pyext/python_descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+
+#define C(str) const_cast<char*>(str)
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+static void CFieldDescriptorDealloc(CFieldDescriptor* self);
+
+static google::protobuf::DescriptorPool* g_descriptor_pool = NULL;
+
+static PyObject* CFieldDescriptor_GetFullName(
+ CFieldDescriptor* self, void *closure) {
+ Py_XINCREF(self->full_name);
+ return self->full_name;
+}
+
+static PyObject* CFieldDescriptor_GetName(
+ CFieldDescriptor *self, void *closure) {
+ Py_XINCREF(self->name);
+ return self->name;
+}
+
+static PyObject* CFieldDescriptor_GetCppType(
+ CFieldDescriptor *self, void *closure) {
+ Py_XINCREF(self->cpp_type);
+ return self->cpp_type;
+}
+
+static PyObject* CFieldDescriptor_GetLabel(
+ CFieldDescriptor *self, void *closure) {
+ Py_XINCREF(self->label);
+ return self->label;
+}
+
+static PyObject* CFieldDescriptor_GetID(
+ CFieldDescriptor *self, void *closure) {
+ Py_XINCREF(self->id);
+ return self->id;
+}
+
+
+static PyGetSetDef CFieldDescriptorGetters[] = {
+ { C("full_name"),
+ (getter)CFieldDescriptor_GetFullName, NULL, "Full name", NULL},
+ { C("name"),
+ (getter)CFieldDescriptor_GetName, NULL, "last name", NULL},
+ { C("cpp_type"),
+ (getter)CFieldDescriptor_GetCppType, NULL, "C++ Type", NULL},
+ { C("label"),
+ (getter)CFieldDescriptor_GetLabel, NULL, "Label", NULL},
+ { C("id"),
+ (getter)CFieldDescriptor_GetID, NULL, "ID", NULL},
+ {NULL}
+};
+
+PyTypeObject CFieldDescriptor_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ C("google3.net.google.protobuf.python.internal."
+ "_net_proto2___python."
+ "CFieldDescriptor"), // tp_name
+ sizeof(CFieldDescriptor), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)CFieldDescriptorDealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ C("A Field Descriptor"), // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ 0, // tp_methods
+ 0, // tp_members
+ CFieldDescriptorGetters, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ PyType_GenericAlloc, // tp_alloc
+ PyType_GenericNew, // tp_new
+ PyObject_Del, // tp_free
+};
+
+static void CFieldDescriptorDealloc(CFieldDescriptor* self) {
+ Py_DECREF(self->full_name);
+ Py_DECREF(self->name);
+ Py_DECREF(self->cpp_type);
+ Py_DECREF(self->label);
+ Py_DECREF(self->id);
+ self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+typedef struct {
+ PyObject_HEAD
+
+ const google::protobuf::DescriptorPool* pool;
+} CDescriptorPool;
+
+static void CDescriptorPoolDealloc(CDescriptorPool* self);
+
+static PyObject* CDescriptorPool_NewCDescriptor(
+ const google::protobuf::FieldDescriptor* field_descriptor) {
+ CFieldDescriptor* cfield_descriptor = PyObject_New(
+ CFieldDescriptor, &CFieldDescriptor_Type);
+ if (cfield_descriptor == NULL) {
+ return NULL;
+ }
+ cfield_descriptor->descriptor = field_descriptor;
+
+ cfield_descriptor->full_name = PyString_FromString(
+ field_descriptor->full_name().c_str());
+ cfield_descriptor->name = PyString_FromString(
+ field_descriptor->name().c_str());
+ cfield_descriptor->cpp_type = PyLong_FromLong(field_descriptor->cpp_type());
+ cfield_descriptor->label = PyLong_FromLong(field_descriptor->label());
+ cfield_descriptor->id = PyLong_FromVoidPtr(cfield_descriptor);
+ return reinterpret_cast<PyObject*>(cfield_descriptor);
+}
+
+static PyObject* CDescriptorPool_FindFieldByName(
+ CDescriptorPool* self, PyObject* arg) {
+ const char* full_field_name = PyString_AsString(arg);
+ if (full_field_name == NULL) {
+ return NULL;
+ }
+
+ const google::protobuf::FieldDescriptor* field_descriptor = NULL;
+
+ field_descriptor = self->pool->FindFieldByName(full_field_name);
+ if (field_descriptor == NULL) {
+ PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
+ full_field_name);
+ return NULL;
+ }
+
+ return CDescriptorPool_NewCDescriptor(field_descriptor);
+}
+
+static PyObject* CDescriptorPool_FindExtensionByName(
+ CDescriptorPool* self, PyObject* arg) {
+ const char* full_field_name = PyString_AsString(arg);
+ if (full_field_name == NULL) {
+ return NULL;
+ }
+
+ const google::protobuf::FieldDescriptor* field_descriptor =
+ self->pool->FindExtensionByName(full_field_name);
+ if (field_descriptor == NULL) {
+ PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
+ full_field_name);
+ return NULL;
+ }
+
+ return CDescriptorPool_NewCDescriptor(field_descriptor);
+}
+
+static PyMethodDef CDescriptorPoolMethods[] = {
+ { C("FindFieldByName"),
+ (PyCFunction)CDescriptorPool_FindFieldByName,
+ METH_O,
+ C("Searches for a field descriptor by full name.") },
+ { C("FindExtensionByName"),
+ (PyCFunction)CDescriptorPool_FindExtensionByName,
+ METH_O,
+ C("Searches for extension descriptor by full name.") },
+ {NULL}
+};
+
+PyTypeObject CDescriptorPool_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ C("google3.net.google.protobuf.python.internal."
+ "_net_proto2___python."
+ "CFieldDescriptor"), // tp_name
+ sizeof(CDescriptorPool), // tp_basicsize
+ 0, // tp_itemsize
+ (destructor)CDescriptorPoolDealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ C("A Descriptor Pool"), // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ CDescriptorPoolMethods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ PyType_GenericAlloc, // tp_alloc
+ PyType_GenericNew, // tp_new
+ PyObject_Del, // tp_free
+};
+
+static void CDescriptorPoolDealloc(CDescriptorPool* self) {
+ self->ob_type->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+google::protobuf::DescriptorPool* GetDescriptorPool() {
+ if (g_descriptor_pool == NULL) {
+ g_descriptor_pool = new google::protobuf::DescriptorPool(
+ google::protobuf::DescriptorPool::generated_pool());
+ }
+ return g_descriptor_pool;
+}
+
+PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) {
+ CDescriptorPool* cdescriptor_pool = PyObject_New(
+ CDescriptorPool, &CDescriptorPool_Type);
+ if (cdescriptor_pool == NULL) {
+ return NULL;
+ }
+ cdescriptor_pool->pool = GetDescriptorPool();
+ return reinterpret_cast<PyObject*>(cdescriptor_pool);
+}
+
+PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) {
+ char* message_type;
+ Py_ssize_t message_len;
+
+ if (PyString_AsStringAndSize(arg, &message_type, &message_len) < 0) {
+ return NULL;
+ }
+
+ google::protobuf::FileDescriptorProto file_proto;
+ if (!file_proto.ParseFromArray(message_type, message_len)) {
+ PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!");
+ return NULL;
+ }
+
+ // If this file is already in the generated pool, don't add it again.
+ if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+ file_proto.name()) != NULL) {
+ Py_RETURN_NONE;
+ }
+
+ const google::protobuf::FileDescriptor* descriptor = GetDescriptorPool()->BuildFile(
+ file_proto);
+ if (descriptor == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Couldn't build proto file into descriptor pool!");
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+bool InitDescriptor() {
+ CFieldDescriptor_Type.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&CFieldDescriptor_Type) < 0)
+ return false;
+
+ CDescriptorPool_Type.tp_new = PyType_GenericNew;
+ if (PyType_Ready(&CDescriptorPool_Type) < 0)
+ return false;
+ return true;
+}
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.h b/src/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.h
new file mode 100644
index 0000000..5232680
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.h
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: petar@google.com (Petar Petrov)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__
+#define GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__
+
+#include <Python.h>
+#include <structmember.h>
+
+#include <google/protobuf/descriptor.h>
+
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+typedef struct {
+ PyObject_HEAD
+
+ // The proto2 descriptor that this object represents.
+ const google::protobuf::FieldDescriptor* descriptor;
+
+ // Full name of the field (PyString).
+ PyObject* full_name;
+
+ // Name of the field (PyString).
+ PyObject* name;
+
+ // C++ type of the field (PyLong).
+ PyObject* cpp_type;
+
+ // Name of the field (PyLong).
+ PyObject* label;
+
+ // Identity of the descriptor (PyLong used as a poiner).
+ PyObject* id;
+} CFieldDescriptor;
+
+extern PyTypeObject CFieldDescriptor_Type;
+
+extern PyTypeObject CDescriptorPool_Type;
+
+
+PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args);
+PyObject* Python_BuildFile(PyObject* ignored, PyObject* args);
+bool InitDescriptor();
+google::protobuf::DescriptorPool* GetDescriptorPool();
+
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__
diff --git a/src/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.cc b/src/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.cc
new file mode 100644
index 0000000..1b1ab5d
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.cc
@@ -0,0 +1,63 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: qrczak@google.com (Marcin Kowalczyk)
+
+#include <google/protobuf/pyext/python_protobuf.h>
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) {
+ return NULL;
+}
+static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) {
+ return NULL;
+}
+
+// This is initialized with a default, stub implementation.
+// If python-google.protobuf.cc is loaded, the function pointer is overridden
+// with a full implementation.
+const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg) =
+ GetCProtoInsidePyProtoStub;
+Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg) =
+ MutableCProtoInsidePyProtoStub;
+
+const Message* GetCProtoInsidePyProto(PyObject* msg) {
+ return GetCProtoInsidePyProtoPtr(msg);
+}
+Message* MutableCProtoInsidePyProto(PyObject* msg) {
+ return MutableCProtoInsidePyProtoPtr(msg);
+}
+
+} // namespace python
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.h b/src/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.h
new file mode 100644
index 0000000..c5b0b1c
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.h
@@ -0,0 +1,57 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: qrczak@google.com (Marcin Kowalczyk)
+//
+// This module exposes the C proto inside the given Python proto, in
+// case the Python proto is implemented with a C proto.
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
+#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
+
+#include <Python.h>
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace python {
+
+// Return the pointer to the C proto inside the given Python proto,
+// or NULL when this is not a Python proto implemented with a C proto.
+const Message* GetCProtoInsidePyProto(PyObject* msg);
+Message* MutableCProtoInsidePyProto(PyObject* msg);
+
+} // namespace python
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
diff --git a/src/third_party/protobuf/python/google/protobuf/reflection.py b/src/third_party/protobuf/python/google/protobuf/reflection.py
new file mode 100755
index 0000000..1373c88
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/reflection.py
@@ -0,0 +1,142 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This code is meant to work on Python 2.4 and above only.
+
+"""Contains a metaclass and helper functions used to create
+protocol message classes from Descriptor objects at runtime.
+
+Recall that a metaclass is the "type" of a class.
+(A class is to a metaclass what an instance is to a class.)
+
+In this case, we use the GeneratedProtocolMessageType metaclass
+to inject all the useful functionality into the classes
+output by the protocol compiler at compile-time.
+
+The upshot of all this is that the real implementation
+details for ALL pure-Python protocol buffers are *here in
+this file*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+from google.protobuf.internal import api_implementation
+from google.protobuf import descriptor as descriptor_mod
+_FieldDescriptor = descriptor_mod.FieldDescriptor
+
+
+if api_implementation.Type() == 'cpp':
+ from google.protobuf.internal import cpp_message
+ _NewMessage = cpp_message.NewMessage
+ _InitMessage = cpp_message.InitMessage
+else:
+ from google.protobuf.internal import python_message
+ _NewMessage = python_message.NewMessage
+ _InitMessage = python_message.InitMessage
+
+
+class GeneratedProtocolMessageType(type):
+
+ """Metaclass for protocol message classes created at runtime from Descriptors.
+
+ We add implementations for all methods described in the Message class. We
+ also create properties to allow getting/setting all fields in the protocol
+ message. Finally, we create slots to prevent users from accidentally
+ "setting" nonexistent fields in the protocol message, which then wouldn't get
+ serialized / deserialized properly.
+
+ The protocol compiler currently uses this metaclass to create protocol
+ message classes at runtime. Clients can also manually create their own
+ classes at runtime, as in this example:
+
+ mydescriptor = Descriptor(.....)
+ class MyProtoClass(Message):
+ __metaclass__ = GeneratedProtocolMessageType
+ DESCRIPTOR = mydescriptor
+ myproto_instance = MyProtoClass()
+ myproto.foo_field = 23
+ ...
+ """
+
+ # Must be consistent with the protocol-compiler code in
+ # proto2/compiler/internal/generator.*.
+ _DESCRIPTOR_KEY = 'DESCRIPTOR'
+
+ def __new__(cls, name, bases, dictionary):
+ """Custom allocation for runtime-generated class types.
+
+ We override __new__ because this is apparently the only place
+ where we can meaningfully set __slots__ on the class we're creating(?).
+ (The interplay between metaclasses and slots is not very well-documented).
+
+ Args:
+ name: Name of the class (ignored, but required by the
+ metaclass protocol).
+ bases: Base classes of the class we're constructing.
+ (Should be message.Message). We ignore this field, but
+ it's required by the metaclass protocol
+ dictionary: The class dictionary of the class we're
+ constructing. dictionary[_DESCRIPTOR_KEY] must contain
+ a Descriptor object describing this protocol message
+ type.
+
+ Returns:
+ Newly-allocated class.
+ """
+ descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+ _NewMessage(descriptor, dictionary)
+ superclass = super(GeneratedProtocolMessageType, cls)
+
+ new_class = superclass.__new__(cls, name, bases, dictionary)
+ setattr(descriptor, '_concrete_class', new_class)
+ return new_class
+
+ def __init__(cls, name, bases, dictionary):
+ """Here we perform the majority of our work on the class.
+ We add enum getters, an __init__ method, implementations
+ of all Message methods, and properties for all fields
+ in the protocol type.
+
+ Args:
+ name: Name of the class (ignored, but required by the
+ metaclass protocol).
+ bases: Base classes of the class we're constructing.
+ (Should be message.Message). We ignore this field, but
+ it's required by the metaclass protocol
+ dictionary: The class dictionary of the class we're
+ constructing. dictionary[_DESCRIPTOR_KEY] must contain
+ a Descriptor object describing this protocol message
+ type.
+ """
+ descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+ _InitMessage(descriptor, cls)
+ superclass = super(GeneratedProtocolMessageType, cls)
+ superclass.__init__(name, bases, dictionary)
diff --git a/src/third_party/protobuf/python/google/protobuf/service.py b/src/third_party/protobuf/python/google/protobuf/service.py
new file mode 100755
index 0000000..180b70e
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/service.py
@@ -0,0 +1,226 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""DEPRECATED: Declares the RPC service interfaces.
+
+This module declares the abstract interfaces underlying proto2 RPC
+services. These are intended to be independent of any particular RPC
+implementation, so that proto2 services can be used on top of a variety
+of implementations. Starting with version 2.3.0, RPC implementations should
+not try to build on these, but should instead provide code generator plugins
+which generate code specific to the particular RPC implementation. This way
+the generated code can be more appropriate for the implementation in use
+and can avoid unnecessary layers of indirection.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+
+class RpcException(Exception):
+ """Exception raised on failed blocking RPC method call."""
+ pass
+
+
+class Service(object):
+
+ """Abstract base interface for protocol-buffer-based RPC services.
+
+ Services themselves are abstract classes (implemented either by servers or as
+ stubs), but they subclass this base interface. The methods of this
+ interface can be used to call the methods of the service without knowing
+ its exact type at compile time (analogous to the Message interface).
+ """
+
+ def GetDescriptor():
+ """Retrieves this service's descriptor."""
+ raise NotImplementedError
+
+ def CallMethod(self, method_descriptor, rpc_controller,
+ request, done):
+ """Calls a method of the service specified by method_descriptor.
+
+ If "done" is None then the call is blocking and the response
+ message will be returned directly. Otherwise the call is asynchronous
+ and "done" will later be called with the response value.
+
+ In the blocking case, RpcException will be raised on error.
+
+ Preconditions:
+ * method_descriptor.service == GetDescriptor
+ * request is of the exact same classes as returned by
+ GetRequestClass(method).
+ * After the call has started, the request must not be modified.
+ * "rpc_controller" is of the correct type for the RPC implementation being
+ used by this Service. For stubs, the "correct type" depends on the
+ RpcChannel which the stub is using.
+
+ Postconditions:
+ * "done" will be called when the method is complete. This may be
+ before CallMethod() returns or it may be at some point in the future.
+ * If the RPC failed, the response value passed to "done" will be None.
+ Further details about the failure can be found by querying the
+ RpcController.
+ """
+ raise NotImplementedError
+
+ def GetRequestClass(self, method_descriptor):
+ """Returns the class of the request message for the specified method.
+
+ CallMethod() requires that the request is of a particular subclass of
+ Message. GetRequestClass() gets the default instance of this required
+ type.
+
+ Example:
+ method = service.GetDescriptor().FindMethodByName("Foo")
+ request = stub.GetRequestClass(method)()
+ request.ParseFromString(input)
+ service.CallMethod(method, request, callback)
+ """
+ raise NotImplementedError
+
+ def GetResponseClass(self, method_descriptor):
+ """Returns the class of the response message for the specified method.
+
+ This method isn't really needed, as the RpcChannel's CallMethod constructs
+ the response protocol message. It's provided anyway in case it is useful
+ for the caller to know the response type in advance.
+ """
+ raise NotImplementedError
+
+
+class RpcController(object):
+
+ """An RpcController mediates a single method call.
+
+ The primary purpose of the controller is to provide a way to manipulate
+ settings specific to the RPC implementation and to find out about RPC-level
+ errors. The methods provided by the RpcController interface are intended
+ to be a "least common denominator" set of features which we expect all
+ implementations to support. Specific implementations may provide more
+ advanced features (e.g. deadline propagation).
+ """
+
+ # Client-side methods below
+
+ def Reset(self):
+ """Resets the RpcController to its initial state.
+
+ After the RpcController has been reset, it may be reused in
+ a new call. Must not be called while an RPC is in progress.
+ """
+ raise NotImplementedError
+
+ def Failed(self):
+ """Returns true if the call failed.
+
+ After a call has finished, returns true if the call failed. The possible
+ reasons for failure depend on the RPC implementation. Failed() must not
+ be called before a call has finished. If Failed() returns true, the
+ contents of the response message are undefined.
+ """
+ raise NotImplementedError
+
+ def ErrorText(self):
+ """If Failed is true, returns a human-readable description of the error."""
+ raise NotImplementedError
+
+ def StartCancel(self):
+ """Initiate cancellation.
+
+ Advises the RPC system that the caller desires that the RPC call be
+ canceled. The RPC system may cancel it immediately, may wait awhile and
+ then cancel it, or may not even cancel the call at all. If the call is
+ canceled, the "done" callback will still be called and the RpcController
+ will indicate that the call failed at that time.
+ """
+ raise NotImplementedError
+
+ # Server-side methods below
+
+ def SetFailed(self, reason):
+ """Sets a failure reason.
+
+ Causes Failed() to return true on the client side. "reason" will be
+ incorporated into the message returned by ErrorText(). If you find
+ you need to return machine-readable information about failures, you
+ should incorporate it into your response protocol buffer and should
+ NOT call SetFailed().
+ """
+ raise NotImplementedError
+
+ def IsCanceled(self):
+ """Checks if the client cancelled the RPC.
+
+ If true, indicates that the client canceled the RPC, so the server may
+ as well give up on replying to it. The server should still call the
+ final "done" callback.
+ """
+ raise NotImplementedError
+
+ def NotifyOnCancel(self, callback):
+ """Sets a callback to invoke on cancel.
+
+ Asks that the given callback be called when the RPC is canceled. The
+ callback will always be called exactly once. If the RPC completes without
+ being canceled, the callback will be called after completion. If the RPC
+ has already been canceled when NotifyOnCancel() is called, the callback
+ will be called immediately.
+
+ NotifyOnCancel() must be called no more than once per request.
+ """
+ raise NotImplementedError
+
+
+class RpcChannel(object):
+
+ """Abstract interface for an RPC channel.
+
+ An RpcChannel represents a communication line to a service which can be used
+ to call that service's methods. The service may be running on another
+ machine. Normally, you should not use an RpcChannel directly, but instead
+ construct a stub {@link Service} wrapping it. Example:
+
+ Example:
+ RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234")
+ RpcController controller = rpcImpl.Controller()
+ MyService service = MyService_Stub(channel)
+ service.MyMethod(controller, request, callback)
+ """
+
+ def CallMethod(self, method_descriptor, rpc_controller,
+ request, response_class, done):
+ """Calls the method identified by the descriptor.
+
+ Call the given method of the remote service. The signature of this
+ procedure looks the same as Service.CallMethod(), but the requirements
+ are less strict in one important way: the request object doesn't have to
+ be of any specific class as long as its descriptor is method.input_type.
+ """
+ raise NotImplementedError
diff --git a/src/third_party/protobuf/python/google/protobuf/service_reflection.py b/src/third_party/protobuf/python/google/protobuf/service_reflection.py
new file mode 100755
index 0000000..851e83e
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/service_reflection.py
@@ -0,0 +1,284 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains metaclasses used to create protocol service and service stub
+classes from ServiceDescriptor objects at runtime.
+
+The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to
+inject all useful functionality into the classes output by the protocol
+compiler at compile-time.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+
+class GeneratedServiceType(type):
+
+ """Metaclass for service classes created at runtime from ServiceDescriptors.
+
+ Implementations for all methods described in the Service class are added here
+ by this class. We also create properties to allow getting/setting all fields
+ in the protocol message.
+
+ The protocol compiler currently uses this metaclass to create protocol service
+ classes at runtime. Clients can also manually create their own classes at
+ runtime, as in this example:
+
+ mydescriptor = ServiceDescriptor(.....)
+ class MyProtoService(service.Service):
+ __metaclass__ = GeneratedServiceType
+ DESCRIPTOR = mydescriptor
+ myservice_instance = MyProtoService()
+ ...
+ """
+
+ _DESCRIPTOR_KEY = 'DESCRIPTOR'
+
+ def __init__(cls, name, bases, dictionary):
+ """Creates a message service class.
+
+ Args:
+ name: Name of the class (ignored, but required by the metaclass
+ protocol).
+ bases: Base classes of the class being constructed.
+ dictionary: The class dictionary of the class being constructed.
+ dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object
+ describing this protocol service type.
+ """
+ # Don't do anything if this class doesn't have a descriptor. This happens
+ # when a service class is subclassed.
+ if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary:
+ return
+ descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY]
+ service_builder = _ServiceBuilder(descriptor)
+ service_builder.BuildService(cls)
+
+
+class GeneratedServiceStubType(GeneratedServiceType):
+
+ """Metaclass for service stubs created at runtime from ServiceDescriptors.
+
+ This class has similar responsibilities as GeneratedServiceType, except that
+ it creates the service stub classes.
+ """
+
+ _DESCRIPTOR_KEY = 'DESCRIPTOR'
+
+ def __init__(cls, name, bases, dictionary):
+ """Creates a message service stub class.
+
+ Args:
+ name: Name of the class (ignored, here).
+ bases: Base classes of the class being constructed.
+ dictionary: The class dictionary of the class being constructed.
+ dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object
+ describing this protocol service type.
+ """
+ super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary)
+ # Don't do anything if this class doesn't have a descriptor. This happens
+ # when a service stub is subclassed.
+ if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary:
+ return
+ descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY]
+ service_stub_builder = _ServiceStubBuilder(descriptor)
+ service_stub_builder.BuildServiceStub(cls)
+
+
+class _ServiceBuilder(object):
+
+ """This class constructs a protocol service class using a service descriptor.
+
+ Given a service descriptor, this class constructs a class that represents
+ the specified service descriptor. One service builder instance constructs
+ exactly one service class. That means all instances of that class share the
+ same builder.
+ """
+
+ def __init__(self, service_descriptor):
+ """Initializes an instance of the service class builder.
+
+ Args:
+ service_descriptor: ServiceDescriptor to use when constructing the
+ service class.
+ """
+ self.descriptor = service_descriptor
+
+ def BuildService(self, cls):
+ """Constructs the service class.
+
+ Args:
+ cls: The class that will be constructed.
+ """
+
+ # CallMethod needs to operate with an instance of the Service class. This
+ # internal wrapper function exists only to be able to pass the service
+ # instance to the method that does the real CallMethod work.
+ def _WrapCallMethod(srvc, method_descriptor,
+ rpc_controller, request, callback):
+ return self._CallMethod(srvc, method_descriptor,
+ rpc_controller, request, callback)
+ self.cls = cls
+ cls.CallMethod = _WrapCallMethod
+ cls.GetDescriptor = staticmethod(lambda: self.descriptor)
+ cls.GetDescriptor.__doc__ = "Returns the service descriptor."
+ cls.GetRequestClass = self._GetRequestClass
+ cls.GetResponseClass = self._GetResponseClass
+ for method in self.descriptor.methods:
+ setattr(cls, method.name, self._GenerateNonImplementedMethod(method))
+
+ def _CallMethod(self, srvc, method_descriptor,
+ rpc_controller, request, callback):
+ """Calls the method described by a given method descriptor.
+
+ Args:
+ srvc: Instance of the service for which this method is called.
+ method_descriptor: Descriptor that represent the method to call.
+ rpc_controller: RPC controller to use for this method's execution.
+ request: Request protocol message.
+ callback: A callback to invoke after the method has completed.
+ """
+ if method_descriptor.containing_service != self.descriptor:
+ raise RuntimeError(
+ 'CallMethod() given method descriptor for wrong service type.')
+ method = getattr(srvc, method_descriptor.name)
+ return method(rpc_controller, request, callback)
+
+ def _GetRequestClass(self, method_descriptor):
+ """Returns the class of the request protocol message.
+
+ Args:
+ method_descriptor: Descriptor of the method for which to return the
+ request protocol message class.
+
+ Returns:
+ A class that represents the input protocol message of the specified
+ method.
+ """
+ if method_descriptor.containing_service != self.descriptor:
+ raise RuntimeError(
+ 'GetRequestClass() given method descriptor for wrong service type.')
+ return method_descriptor.input_type._concrete_class
+
+ def _GetResponseClass(self, method_descriptor):
+ """Returns the class of the response protocol message.
+
+ Args:
+ method_descriptor: Descriptor of the method for which to return the
+ response protocol message class.
+
+ Returns:
+ A class that represents the output protocol message of the specified
+ method.
+ """
+ if method_descriptor.containing_service != self.descriptor:
+ raise RuntimeError(
+ 'GetResponseClass() given method descriptor for wrong service type.')
+ return method_descriptor.output_type._concrete_class
+
+ def _GenerateNonImplementedMethod(self, method):
+ """Generates and returns a method that can be set for a service methods.
+
+ Args:
+ method: Descriptor of the service method for which a method is to be
+ generated.
+
+ Returns:
+ A method that can be added to the service class.
+ """
+ return lambda inst, rpc_controller, request, callback: (
+ self._NonImplementedMethod(method.name, rpc_controller, callback))
+
+ def _NonImplementedMethod(self, method_name, rpc_controller, callback):
+ """The body of all methods in the generated service class.
+
+ Args:
+ method_name: Name of the method being executed.
+ rpc_controller: RPC controller used to execute this method.
+ callback: A callback which will be invoked when the method finishes.
+ """
+ rpc_controller.SetFailed('Method %s not implemented.' % method_name)
+ callback(None)
+
+
+class _ServiceStubBuilder(object):
+
+ """Constructs a protocol service stub class using a service descriptor.
+
+ Given a service descriptor, this class constructs a suitable stub class.
+ A stub is just a type-safe wrapper around an RpcChannel which emulates a
+ local implementation of the service.
+
+ One service stub builder instance constructs exactly one class. It means all
+ instances of that class share the same service stub builder.
+ """
+
+ def __init__(self, service_descriptor):
+ """Initializes an instance of the service stub class builder.
+
+ Args:
+ service_descriptor: ServiceDescriptor to use when constructing the
+ stub class.
+ """
+ self.descriptor = service_descriptor
+
+ def BuildServiceStub(self, cls):
+ """Constructs the stub class.
+
+ Args:
+ cls: The class that will be constructed.
+ """
+
+ def _ServiceStubInit(stub, rpc_channel):
+ stub.rpc_channel = rpc_channel
+ self.cls = cls
+ cls.__init__ = _ServiceStubInit
+ for method in self.descriptor.methods:
+ setattr(cls, method.name, self._GenerateStubMethod(method))
+
+ def _GenerateStubMethod(self, method):
+ return (lambda inst, rpc_controller, request, callback=None:
+ self._StubMethod(inst, method, rpc_controller, request, callback))
+
+ def _StubMethod(self, stub, method_descriptor,
+ rpc_controller, request, callback):
+ """The body of all service methods in the generated stub class.
+
+ Args:
+ stub: Stub instance.
+ method_descriptor: Descriptor of the invoked method.
+ rpc_controller: Rpc controller to execute the method.
+ request: Request protocol message.
+ callback: A callback to execute when the method finishes.
+ Returns:
+ Response message (in case of blocking call).
+ """
+ return stub.rpc_channel.CallMethod(
+ method_descriptor, rpc_controller, request,
+ method_descriptor.output_type._concrete_class, callback)
diff --git a/src/third_party/protobuf/python/google/protobuf/text_format.py b/src/third_party/protobuf/python/google/protobuf/text_format.py
new file mode 100755
index 0000000..c3a1cf6
--- /dev/null
+++ b/src/third_party/protobuf/python/google/protobuf/text_format.py
@@ -0,0 +1,691 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains routines for printing protocol messages in text format."""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import cStringIO
+import re
+
+from collections import deque
+from google.protobuf.internal import type_checkers
+from google.protobuf import descriptor
+
+__all__ = [ 'MessageToString', 'PrintMessage', 'PrintField',
+ 'PrintFieldValue', 'Merge' ]
+
+
+# Infinity and NaN are not explicitly supported by Python pre-2.6, and
+# float('inf') does not work on Windows (pre-2.6).
+_INFINITY = 1e10000 # overflows, thus will actually be infinity.
+_NAN = _INFINITY * 0
+
+
+class ParseError(Exception):
+ """Thrown in case of ASCII parsing error."""
+
+
+def MessageToString(message, as_utf8=False, as_one_line=False):
+ out = cStringIO.StringIO()
+ PrintMessage(message, out, as_utf8=as_utf8, as_one_line=as_one_line)
+ result = out.getvalue()
+ out.close()
+ if as_one_line:
+ return result.rstrip()
+ return result
+
+
+def PrintMessage(message, out, indent=0, as_utf8=False, as_one_line=False):
+ for field, value in message.ListFields():
+ if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ for element in value:
+ PrintField(field, element, out, indent, as_utf8, as_one_line)
+ else:
+ PrintField(field, value, out, indent, as_utf8, as_one_line)
+
+
+def PrintField(field, value, out, indent=0, as_utf8=False, as_one_line=False):
+ """Print a single field name/value pair. For repeated fields, the value
+ should be a single element."""
+
+ out.write(' ' * indent);
+ if field.is_extension:
+ out.write('[')
+ if (field.containing_type.GetOptions().message_set_wire_format and
+ field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
+ field.message_type == field.extension_scope and
+ field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
+ out.write(field.message_type.full_name)
+ else:
+ out.write(field.full_name)
+ out.write(']')
+ elif field.type == descriptor.FieldDescriptor.TYPE_GROUP:
+ # For groups, use the capitalized name.
+ out.write(field.message_type.name)
+ else:
+ out.write(field.name)
+
+ if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ # The colon is optional in this case, but our cross-language golden files
+ # don't include it.
+ out.write(': ')
+
+ PrintFieldValue(field, value, out, indent, as_utf8, as_one_line)
+ if as_one_line:
+ out.write(' ')
+ else:
+ out.write('\n')
+
+
+def PrintFieldValue(field, value, out, indent=0,
+ as_utf8=False, as_one_line=False):
+ """Print a single field value (not including name). For repeated fields,
+ the value should be a single element."""
+
+ if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ if as_one_line:
+ out.write(' { ')
+ PrintMessage(value, out, indent, as_utf8, as_one_line)
+ out.write('}')
+ else:
+ out.write(' {\n')
+ PrintMessage(value, out, indent + 2, as_utf8, as_one_line)
+ out.write(' ' * indent + '}')
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
+ out.write(field.enum_type.values_by_number[value].name)
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
+ out.write('\"')
+ if type(value) is unicode:
+ out.write(_CEscape(value.encode('utf-8'), as_utf8))
+ else:
+ out.write(_CEscape(value, as_utf8))
+ out.write('\"')
+ elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
+ if value:
+ out.write("true")
+ else:
+ out.write("false")
+ else:
+ out.write(str(value))
+
+
+def Merge(text, message):
+ """Merges an ASCII representation of a protocol message into a message.
+
+ Args:
+ text: Message ASCII representation.
+ message: A protocol buffer message to merge into.
+
+ Raises:
+ ParseError: On ASCII parsing problems.
+ """
+ tokenizer = _Tokenizer(text)
+ while not tokenizer.AtEnd():
+ _MergeField(tokenizer, message)
+
+
+def _MergeField(tokenizer, message):
+ """Merges a single protocol message field into a message.
+
+ Args:
+ tokenizer: A tokenizer to parse the field name and values.
+ message: A protocol message to record the data.
+
+ Raises:
+ ParseError: In case of ASCII parsing problems.
+ """
+ message_descriptor = message.DESCRIPTOR
+ if tokenizer.TryConsume('['):
+ name = [tokenizer.ConsumeIdentifier()]
+ while tokenizer.TryConsume('.'):
+ name.append(tokenizer.ConsumeIdentifier())
+ name = '.'.join(name)
+
+ if not message_descriptor.is_extendable:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Message type "%s" does not have extensions.' %
+ message_descriptor.full_name)
+ field = message.Extensions._FindExtensionByName(name)
+ if not field:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Extension "%s" not registered.' % name)
+ elif message_descriptor != field.containing_type:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Extension "%s" does not extend message type "%s".' % (
+ name, message_descriptor.full_name))
+ tokenizer.Consume(']')
+ else:
+ name = tokenizer.ConsumeIdentifier()
+ field = message_descriptor.fields_by_name.get(name, None)
+
+ # Group names are expected to be capitalized as they appear in the
+ # .proto file, which actually matches their type names, not their field
+ # names.
+ if not field:
+ field = message_descriptor.fields_by_name.get(name.lower(), None)
+ if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP:
+ field = None
+
+ if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and
+ field.message_type.name != name):
+ field = None
+
+ if not field:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Message type "%s" has no field named "%s".' % (
+ message_descriptor.full_name, name))
+
+ if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+ tokenizer.TryConsume(':')
+
+ if tokenizer.TryConsume('<'):
+ end_token = '>'
+ else:
+ tokenizer.Consume('{')
+ end_token = '}'
+
+ if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ if field.is_extension:
+ sub_message = message.Extensions[field].add()
+ else:
+ sub_message = getattr(message, field.name).add()
+ else:
+ if field.is_extension:
+ sub_message = message.Extensions[field]
+ else:
+ sub_message = getattr(message, field.name)
+ sub_message.SetInParent()
+
+ while not tokenizer.TryConsume(end_token):
+ if tokenizer.AtEnd():
+ raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token))
+ _MergeField(tokenizer, sub_message)
+ else:
+ _MergeScalarField(tokenizer, message, field)
+
+
+def _MergeScalarField(tokenizer, message, field):
+ """Merges a single protocol message scalar field into a message.
+
+ Args:
+ tokenizer: A tokenizer to parse the field value.
+ message: A protocol message to record the data.
+ field: The descriptor of the field to be merged.
+
+ Raises:
+ ParseError: In case of ASCII parsing problems.
+ RuntimeError: On runtime errors.
+ """
+ tokenizer.Consume(':')
+ value = None
+
+ if field.type in (descriptor.FieldDescriptor.TYPE_INT32,
+ descriptor.FieldDescriptor.TYPE_SINT32,
+ descriptor.FieldDescriptor.TYPE_SFIXED32):
+ value = tokenizer.ConsumeInt32()
+ elif field.type in (descriptor.FieldDescriptor.TYPE_INT64,
+ descriptor.FieldDescriptor.TYPE_SINT64,
+ descriptor.FieldDescriptor.TYPE_SFIXED64):
+ value = tokenizer.ConsumeInt64()
+ elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32,
+ descriptor.FieldDescriptor.TYPE_FIXED32):
+ value = tokenizer.ConsumeUint32()
+ elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64,
+ descriptor.FieldDescriptor.TYPE_FIXED64):
+ value = tokenizer.ConsumeUint64()
+ elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT,
+ descriptor.FieldDescriptor.TYPE_DOUBLE):
+ value = tokenizer.ConsumeFloat()
+ elif field.type == descriptor.FieldDescriptor.TYPE_BOOL:
+ value = tokenizer.ConsumeBool()
+ elif field.type == descriptor.FieldDescriptor.TYPE_STRING:
+ value = tokenizer.ConsumeString()
+ elif field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+ value = tokenizer.ConsumeByteString()
+ elif field.type == descriptor.FieldDescriptor.TYPE_ENUM:
+ # Enum can be specified by a number (the enum value), or by
+ # a string literal (the enum name).
+ enum_descriptor = field.enum_type
+ if tokenizer.LookingAtInteger():
+ number = tokenizer.ConsumeInt32()
+ enum_value = enum_descriptor.values_by_number.get(number, None)
+ if enum_value is None:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Enum type "%s" has no value with number %d.' % (
+ enum_descriptor.full_name, number))
+ else:
+ identifier = tokenizer.ConsumeIdentifier()
+ enum_value = enum_descriptor.values_by_name.get(identifier, None)
+ if enum_value is None:
+ raise tokenizer.ParseErrorPreviousToken(
+ 'Enum type "%s" has no value named %s.' % (
+ enum_descriptor.full_name, identifier))
+ value = enum_value.number
+ else:
+ raise RuntimeError('Unknown field type %d' % field.type)
+
+ if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+ if field.is_extension:
+ message.Extensions[field].append(value)
+ else:
+ getattr(message, field.name).append(value)
+ else:
+ if field.is_extension:
+ message.Extensions[field] = value
+ else:
+ setattr(message, field.name, value)
+
+
+class _Tokenizer(object):
+ """Protocol buffer ASCII representation tokenizer.
+
+ This class handles the lower level string parsing by splitting it into
+ meaningful tokens.
+
+ It was directly ported from the Java protocol buffer API.
+ """
+
+ _WHITESPACE = re.compile('(\\s|(#.*$))+', re.MULTILINE)
+ _TOKEN = re.compile(
+ '[a-zA-Z_][0-9a-zA-Z_+-]*|' # an identifier
+ '[0-9+-][0-9a-zA-Z_.+-]*|' # a number
+ '\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|' # a double-quoted string
+ '\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)') # a single-quoted string
+ _IDENTIFIER = re.compile('\w+')
+ _INTEGER_CHECKERS = [type_checkers.Uint32ValueChecker(),
+ type_checkers.Int32ValueChecker(),
+ type_checkers.Uint64ValueChecker(),
+ type_checkers.Int64ValueChecker()]
+ _FLOAT_INFINITY = re.compile('-?inf(inity)?f?', re.IGNORECASE)
+ _FLOAT_NAN = re.compile("nanf?", re.IGNORECASE)
+
+ def __init__(self, text_message):
+ self._text_message = text_message
+
+ self._position = 0
+ self._line = -1
+ self._column = 0
+ self._token_start = None
+ self.token = ''
+ self._lines = deque(text_message.split('\n'))
+ self._current_line = ''
+ self._previous_line = 0
+ self._previous_column = 0
+ self._SkipWhitespace()
+ self.NextToken()
+
+ def AtEnd(self):
+ """Checks the end of the text was reached.
+
+ Returns:
+ True iff the end was reached.
+ """
+ return self.token == ''
+
+ def _PopLine(self):
+ while len(self._current_line) <= self._column:
+ if not self._lines:
+ self._current_line = ''
+ return
+ self._line += 1
+ self._column = 0
+ self._current_line = self._lines.popleft()
+
+ def _SkipWhitespace(self):
+ while True:
+ self._PopLine()
+ match = self._WHITESPACE.match(self._current_line, self._column)
+ if not match:
+ break
+ length = len(match.group(0))
+ self._column += length
+
+ def TryConsume(self, token):
+ """Tries to consume a given piece of text.
+
+ Args:
+ token: Text to consume.
+
+ Returns:
+ True iff the text was consumed.
+ """
+ if self.token == token:
+ self.NextToken()
+ return True
+ return False
+
+ def Consume(self, token):
+ """Consumes a piece of text.
+
+ Args:
+ token: Text to consume.
+
+ Raises:
+ ParseError: If the text couldn't be consumed.
+ """
+ if not self.TryConsume(token):
+ raise self._ParseError('Expected "%s".' % token)
+
+ def LookingAtInteger(self):
+ """Checks if the current token is an integer.
+
+ Returns:
+ True iff the current token is an integer.
+ """
+ if not self.token:
+ return False
+ c = self.token[0]
+ return (c >= '0' and c <= '9') or c == '-' or c == '+'
+
+ def ConsumeIdentifier(self):
+ """Consumes protocol message field identifier.
+
+ Returns:
+ Identifier string.
+
+ Raises:
+ ParseError: If an identifier couldn't be consumed.
+ """
+ result = self.token
+ if not self._IDENTIFIER.match(result):
+ raise self._ParseError('Expected identifier.')
+ self.NextToken()
+ return result
+
+ def ConsumeInt32(self):
+ """Consumes a signed 32bit integer number.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If a signed 32bit integer couldn't be consumed.
+ """
+ try:
+ result = self._ParseInteger(self.token, is_signed=True, is_long=False)
+ except ValueError, e:
+ raise self._IntegerParseError(e)
+ self.NextToken()
+ return result
+
+ def ConsumeUint32(self):
+ """Consumes an unsigned 32bit integer number.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If an unsigned 32bit integer couldn't be consumed.
+ """
+ try:
+ result = self._ParseInteger(self.token, is_signed=False, is_long=False)
+ except ValueError, e:
+ raise self._IntegerParseError(e)
+ self.NextToken()
+ return result
+
+ def ConsumeInt64(self):
+ """Consumes a signed 64bit integer number.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If a signed 64bit integer couldn't be consumed.
+ """
+ try:
+ result = self._ParseInteger(self.token, is_signed=True, is_long=True)
+ except ValueError, e:
+ raise self._IntegerParseError(e)
+ self.NextToken()
+ return result
+
+ def ConsumeUint64(self):
+ """Consumes an unsigned 64bit integer number.
+
+ Returns:
+ The integer parsed.
+
+ Raises:
+ ParseError: If an unsigned 64bit integer couldn't be consumed.
+ """
+ try:
+ result = self._ParseInteger(self.token, is_signed=False, is_long=True)
+ except ValueError, e:
+ raise self._IntegerParseError(e)
+ self.NextToken()
+ return result
+
+ def ConsumeFloat(self):
+ """Consumes an floating point number.
+
+ Returns:
+ The number parsed.
+
+ Raises:
+ ParseError: If a floating point number couldn't be consumed.
+ """
+ text = self.token
+ if self._FLOAT_INFINITY.match(text):
+ self.NextToken()
+ if text.startswith('-'):
+ return -_INFINITY
+ return _INFINITY
+
+ if self._FLOAT_NAN.match(text):
+ self.NextToken()
+ return _NAN
+
+ try:
+ result = float(text)
+ except ValueError, e:
+ raise self._FloatParseError(e)
+ self.NextToken()
+ return result
+
+ def ConsumeBool(self):
+ """Consumes a boolean value.
+
+ Returns:
+ The bool parsed.
+
+ Raises:
+ ParseError: If a boolean value couldn't be consumed.
+ """
+ if self.token in ('true', 't', '1'):
+ self.NextToken()
+ return True
+ elif self.token in ('false', 'f', '0'):
+ self.NextToken()
+ return False
+ else:
+ raise self._ParseError('Expected "true" or "false".')
+
+ def ConsumeString(self):
+ """Consumes a string value.
+
+ Returns:
+ The string parsed.
+
+ Raises:
+ ParseError: If a string value couldn't be consumed.
+ """
+ bytes = self.ConsumeByteString()
+ try:
+ return unicode(bytes, 'utf-8')
+ except UnicodeDecodeError, e:
+ raise self._StringParseError(e)
+
+ def ConsumeByteString(self):
+ """Consumes a byte array value.
+
+ Returns:
+ The array parsed (as a string).
+
+ Raises:
+ ParseError: If a byte array value couldn't be consumed.
+ """
+ list = [self._ConsumeSingleByteString()]
+ while len(self.token) > 0 and self.token[0] in ('\'', '"'):
+ list.append(self._ConsumeSingleByteString())
+ return "".join(list)
+
+ def _ConsumeSingleByteString(self):
+ """Consume one token of a string literal.
+
+ String literals (whether bytes or text) can come in multiple adjacent
+ tokens which are automatically concatenated, like in C or Python. This
+ method only consumes one token.
+ """
+ text = self.token
+ if len(text) < 1 or text[0] not in ('\'', '"'):
+ raise self._ParseError('Exptected string.')
+
+ if len(text) < 2 or text[-1] != text[0]:
+ raise self._ParseError('String missing ending quote.')
+
+ try:
+ result = _CUnescape(text[1:-1])
+ except ValueError, e:
+ raise self._ParseError(str(e))
+ self.NextToken()
+ return result
+
+ def _ParseInteger(self, text, is_signed=False, is_long=False):
+ """Parses an integer.
+
+ Args:
+ text: The text to parse.
+ is_signed: True if a signed integer must be parsed.
+ is_long: True if a long integer must be parsed.
+
+ Returns:
+ The integer value.
+
+ Raises:
+ ValueError: Thrown Iff the text is not a valid integer.
+ """
+ pos = 0
+ if text.startswith('-'):
+ pos += 1
+
+ base = 10
+ if text.startswith('0x', pos) or text.startswith('0X', pos):
+ base = 16
+ elif text.startswith('0', pos):
+ base = 8
+
+ # Do the actual parsing. Exception handling is propagated to caller.
+ result = int(text, base)
+
+ # Check if the integer is sane. Exceptions handled by callers.
+ checker = self._INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)]
+ checker.CheckValue(result)
+ return result
+
+ def ParseErrorPreviousToken(self, message):
+ """Creates and *returns* a ParseError for the previously read token.
+
+ Args:
+ message: A message to set for the exception.
+
+ Returns:
+ A ParseError instance.
+ """
+ return ParseError('%d:%d : %s' % (
+ self._previous_line + 1, self._previous_column + 1, message))
+
+ def _ParseError(self, message):
+ """Creates and *returns* a ParseError for the current token."""
+ return ParseError('%d:%d : %s' % (
+ self._line + 1, self._column - len(self.token) + 1, message))
+
+ def _IntegerParseError(self, e):
+ return self._ParseError('Couldn\'t parse integer: ' + str(e))
+
+ def _FloatParseError(self, e):
+ return self._ParseError('Couldn\'t parse number: ' + str(e))
+
+ def _StringParseError(self, e):
+ return self._ParseError('Couldn\'t parse string: ' + str(e))
+
+ def NextToken(self):
+ """Reads the next meaningful token."""
+ self._previous_line = self._line
+ self._previous_column = self._column
+
+ self._column += len(self.token)
+ self._SkipWhitespace()
+
+ if not self._lines and len(self._current_line) <= self._column:
+ self.token = ''
+ return
+
+ match = self._TOKEN.match(self._current_line, self._column)
+ if match:
+ token = match.group(0)
+ self.token = token
+ else:
+ self.token = self._current_line[self._column]
+
+
+# text.encode('string_escape') does not seem to satisfy our needs as it
+# encodes unprintable characters using two-digit hex escapes whereas our
+# C++ unescaping function allows hex escapes to be any length. So,
+# "\0011".encode('string_escape') ends up being "\\x011", which will be
+# decoded in C++ as a single-character string with char code 0x11.
+def _CEscape(text, as_utf8):
+ def escape(c):
+ o = ord(c)
+ if o == 10: return r"\n" # optional escape
+ if o == 13: return r"\r" # optional escape
+ if o == 9: return r"\t" # optional escape
+ if o == 39: return r"\'" # optional escape
+
+ if o == 34: return r'\"' # necessary escape
+ if o == 92: return r"\\" # necessary escape
+
+ # necessary escapes
+ if not as_utf8 and (o >= 127 or o < 32): return "\\%03o" % o
+ return c
+ return "".join([escape(c) for c in text])
+
+
+_CUNESCAPE_HEX = re.compile('\\\\x([0-9a-fA-F]{2}|[0-9a-fA-F])')
+
+
+def _CUnescape(text):
+ def ReplaceHex(m):
+ return chr(int(m.group(0)[2:], 16))
+ # This is required because the 'string_escape' encoding doesn't
+ # allow single-digit hex escapes (like '\xf').
+ result = _CUNESCAPE_HEX.sub(ReplaceHex, text)
+ return result.decode('string_escape')
diff --git a/src/third_party/protobuf/python/mox.py b/src/third_party/protobuf/python/mox.py
new file mode 100755
index 0000000..ce80ba5
--- /dev/null
+++ b/src/third_party/protobuf/python/mox.py
@@ -0,0 +1,1401 @@
+#!/usr/bin/python2.4
+#
+# Copyright 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This file is used for testing. The original is at:
+# http://code.google.com/p/pymox/
+
+"""Mox, an object-mocking framework for Python.
+
+Mox works in the record-replay-verify paradigm. When you first create
+a mock object, it is in record mode. You then programmatically set
+the expected behavior of the mock object (what methods are to be
+called on it, with what parameters, what they should return, and in
+what order).
+
+Once you have set up the expected mock behavior, you put it in replay
+mode. Now the mock responds to method calls just as you told it to.
+If an unexpected method (or an expected method with unexpected
+parameters) is called, then an exception will be raised.
+
+Once you are done interacting with the mock, you need to verify that
+all the expected interactions occured. (Maybe your code exited
+prematurely without calling some cleanup method!) The verify phase
+ensures that every expected method was called; otherwise, an exception
+will be raised.
+
+Suggested usage / workflow:
+
+ # Create Mox factory
+ my_mox = Mox()
+
+ # Create a mock data access object
+ mock_dao = my_mox.CreateMock(DAOClass)
+
+ # Set up expected behavior
+ mock_dao.RetrievePersonWithIdentifier('1').AndReturn(person)
+ mock_dao.DeletePerson(person)
+
+ # Put mocks in replay mode
+ my_mox.ReplayAll()
+
+ # Inject mock object and run test
+ controller.SetDao(mock_dao)
+ controller.DeletePersonById('1')
+
+ # Verify all methods were called as expected
+ my_mox.VerifyAll()
+"""
+
+from collections import deque
+import re
+import types
+import unittest
+
+import stubout
+
+class Error(AssertionError):
+ """Base exception for this module."""
+
+ pass
+
+
+class ExpectedMethodCallsError(Error):
+ """Raised when Verify() is called before all expected methods have been called
+ """
+
+ def __init__(self, expected_methods):
+ """Init exception.
+
+ Args:
+ # expected_methods: A sequence of MockMethod objects that should have been
+ # called.
+ expected_methods: [MockMethod]
+
+ Raises:
+ ValueError: if expected_methods contains no methods.
+ """
+
+ if not expected_methods:
+ raise ValueError("There must be at least one expected method")
+ Error.__init__(self)
+ self._expected_methods = expected_methods
+
+ def __str__(self):
+ calls = "\n".join(["%3d. %s" % (i, m)
+ for i, m in enumerate(self._expected_methods)])
+ return "Verify: Expected methods never called:\n%s" % (calls,)
+
+
+class UnexpectedMethodCallError(Error):
+ """Raised when an unexpected method is called.
+
+ This can occur if a method is called with incorrect parameters, or out of the
+ specified order.
+ """
+
+ def __init__(self, unexpected_method, expected):
+ """Init exception.
+
+ Args:
+ # unexpected_method: MockMethod that was called but was not at the head of
+ # the expected_method queue.
+ # expected: MockMethod or UnorderedGroup the method should have
+ # been in.
+ unexpected_method: MockMethod
+ expected: MockMethod or UnorderedGroup
+ """
+
+ Error.__init__(self)
+ self._unexpected_method = unexpected_method
+ self._expected = expected
+
+ def __str__(self):
+ return "Unexpected method call: %s. Expecting: %s" % \
+ (self._unexpected_method, self._expected)
+
+
+class UnknownMethodCallError(Error):
+ """Raised if an unknown method is requested of the mock object."""
+
+ def __init__(self, unknown_method_name):
+ """Init exception.
+
+ Args:
+ # unknown_method_name: Method call that is not part of the mocked class's
+ # public interface.
+ unknown_method_name: str
+ """
+
+ Error.__init__(self)
+ self._unknown_method_name = unknown_method_name
+
+ def __str__(self):
+ return "Method called is not a member of the object: %s" % \
+ self._unknown_method_name
+
+
+class Mox(object):
+ """Mox: a factory for creating mock objects."""
+
+ # A list of types that should be stubbed out with MockObjects (as
+ # opposed to MockAnythings).
+ _USE_MOCK_OBJECT = [types.ClassType, types.InstanceType, types.ModuleType,
+ types.ObjectType, types.TypeType]
+
+ def __init__(self):
+ """Initialize a new Mox."""
+
+ self._mock_objects = []
+ self.stubs = stubout.StubOutForTesting()
+
+ def CreateMock(self, class_to_mock):
+ """Create a new mock object.
+
+ Args:
+ # class_to_mock: the class to be mocked
+ class_to_mock: class
+
+ Returns:
+ MockObject that can be used as the class_to_mock would be.
+ """
+
+ new_mock = MockObject(class_to_mock)
+ self._mock_objects.append(new_mock)
+ return new_mock
+
+ def CreateMockAnything(self):
+ """Create a mock that will accept any method calls.
+
+ This does not enforce an interface.
+ """
+
+ new_mock = MockAnything()
+ self._mock_objects.append(new_mock)
+ return new_mock
+
+ def ReplayAll(self):
+ """Set all mock objects to replay mode."""
+
+ for mock_obj in self._mock_objects:
+ mock_obj._Replay()
+
+
+ def VerifyAll(self):
+ """Call verify on all mock objects created."""
+
+ for mock_obj in self._mock_objects:
+ mock_obj._Verify()
+
+ def ResetAll(self):
+ """Call reset on all mock objects. This does not unset stubs."""
+
+ for mock_obj in self._mock_objects:
+ mock_obj._Reset()
+
+ def StubOutWithMock(self, obj, attr_name, use_mock_anything=False):
+ """Replace a method, attribute, etc. with a Mock.
+
+ This will replace a class or module with a MockObject, and everything else
+ (method, function, etc) with a MockAnything. This can be overridden to
+ always use a MockAnything by setting use_mock_anything to True.
+
+ Args:
+ obj: A Python object (class, module, instance, callable).
+ attr_name: str. The name of the attribute to replace with a mock.
+ use_mock_anything: bool. True if a MockAnything should be used regardless
+ of the type of attribute.
+ """
+
+ attr_to_replace = getattr(obj, attr_name)
+ if type(attr_to_replace) in self._USE_MOCK_OBJECT and not use_mock_anything:
+ stub = self.CreateMock(attr_to_replace)
+ else:
+ stub = self.CreateMockAnything()
+
+ self.stubs.Set(obj, attr_name, stub)
+
+ def UnsetStubs(self):
+ """Restore stubs to their original state."""
+
+ self.stubs.UnsetAll()
+
+def Replay(*args):
+ """Put mocks into Replay mode.
+
+ Args:
+ # args is any number of mocks to put into replay mode.
+ """
+
+ for mock in args:
+ mock._Replay()
+
+
+def Verify(*args):
+ """Verify mocks.
+
+ Args:
+ # args is any number of mocks to be verified.
+ """
+
+ for mock in args:
+ mock._Verify()
+
+
+def Reset(*args):
+ """Reset mocks.
+
+ Args:
+ # args is any number of mocks to be reset.
+ """
+
+ for mock in args:
+ mock._Reset()
+
+
+class MockAnything:
+ """A mock that can be used to mock anything.
+
+ This is helpful for mocking classes that do not provide a public interface.
+ """
+
+ def __init__(self):
+ """ """
+ self._Reset()
+
+ def __getattr__(self, method_name):
+ """Intercept method calls on this object.
+
+ A new MockMethod is returned that is aware of the MockAnything's
+ state (record or replay). The call will be recorded or replayed
+ by the MockMethod's __call__.
+
+ Args:
+ # method name: the name of the method being called.
+ method_name: str
+
+ Returns:
+ A new MockMethod aware of MockAnything's state (record or replay).
+ """
+
+ return self._CreateMockMethod(method_name)
+
+ def _CreateMockMethod(self, method_name):
+ """Create a new mock method call and return it.
+
+ Args:
+ # method name: the name of the method being called.
+ method_name: str
+
+ Returns:
+ A new MockMethod aware of MockAnything's state (record or replay).
+ """
+
+ return MockMethod(method_name, self._expected_calls_queue,
+ self._replay_mode)
+
+ def __nonzero__(self):
+ """Return 1 for nonzero so the mock can be used as a conditional."""
+
+ return 1
+
+ def __eq__(self, rhs):
+ """Provide custom logic to compare objects."""
+
+ return (isinstance(rhs, MockAnything) and
+ self._replay_mode == rhs._replay_mode and
+ self._expected_calls_queue == rhs._expected_calls_queue)
+
+ def __ne__(self, rhs):
+ """Provide custom logic to compare objects."""
+
+ return not self == rhs
+
+ def _Replay(self):
+ """Start replaying expected method calls."""
+
+ self._replay_mode = True
+
+ def _Verify(self):
+ """Verify that all of the expected calls have been made.
+
+ Raises:
+ ExpectedMethodCallsError: if there are still more method calls in the
+ expected queue.
+ """
+
+ # If the list of expected calls is not empty, raise an exception
+ if self._expected_calls_queue:
+ # The last MultipleTimesGroup is not popped from the queue.
+ if (len(self._expected_calls_queue) == 1 and
+ isinstance(self._expected_calls_queue[0], MultipleTimesGroup) and
+ self._expected_calls_queue[0].IsSatisfied()):
+ pass
+ else:
+ raise ExpectedMethodCallsError(self._expected_calls_queue)
+
+ def _Reset(self):
+ """Reset the state of this mock to record mode with an empty queue."""
+
+ # Maintain a list of method calls we are expecting
+ self._expected_calls_queue = deque()
+
+ # Make sure we are in setup mode, not replay mode
+ self._replay_mode = False
+
+
+class MockObject(MockAnything, object):
+ """A mock object that simulates the public/protected interface of a class."""
+
+ def __init__(self, class_to_mock):
+ """Initialize a mock object.
+
+ This determines the methods and properties of the class and stores them.
+
+ Args:
+ # class_to_mock: class to be mocked
+ class_to_mock: class
+ """
+
+ # This is used to hack around the mixin/inheritance of MockAnything, which
+ # is not a proper object (it can be anything. :-)
+ MockAnything.__dict__['__init__'](self)
+
+ # Get a list of all the public and special methods we should mock.
+ self._known_methods = set()
+ self._known_vars = set()
+ self._class_to_mock = class_to_mock
+ for method in dir(class_to_mock):
+ if callable(getattr(class_to_mock, method)):
+ self._known_methods.add(method)
+ else:
+ self._known_vars.add(method)
+
+ def __getattr__(self, name):
+ """Intercept attribute request on this object.
+
+ If the attribute is a public class variable, it will be returned and not
+ recorded as a call.
+
+ If the attribute is not a variable, it is handled like a method
+ call. The method name is checked against the set of mockable
+ methods, and a new MockMethod is returned that is aware of the
+ MockObject's state (record or replay). The call will be recorded
+ or replayed by the MockMethod's __call__.
+
+ Args:
+ # name: the name of the attribute being requested.
+ name: str
+
+ Returns:
+ Either a class variable or a new MockMethod that is aware of the state
+ of the mock (record or replay).
+
+ Raises:
+ UnknownMethodCallError if the MockObject does not mock the requested
+ method.
+ """
+
+ if name in self._known_vars:
+ return getattr(self._class_to_mock, name)
+
+ if name in self._known_methods:
+ return self._CreateMockMethod(name)
+
+ raise UnknownMethodCallError(name)
+
+ def __eq__(self, rhs):
+ """Provide custom logic to compare objects."""
+
+ return (isinstance(rhs, MockObject) and
+ self._class_to_mock == rhs._class_to_mock and
+ self._replay_mode == rhs._replay_mode and
+ self._expected_calls_queue == rhs._expected_calls_queue)
+
+ def __setitem__(self, key, value):
+ """Provide custom logic for mocking classes that support item assignment.
+
+ Args:
+ key: Key to set the value for.
+ value: Value to set.
+
+ Returns:
+ Expected return value in replay mode. A MockMethod object for the
+ __setitem__ method that has already been called if not in replay mode.
+
+ Raises:
+ TypeError if the underlying class does not support item assignment.
+ UnexpectedMethodCallError if the object does not expect the call to
+ __setitem__.
+
+ """
+ setitem = self._class_to_mock.__dict__.get('__setitem__', None)
+
+ # Verify the class supports item assignment.
+ if setitem is None:
+ raise TypeError('object does not support item assignment')
+
+ # If we are in replay mode then simply call the mock __setitem__ method.
+ if self._replay_mode:
+ return MockMethod('__setitem__', self._expected_calls_queue,
+ self._replay_mode)(key, value)
+
+
+ # Otherwise, create a mock method __setitem__.
+ return self._CreateMockMethod('__setitem__')(key, value)
+
+ def __getitem__(self, key):
+ """Provide custom logic for mocking classes that are subscriptable.
+
+ Args:
+ key: Key to return the value for.
+
+ Returns:
+ Expected return value in replay mode. A MockMethod object for the
+ __getitem__ method that has already been called if not in replay mode.
+
+ Raises:
+ TypeError if the underlying class is not subscriptable.
+ UnexpectedMethodCallError if the object does not expect the call to
+ __setitem__.
+
+ """
+ getitem = self._class_to_mock.__dict__.get('__getitem__', None)
+
+ # Verify the class supports item assignment.
+ if getitem is None:
+ raise TypeError('unsubscriptable object')
+
+ # If we are in replay mode then simply call the mock __getitem__ method.
+ if self._replay_mode:
+ return MockMethod('__getitem__', self._expected_calls_queue,
+ self._replay_mode)(key)
+
+
+ # Otherwise, create a mock method __getitem__.
+ return self._CreateMockMethod('__getitem__')(key)
+
+ def __call__(self, *params, **named_params):
+ """Provide custom logic for mocking classes that are callable."""
+
+ # Verify the class we are mocking is callable
+ callable = self._class_to_mock.__dict__.get('__call__', None)
+ if callable is None:
+ raise TypeError('Not callable')
+
+ # Because the call is happening directly on this object instead of a method,
+ # the call on the mock method is made right here
+ mock_method = self._CreateMockMethod('__call__')
+ return mock_method(*params, **named_params)
+
+ @property
+ def __class__(self):
+ """Return the class that is being mocked."""
+
+ return self._class_to_mock
+
+
+class MockMethod(object):
+ """Callable mock method.
+
+ A MockMethod should act exactly like the method it mocks, accepting parameters
+ and returning a value, or throwing an exception (as specified). When this
+ method is called, it can optionally verify whether the called method (name and
+ signature) matches the expected method.
+ """
+
+ def __init__(self, method_name, call_queue, replay_mode):
+ """Construct a new mock method.
+
+ Args:
+ # method_name: the name of the method
+ # call_queue: deque of calls, verify this call against the head, or add
+ # this call to the queue.
+ # replay_mode: False if we are recording, True if we are verifying calls
+ # against the call queue.
+ method_name: str
+ call_queue: list or deque
+ replay_mode: bool
+ """
+
+ self._name = method_name
+ self._call_queue = call_queue
+ if not isinstance(call_queue, deque):
+ self._call_queue = deque(self._call_queue)
+ self._replay_mode = replay_mode
+
+ self._params = None
+ self._named_params = None
+ self._return_value = None
+ self._exception = None
+ self._side_effects = None
+
+ def __call__(self, *params, **named_params):
+ """Log parameters and return the specified return value.
+
+ If the Mock(Anything/Object) associated with this call is in record mode,
+ this MockMethod will be pushed onto the expected call queue. If the mock
+ is in replay mode, this will pop a MockMethod off the top of the queue and
+ verify this call is equal to the expected call.
+
+ Raises:
+ UnexpectedMethodCall if this call is supposed to match an expected method
+ call and it does not.
+ """
+
+ self._params = params
+ self._named_params = named_params
+
+ if not self._replay_mode:
+ self._call_queue.append(self)
+ return self
+
+ expected_method = self._VerifyMethodCall()
+
+ if expected_method._side_effects:
+ expected_method._side_effects(*params, **named_params)
+
+ if expected_method._exception:
+ raise expected_method._exception
+
+ return expected_method._return_value
+
+ def __getattr__(self, name):
+ """Raise an AttributeError with a helpful message."""
+
+ raise AttributeError('MockMethod has no attribute "%s". '
+ 'Did you remember to put your mocks in replay mode?' % name)
+
+ def _PopNextMethod(self):
+ """Pop the next method from our call queue."""
+ try:
+ return self._call_queue.popleft()
+ except IndexError:
+ raise UnexpectedMethodCallError(self, None)
+
+ def _VerifyMethodCall(self):
+ """Verify the called method is expected.
+
+ This can be an ordered method, or part of an unordered set.
+
+ Returns:
+ The expected mock method.
+
+ Raises:
+ UnexpectedMethodCall if the method called was not expected.
+ """
+
+ expected = self._PopNextMethod()
+
+ # Loop here, because we might have a MethodGroup followed by another
+ # group.
+ while isinstance(expected, MethodGroup):
+ expected, method = expected.MethodCalled(self)
+ if method is not None:
+ return method
+
+ # This is a mock method, so just check equality.
+ if expected != self:
+ raise UnexpectedMethodCallError(self, expected)
+
+ return expected
+
+ def __str__(self):
+ params = ', '.join(
+ [repr(p) for p in self._params or []] +
+ ['%s=%r' % x for x in sorted((self._named_params or {}).items())])
+ desc = "%s(%s) -> %r" % (self._name, params, self._return_value)
+ return desc
+
+ def __eq__(self, rhs):
+ """Test whether this MockMethod is equivalent to another MockMethod.
+
+ Args:
+ # rhs: the right hand side of the test
+ rhs: MockMethod
+ """
+
+ return (isinstance(rhs, MockMethod) and
+ self._name == rhs._name and
+ self._params == rhs._params and
+ self._named_params == rhs._named_params)
+
+ def __ne__(self, rhs):
+ """Test whether this MockMethod is not equivalent to another MockMethod.
+
+ Args:
+ # rhs: the right hand side of the test
+ rhs: MockMethod
+ """
+
+ return not self == rhs
+
+ def GetPossibleGroup(self):
+ """Returns a possible group from the end of the call queue or None if no
+ other methods are on the stack.
+ """
+
+ # Remove this method from the tail of the queue so we can add it to a group.
+ this_method = self._call_queue.pop()
+ assert this_method == self
+
+ # Determine if the tail of the queue is a group, or just a regular ordered
+ # mock method.
+ group = None
+ try:
+ group = self._call_queue[-1]
+ except IndexError:
+ pass
+
+ return group
+
+ def _CheckAndCreateNewGroup(self, group_name, group_class):
+ """Checks if the last method (a possible group) is an instance of our
+ group_class. Adds the current method to this group or creates a new one.
+
+ Args:
+
+ group_name: the name of the group.
+ group_class: the class used to create instance of this new group
+ """
+ group = self.GetPossibleGroup()
+
+ # If this is a group, and it is the correct group, add the method.
+ if isinstance(group, group_class) and group.group_name() == group_name:
+ group.AddMethod(self)
+ return self
+
+ # Create a new group and add the method.
+ new_group = group_class(group_name)
+ new_group.AddMethod(self)
+ self._call_queue.append(new_group)
+ return self
+
+ def InAnyOrder(self, group_name="default"):
+ """Move this method into a group of unordered calls.
+
+ A group of unordered calls must be defined together, and must be executed
+ in full before the next expected method can be called. There can be
+ multiple groups that are expected serially, if they are given
+ different group names. The same group name can be reused if there is a
+ standard method call, or a group with a different name, spliced between
+ usages.
+
+ Args:
+ group_name: the name of the unordered group.
+
+ Returns:
+ self
+ """
+ return self._CheckAndCreateNewGroup(group_name, UnorderedGroup)
+
+ def MultipleTimes(self, group_name="default"):
+ """Move this method into group of calls which may be called multiple times.
+
+ A group of repeating calls must be defined together, and must be executed in
+ full before the next expected mehtod can be called.
+
+ Args:
+ group_name: the name of the unordered group.
+
+ Returns:
+ self
+ """
+ return self._CheckAndCreateNewGroup(group_name, MultipleTimesGroup)
+
+ def AndReturn(self, return_value):
+ """Set the value to return when this method is called.
+
+ Args:
+ # return_value can be anything.
+ """
+
+ self._return_value = return_value
+ return return_value
+
+ def AndRaise(self, exception):
+ """Set the exception to raise when this method is called.
+
+ Args:
+ # exception: the exception to raise when this method is called.
+ exception: Exception
+ """
+
+ self._exception = exception
+
+ def WithSideEffects(self, side_effects):
+ """Set the side effects that are simulated when this method is called.
+
+ Args:
+ side_effects: A callable which modifies the parameters or other relevant
+ state which a given test case depends on.
+
+ Returns:
+ Self for chaining with AndReturn and AndRaise.
+ """
+ self._side_effects = side_effects
+ return self
+
+class Comparator:
+ """Base class for all Mox comparators.
+
+ A Comparator can be used as a parameter to a mocked method when the exact
+ value is not known. For example, the code you are testing might build up a
+ long SQL string that is passed to your mock DAO. You're only interested that
+ the IN clause contains the proper primary keys, so you can set your mock
+ up as follows:
+
+ mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result)
+
+ Now whatever query is passed in must contain the string 'IN (1, 2, 4, 5)'.
+
+ A Comparator may replace one or more parameters, for example:
+ # return at most 10 rows
+ mock_dao.RunQuery(StrContains('SELECT'), 10)
+
+ or
+
+ # Return some non-deterministic number of rows
+ mock_dao.RunQuery(StrContains('SELECT'), IsA(int))
+ """
+
+ def equals(self, rhs):
+ """Special equals method that all comparators must implement.
+
+ Args:
+ rhs: any python object
+ """
+
+ raise NotImplementedError, 'method must be implemented by a subclass.'
+
+ def __eq__(self, rhs):
+ return self.equals(rhs)
+
+ def __ne__(self, rhs):
+ return not self.equals(rhs)
+
+
+class IsA(Comparator):
+ """This class wraps a basic Python type or class. It is used to verify
+ that a parameter is of the given type or class.
+
+ Example:
+ mock_dao.Connect(IsA(DbConnectInfo))
+ """
+
+ def __init__(self, class_name):
+ """Initialize IsA
+
+ Args:
+ class_name: basic python type or a class
+ """
+
+ self._class_name = class_name
+
+ def equals(self, rhs):
+ """Check to see if the RHS is an instance of class_name.
+
+ Args:
+ # rhs: the right hand side of the test
+ rhs: object
+
+ Returns:
+ bool
+ """
+
+ try:
+ return isinstance(rhs, self._class_name)
+ except TypeError:
+ # Check raw types if there was a type error. This is helpful for
+ # things like cStringIO.StringIO.
+ return type(rhs) == type(self._class_name)
+
+ def __repr__(self):
+ return str(self._class_name)
+
+class IsAlmost(Comparator):
+ """Comparison class used to check whether a parameter is nearly equal
+ to a given value. Generally useful for floating point numbers.
+
+ Example mock_dao.SetTimeout((IsAlmost(3.9)))
+ """
+
+ def __init__(self, float_value, places=7):
+ """Initialize IsAlmost.
+
+ Args:
+ float_value: The value for making the comparison.
+ places: The number of decimal places to round to.
+ """
+
+ self._float_value = float_value
+ self._places = places
+
+ def equals(self, rhs):
+ """Check to see if RHS is almost equal to float_value
+
+ Args:
+ rhs: the value to compare to float_value
+
+ Returns:
+ bool
+ """
+
+ try:
+ return round(rhs-self._float_value, self._places) == 0
+ except TypeError:
+ # This is probably because either float_value or rhs is not a number.
+ return False
+
+ def __repr__(self):
+ return str(self._float_value)
+
+class StrContains(Comparator):
+ """Comparison class used to check whether a substring exists in a
+ string parameter. This can be useful in mocking a database with SQL
+ passed in as a string parameter, for example.
+
+ Example:
+ mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result)
+ """
+
+ def __init__(self, search_string):
+ """Initialize.
+
+ Args:
+ # search_string: the string you are searching for
+ search_string: str
+ """
+
+ self._search_string = search_string
+
+ def equals(self, rhs):
+ """Check to see if the search_string is contained in the rhs string.
+
+ Args:
+ # rhs: the right hand side of the test
+ rhs: object
+
+ Returns:
+ bool
+ """
+
+ try:
+ return rhs.find(self._search_string) > -1
+ except Exception:
+ return False
+
+ def __repr__(self):
+ return '<str containing \'%s\'>' % self._search_string
+
+
+class Regex(Comparator):
+ """Checks if a string matches a regular expression.
+
+ This uses a given regular expression to determine equality.
+ """
+
+ def __init__(self, pattern, flags=0):
+ """Initialize.
+
+ Args:
+ # pattern is the regular expression to search for
+ pattern: str
+ # flags passed to re.compile function as the second argument
+ flags: int
+ """
+
+ self.regex = re.compile(pattern, flags=flags)
+
+ def equals(self, rhs):
+ """Check to see if rhs matches regular expression pattern.
+
+ Returns:
+ bool
+ """
+
+ return self.regex.search(rhs) is not None
+
+ def __repr__(self):
+ s = '<regular expression \'%s\'' % self.regex.pattern
+ if self.regex.flags:
+ s += ', flags=%d' % self.regex.flags
+ s += '>'
+ return s
+
+
+class In(Comparator):
+ """Checks whether an item (or key) is in a list (or dict) parameter.
+
+ Example:
+ mock_dao.GetUsersInfo(In('expectedUserName')).AndReturn(mock_result)
+ """
+
+ def __init__(self, key):
+ """Initialize.
+
+ Args:
+ # key is any thing that could be in a list or a key in a dict
+ """
+
+ self._key = key
+
+ def equals(self, rhs):
+ """Check to see whether key is in rhs.
+
+ Args:
+ rhs: dict
+
+ Returns:
+ bool
+ """
+
+ return self._key in rhs
+
+ def __repr__(self):
+ return '<sequence or map containing \'%s\'>' % self._key
+
+
+class ContainsKeyValue(Comparator):
+ """Checks whether a key/value pair is in a dict parameter.
+
+ Example:
+ mock_dao.UpdateUsers(ContainsKeyValue('stevepm', stevepm_user_info))
+ """
+
+ def __init__(self, key, value):
+ """Initialize.
+
+ Args:
+ # key: a key in a dict
+ # value: the corresponding value
+ """
+
+ self._key = key
+ self._value = value
+
+ def equals(self, rhs):
+ """Check whether the given key/value pair is in the rhs dict.
+
+ Returns:
+ bool
+ """
+
+ try:
+ return rhs[self._key] == self._value
+ except Exception:
+ return False
+
+ def __repr__(self):
+ return '<map containing the entry \'%s: %s\'>' % (self._key, self._value)
+
+
+class SameElementsAs(Comparator):
+ """Checks whether iterables contain the same elements (ignoring order).
+
+ Example:
+ mock_dao.ProcessUsers(SameElementsAs('stevepm', 'salomaki'))
+ """
+
+ def __init__(self, expected_seq):
+ """Initialize.
+
+ Args:
+ expected_seq: a sequence
+ """
+
+ self._expected_seq = expected_seq
+
+ def equals(self, actual_seq):
+ """Check to see whether actual_seq has same elements as expected_seq.
+
+ Args:
+ actual_seq: sequence
+
+ Returns:
+ bool
+ """
+
+ try:
+ expected = dict([(element, None) for element in self._expected_seq])
+ actual = dict([(element, None) for element in actual_seq])
+ except TypeError:
+ # Fall back to slower list-compare if any of the objects are unhashable.
+ expected = list(self._expected_seq)
+ actual = list(actual_seq)
+ expected.sort()
+ actual.sort()
+ return expected == actual
+
+ def __repr__(self):
+ return '<sequence with same elements as \'%s\'>' % self._expected_seq
+
+
+class And(Comparator):
+ """Evaluates one or more Comparators on RHS and returns an AND of the results.
+ """
+
+ def __init__(self, *args):
+ """Initialize.
+
+ Args:
+ *args: One or more Comparator
+ """
+
+ self._comparators = args
+
+ def equals(self, rhs):
+ """Checks whether all Comparators are equal to rhs.
+
+ Args:
+ # rhs: can be anything
+
+ Returns:
+ bool
+ """
+
+ for comparator in self._comparators:
+ if not comparator.equals(rhs):
+ return False
+
+ return True
+
+ def __repr__(self):
+ return '<AND %s>' % str(self._comparators)
+
+
+class Or(Comparator):
+ """Evaluates one or more Comparators on RHS and returns an OR of the results.
+ """
+
+ def __init__(self, *args):
+ """Initialize.
+
+ Args:
+ *args: One or more Mox comparators
+ """
+
+ self._comparators = args
+
+ def equals(self, rhs):
+ """Checks whether any Comparator is equal to rhs.
+
+ Args:
+ # rhs: can be anything
+
+ Returns:
+ bool
+ """
+
+ for comparator in self._comparators:
+ if comparator.equals(rhs):
+ return True
+
+ return False
+
+ def __repr__(self):
+ return '<OR %s>' % str(self._comparators)
+
+
+class Func(Comparator):
+ """Call a function that should verify the parameter passed in is correct.
+
+ You may need the ability to perform more advanced operations on the parameter
+ in order to validate it. You can use this to have a callable validate any
+ parameter. The callable should return either True or False.
+
+
+ Example:
+
+ def myParamValidator(param):
+ # Advanced logic here
+ return True
+
+ mock_dao.DoSomething(Func(myParamValidator), true)
+ """
+
+ def __init__(self, func):
+ """Initialize.
+
+ Args:
+ func: callable that takes one parameter and returns a bool
+ """
+
+ self._func = func
+
+ def equals(self, rhs):
+ """Test whether rhs passes the function test.
+
+ rhs is passed into func.
+
+ Args:
+ rhs: any python object
+
+ Returns:
+ the result of func(rhs)
+ """
+
+ return self._func(rhs)
+
+ def __repr__(self):
+ return str(self._func)
+
+
+class IgnoreArg(Comparator):
+ """Ignore an argument.
+
+ This can be used when we don't care about an argument of a method call.
+
+ Example:
+ # Check if CastMagic is called with 3 as first arg and 'disappear' as third.
+ mymock.CastMagic(3, IgnoreArg(), 'disappear')
+ """
+
+ def equals(self, unused_rhs):
+ """Ignores arguments and returns True.
+
+ Args:
+ unused_rhs: any python object
+
+ Returns:
+ always returns True
+ """
+
+ return True
+
+ def __repr__(self):
+ return '<IgnoreArg>'
+
+
+class MethodGroup(object):
+ """Base class containing common behaviour for MethodGroups."""
+
+ def __init__(self, group_name):
+ self._group_name = group_name
+
+ def group_name(self):
+ return self._group_name
+
+ def __str__(self):
+ return '<%s "%s">' % (self.__class__.__name__, self._group_name)
+
+ def AddMethod(self, mock_method):
+ raise NotImplementedError
+
+ def MethodCalled(self, mock_method):
+ raise NotImplementedError
+
+ def IsSatisfied(self):
+ raise NotImplementedError
+
+class UnorderedGroup(MethodGroup):
+ """UnorderedGroup holds a set of method calls that may occur in any order.
+
+ This construct is helpful for non-deterministic events, such as iterating
+ over the keys of a dict.
+ """
+
+ def __init__(self, group_name):
+ super(UnorderedGroup, self).__init__(group_name)
+ self._methods = []
+
+ def AddMethod(self, mock_method):
+ """Add a method to this group.
+
+ Args:
+ mock_method: A mock method to be added to this group.
+ """
+
+ self._methods.append(mock_method)
+
+ def MethodCalled(self, mock_method):
+ """Remove a method call from the group.
+
+ If the method is not in the set, an UnexpectedMethodCallError will be
+ raised.
+
+ Args:
+ mock_method: a mock method that should be equal to a method in the group.
+
+ Returns:
+ The mock method from the group
+
+ Raises:
+ UnexpectedMethodCallError if the mock_method was not in the group.
+ """
+
+ # Check to see if this method exists, and if so, remove it from the set
+ # and return it.
+ for method in self._methods:
+ if method == mock_method:
+ # Remove the called mock_method instead of the method in the group.
+ # The called method will match any comparators when equality is checked
+ # during removal. The method in the group could pass a comparator to
+ # another comparator during the equality check.
+ self._methods.remove(mock_method)
+
+ # If this group is not empty, put it back at the head of the queue.
+ if not self.IsSatisfied():
+ mock_method._call_queue.appendleft(self)
+
+ return self, method
+
+ raise UnexpectedMethodCallError(mock_method, self)
+
+ def IsSatisfied(self):
+ """Return True if there are not any methods in this group."""
+
+ return len(self._methods) == 0
+
+
+class MultipleTimesGroup(MethodGroup):
+ """MultipleTimesGroup holds methods that may be called any number of times.
+
+ Note: Each method must be called at least once.
+
+ This is helpful, if you don't know or care how many times a method is called.
+ """
+
+ def __init__(self, group_name):
+ super(MultipleTimesGroup, self).__init__(group_name)
+ self._methods = set()
+ self._methods_called = set()
+
+ def AddMethod(self, mock_method):
+ """Add a method to this group.
+
+ Args:
+ mock_method: A mock method to be added to this group.
+ """
+
+ self._methods.add(mock_method)
+
+ def MethodCalled(self, mock_method):
+ """Remove a method call from the group.
+
+ If the method is not in the set, an UnexpectedMethodCallError will be
+ raised.
+
+ Args:
+ mock_method: a mock method that should be equal to a method in the group.
+
+ Returns:
+ The mock method from the group
+
+ Raises:
+ UnexpectedMethodCallError if the mock_method was not in the group.
+ """
+
+ # Check to see if this method exists, and if so add it to the set of
+ # called methods.
+
+ for method in self._methods:
+ if method == mock_method:
+ self._methods_called.add(mock_method)
+ # Always put this group back on top of the queue, because we don't know
+ # when we are done.
+ mock_method._call_queue.appendleft(self)
+ return self, method
+
+ if self.IsSatisfied():
+ next_method = mock_method._PopNextMethod();
+ return next_method, None
+ else:
+ raise UnexpectedMethodCallError(mock_method, self)
+
+ def IsSatisfied(self):
+ """Return True if all methods in this group are called at least once."""
+ # NOTE(psycho): We can't use the simple set difference here because we want
+ # to match different parameters which are considered the same e.g. IsA(str)
+ # and some string. This solution is O(n^2) but n should be small.
+ tmp = self._methods.copy()
+ for called in self._methods_called:
+ for expected in tmp:
+ if called == expected:
+ tmp.remove(expected)
+ if not tmp:
+ return True
+ break
+ return False
+
+
+class MoxMetaTestBase(type):
+ """Metaclass to add mox cleanup and verification to every test.
+
+ As the mox unit testing class is being constructed (MoxTestBase or a
+ subclass), this metaclass will modify all test functions to call the
+ CleanUpMox method of the test class after they finish. This means that
+ unstubbing and verifying will happen for every test with no additional code,
+ and any failures will result in test failures as opposed to errors.
+ """
+
+ def __init__(cls, name, bases, d):
+ type.__init__(cls, name, bases, d)
+
+ # also get all the attributes from the base classes to account
+ # for a case when test class is not the immediate child of MoxTestBase
+ for base in bases:
+ for attr_name in dir(base):
+ d[attr_name] = getattr(base, attr_name)
+
+ for func_name, func in d.items():
+ if func_name.startswith('test') and callable(func):
+ setattr(cls, func_name, MoxMetaTestBase.CleanUpTest(cls, func))
+
+ @staticmethod
+ def CleanUpTest(cls, func):
+ """Adds Mox cleanup code to any MoxTestBase method.
+
+ Always unsets stubs after a test. Will verify all mocks for tests that
+ otherwise pass.
+
+ Args:
+ cls: MoxTestBase or subclass; the class whose test method we are altering.
+ func: method; the method of the MoxTestBase test class we wish to alter.
+
+ Returns:
+ The modified method.
+ """
+ def new_method(self, *args, **kwargs):
+ mox_obj = getattr(self, 'mox', None)
+ cleanup_mox = False
+ if mox_obj and isinstance(mox_obj, Mox):
+ cleanup_mox = True
+ try:
+ func(self, *args, **kwargs)
+ finally:
+ if cleanup_mox:
+ mox_obj.UnsetStubs()
+ if cleanup_mox:
+ mox_obj.VerifyAll()
+ new_method.__name__ = func.__name__
+ new_method.__doc__ = func.__doc__
+ new_method.__module__ = func.__module__
+ return new_method
+
+
+class MoxTestBase(unittest.TestCase):
+ """Convenience test class to make stubbing easier.
+
+ Sets up a "mox" attribute which is an instance of Mox - any mox tests will
+ want this. Also automatically unsets any stubs and verifies that all mock
+ methods have been called at the end of each test, eliminating boilerplate
+ code.
+ """
+
+ __metaclass__ = MoxMetaTestBase
+
+ def setUp(self):
+ self.mox = Mox()
diff --git a/src/third_party/protobuf/python/setup.py b/src/third_party/protobuf/python/setup.py
new file mode 100755
index 0000000..7d9714e
--- /dev/null
+++ b/src/third_party/protobuf/python/setup.py
@@ -0,0 +1,152 @@
+#! /usr/bin/python
+#
+# See README for usage instructions.
+
+# We must use setuptools, not distutils, because we need to use the
+# namespace_packages option for the "google" package.
+from ez_setup import use_setuptools
+use_setuptools()
+
+from setuptools import setup, Extension
+from distutils.spawn import find_executable
+import sys
+import os
+import subprocess
+
+maintainer_email = "protobuf@googlegroups.com"
+
+# Find the Protocol Compiler.
+if os.path.exists("../src/protoc"):
+ protoc = "../src/protoc"
+elif os.path.exists("../src/protoc.exe"):
+ protoc = "../src/protoc.exe"
+elif os.path.exists("../vsprojects/Debug/protoc.exe"):
+ protoc = "../vsprojects/Debug/protoc.exe"
+elif os.path.exists("../vsprojects/Release/protoc.exe"):
+ protoc = "../vsprojects/Release/protoc.exe"
+else:
+ protoc = find_executable("protoc")
+
+def generate_proto(source):
+ """Invokes the Protocol Compiler to generate a _pb2.py from the given
+ .proto file. Does nothing if the output already exists and is newer than
+ the input."""
+
+ output = source.replace(".proto", "_pb2.py").replace("../src/", "")
+
+ if not os.path.exists(source):
+ print "Can't find required file: " + source
+ sys.exit(-1)
+
+ if (not os.path.exists(output) or
+ (os.path.exists(source) and
+ os.path.getmtime(source) > os.path.getmtime(output))):
+ print "Generating %s..." % output
+
+ if protoc == None:
+ sys.stderr.write(
+ "protoc is not installed nor found in ../src. Please compile it "
+ "or install the binary package.\n")
+ sys.exit(-1)
+
+ protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ]
+ if subprocess.call(protoc_command) != 0:
+ sys.exit(-1)
+
+def MakeTestSuite():
+ # This is apparently needed on some systems to make sure that the tests
+ # work even if a previous version is already installed.
+ if 'google' in sys.modules:
+ del sys.modules['google']
+
+ generate_proto("../src/google/protobuf/unittest.proto")
+ generate_proto("../src/google/protobuf/unittest_custom_options.proto")
+ generate_proto("../src/google/protobuf/unittest_import.proto")
+ generate_proto("../src/google/protobuf/unittest_mset.proto")
+ generate_proto("../src/google/protobuf/unittest_no_generic_services.proto")
+ generate_proto("google/protobuf/internal/more_extensions.proto")
+ generate_proto("google/protobuf/internal/more_messages.proto")
+
+ import unittest
+ import google.protobuf.internal.generator_test as generator_test
+ import google.protobuf.internal.descriptor_test as descriptor_test
+ import google.protobuf.internal.reflection_test as reflection_test
+ import google.protobuf.internal.service_reflection_test \
+ as service_reflection_test
+ import google.protobuf.internal.text_format_test as text_format_test
+ import google.protobuf.internal.wire_format_test as wire_format_test
+
+ loader = unittest.defaultTestLoader
+ suite = unittest.TestSuite()
+ for test in [ generator_test,
+ descriptor_test,
+ reflection_test,
+ service_reflection_test,
+ text_format_test,
+ wire_format_test ]:
+ suite.addTest(loader.loadTestsFromModule(test))
+
+ return suite
+
+if __name__ == '__main__':
+ # TODO(kenton): Integrate this into setuptools somehow?
+ if len(sys.argv) >= 2 and sys.argv[1] == "clean":
+ # Delete generated _pb2.py files and .pyc files in the code tree.
+ for (dirpath, dirnames, filenames) in os.walk("."):
+ for filename in filenames:
+ filepath = os.path.join(dirpath, filename)
+ if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \
+ filepath.endswith(".so") or filepath.endswith(".o"):
+ os.remove(filepath)
+ else:
+ # Generate necessary .proto file if it doesn't exist.
+ # TODO(kenton): Maybe we should hook this into a distutils command?
+ generate_proto("../src/google/protobuf/descriptor.proto")
+ generate_proto("../src/google/protobuf/compiler/plugin.proto")
+
+ ext_module_list = []
+
+ # C++ implementation extension
+ if os.getenv("PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION", "python") == "cpp":
+ print "Using EXPERIMENTAL C++ Implmenetation."
+ ext_module_list.append(Extension(
+ "google.protobuf.internal._net_proto2___python",
+ [ "google/protobuf/pyext/python_descriptor.cc",
+ "google/protobuf/pyext/python_protobuf.cc",
+ "google/protobuf/pyext/python-proto2.cc" ],
+ include_dirs = [ "." ],
+ libraries = [ "protobuf" ]))
+
+ setup(name = 'protobuf',
+ version = '2.4.2-pre',
+ packages = [ 'google' ],
+ namespace_packages = [ 'google' ],
+ test_suite = 'setup.MakeTestSuite',
+ # Must list modules explicitly so that we don't install tests.
+ py_modules = [
+ 'google.protobuf.internal.api_implementation',
+ 'google.protobuf.internal.containers',
+ 'google.protobuf.internal.cpp_message',
+ 'google.protobuf.internal.decoder',
+ 'google.protobuf.internal.encoder',
+ 'google.protobuf.internal.message_listener',
+ 'google.protobuf.internal.python_message',
+ 'google.protobuf.internal.type_checkers',
+ 'google.protobuf.internal.wire_format',
+ 'google.protobuf.descriptor',
+ 'google.protobuf.descriptor_pb2',
+ 'google.protobuf.compiler.plugin_pb2',
+ 'google.protobuf.message',
+ 'google.protobuf.reflection',
+ 'google.protobuf.service',
+ 'google.protobuf.service_reflection',
+ 'google.protobuf.text_format' ],
+ ext_modules = ext_module_list,
+ url = 'http://code.google.com/p/protobuf/',
+ maintainer = maintainer_email,
+ maintainer_email = 'protobuf@googlegroups.com',
+ license = 'New BSD License',
+ description = 'Protocol Buffers',
+ long_description =
+ "Protocol Buffers are Google's data interchange format.",
+ )
diff --git a/src/third_party/protobuf/python/stubout.py b/src/third_party/protobuf/python/stubout.py
new file mode 100755
index 0000000..aee4f2d
--- /dev/null
+++ b/src/third_party/protobuf/python/stubout.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python2.4
+#
+# Copyright 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This file is used for testing. The original is at:
+# http://code.google.com/p/pymox/
+
+class StubOutForTesting:
+ """Sample Usage:
+ You want os.path.exists() to always return true during testing.
+
+ stubs = StubOutForTesting()
+ stubs.Set(os.path, 'exists', lambda x: 1)
+ ...
+ stubs.UnsetAll()
+
+ The above changes os.path.exists into a lambda that returns 1. Once
+ the ... part of the code finishes, the UnsetAll() looks up the old value
+ of os.path.exists and restores it.
+
+ """
+ def __init__(self):
+ self.cache = []
+ self.stubs = []
+
+ def __del__(self):
+ self.SmartUnsetAll()
+ self.UnsetAll()
+
+ def SmartSet(self, obj, attr_name, new_attr):
+ """Replace obj.attr_name with new_attr. This method is smart and works
+ at the module, class, and instance level while preserving proper
+ inheritance. It will not stub out C types however unless that has been
+ explicitly allowed by the type.
+
+ This method supports the case where attr_name is a staticmethod or a
+ classmethod of obj.
+
+ Notes:
+ - If obj is an instance, then it is its class that will actually be
+ stubbed. Note that the method Set() does not do that: if obj is
+ an instance, it (and not its class) will be stubbed.
+ - The stubbing is using the builtin getattr and setattr. So, the __get__
+ and __set__ will be called when stubbing (TODO: A better idea would
+ probably be to manipulate obj.__dict__ instead of getattr() and
+ setattr()).
+
+ Raises AttributeError if the attribute cannot be found.
+ """
+ if (inspect.ismodule(obj) or
+ (not inspect.isclass(obj) and obj.__dict__.has_key(attr_name))):
+ orig_obj = obj
+ orig_attr = getattr(obj, attr_name)
+
+ else:
+ if not inspect.isclass(obj):
+ mro = list(inspect.getmro(obj.__class__))
+ else:
+ mro = list(inspect.getmro(obj))
+
+ mro.reverse()
+
+ orig_attr = None
+
+ for cls in mro:
+ try:
+ orig_obj = cls
+ orig_attr = getattr(obj, attr_name)
+ except AttributeError:
+ continue
+
+ if orig_attr is None:
+ raise AttributeError("Attribute not found.")
+
+ # Calling getattr() on a staticmethod transforms it to a 'normal' function.
+ # We need to ensure that we put it back as a staticmethod.
+ old_attribute = obj.__dict__.get(attr_name)
+ if old_attribute is not None and isinstance(old_attribute, staticmethod):
+ orig_attr = staticmethod(orig_attr)
+
+ self.stubs.append((orig_obj, attr_name, orig_attr))
+ setattr(orig_obj, attr_name, new_attr)
+
+ def SmartUnsetAll(self):
+ """Reverses all the SmartSet() calls, restoring things to their original
+ definition. Its okay to call SmartUnsetAll() repeatedly, as later calls
+ have no effect if no SmartSet() calls have been made.
+
+ """
+ self.stubs.reverse()
+
+ for args in self.stubs:
+ setattr(*args)
+
+ self.stubs = []
+
+ def Set(self, parent, child_name, new_child):
+ """Replace child_name's old definition with new_child, in the context
+ of the given parent. The parent could be a module when the child is a
+ function at module scope. Or the parent could be a class when a class'
+ method is being replaced. The named child is set to new_child, while
+ the prior definition is saved away for later, when UnsetAll() is called.
+
+ This method supports the case where child_name is a staticmethod or a
+ classmethod of parent.
+ """
+ old_child = getattr(parent, child_name)
+
+ old_attribute = parent.__dict__.get(child_name)
+ if old_attribute is not None and isinstance(old_attribute, staticmethod):
+ old_child = staticmethod(old_child)
+
+ self.cache.append((parent, old_child, child_name))
+ setattr(parent, child_name, new_child)
+
+ def UnsetAll(self):
+ """Reverses all the Set() calls, restoring things to their original
+ definition. Its okay to call UnsetAll() repeatedly, as later calls have
+ no effect if no Set() calls have been made.
+
+ """
+ # Undo calls to Set() in reverse order, in case Set() was called on the
+ # same arguments repeatedly (want the original call to be last one undone)
+ self.cache.reverse()
+
+ for (parent, old_child, child_name) in self.cache:
+ setattr(parent, child_name, old_child)
+ self.cache = []
diff --git a/src/third_party/protobuf/src/Makefile.am b/src/third_party/protobuf/src/Makefile.am
new file mode 100644
index 0000000..db9e7af
--- /dev/null
+++ b/src/third_party/protobuf/src/Makefile.am
@@ -0,0 +1,371 @@
+## Process this file with automake to produce Makefile.in
+
+if HAVE_ZLIB
+GZCHECKPROGRAMS = zcgzip zcgunzip
+GZHEADERS = google/protobuf/io/gzip_stream.h
+GZTESTS = google/protobuf/io/gzip_stream_unittest.sh
+else
+GZCHECKPROGRAMS =
+GZHEADERS =
+GZTESTS =
+endif
+
+if GCC
+# These are good warnings to turn on by default
+NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+else
+NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS)
+endif
+
+AM_CXXFLAGS = $(NO_OPT_CXXFLAGS) $(PROTOBUF_OPT_FLAG)
+
+AM_LDFLAGS = $(PTHREAD_CFLAGS)
+
+# If I say "dist_include_DATA", automake complains that $(includedir) is not
+# a "legitimate" directory for DATA. Screw you, automake.
+protodir = $(includedir)
+nobase_dist_proto_DATA = google/protobuf/descriptor.proto \
+ google/protobuf/compiler/plugin.proto
+
+# Not sure why these don't get cleaned automatically.
+clean-local:
+ rm -f *.loT
+
+CLEANFILES = $(protoc_outputs) unittest_proto_middleman \
+ testzip.jar testzip.list testzip.proto testzip.zip
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
+
+nobase_include_HEADERS = \
+ google/protobuf/stubs/atomicops.h \
+ google/protobuf/stubs/atomicops_internals_arm_gcc.h \
+ google/protobuf/stubs/atomicops_internals_macosx.h \
+ google/protobuf/stubs/atomicops_internals_mips_gcc.h \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.h \
+ google/protobuf/stubs/atomicops_internals_x86_msvc.h \
+ google/protobuf/stubs/common.h \
+ google/protobuf/stubs/platform_macros.h \
+ google/protobuf/stubs/once.h \
+ google/protobuf/descriptor.h \
+ google/protobuf/descriptor.pb.h \
+ google/protobuf/descriptor_database.h \
+ google/protobuf/dynamic_message.h \
+ google/protobuf/extension_set.h \
+ google/protobuf/generated_message_util.h \
+ google/protobuf/generated_message_reflection.h \
+ google/protobuf/message.h \
+ google/protobuf/message_lite.h \
+ google/protobuf/reflection_ops.h \
+ google/protobuf/repeated_field.h \
+ google/protobuf/service.h \
+ google/protobuf/text_format.h \
+ google/protobuf/unknown_field_set.h \
+ google/protobuf/wire_format.h \
+ google/protobuf/wire_format_lite.h \
+ google/protobuf/wire_format_lite_inl.h \
+ google/protobuf/io/coded_stream.h \
+ $(GZHEADERS) \
+ google/protobuf/io/printer.h \
+ google/protobuf/io/tokenizer.h \
+ google/protobuf/io/zero_copy_stream.h \
+ google/protobuf/io/zero_copy_stream_impl.h \
+ google/protobuf/io/zero_copy_stream_impl_lite.h \
+ google/protobuf/compiler/code_generator.h \
+ google/protobuf/compiler/command_line_interface.h \
+ google/protobuf/compiler/importer.h \
+ google/protobuf/compiler/parser.h \
+ google/protobuf/compiler/plugin.h \
+ google/protobuf/compiler/plugin.pb.h \
+ google/protobuf/compiler/cpp/cpp_generator.h \
+ google/protobuf/compiler/java/java_generator.h \
+ google/protobuf/compiler/python/python_generator.h
+
+lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
+
+libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS)
+libprotobuf_lite_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
+libprotobuf_lite_la_SOURCES = \
+ google/protobuf/stubs/atomicops_internals_x86_gcc.cc \
+ google/protobuf/stubs/common.cc \
+ google/protobuf/stubs/once.cc \
+ google/protobuf/stubs/hash.h \
+ google/protobuf/stubs/map-util.h \
+ google/protobuf/stubs/stl_util-inl.h \
+ google/protobuf/extension_set.cc \
+ google/protobuf/generated_message_util.cc \
+ google/protobuf/message_lite.cc \
+ google/protobuf/repeated_field.cc \
+ google/protobuf/wire_format_lite.cc \
+ google/protobuf/io/coded_stream.cc \
+ google/protobuf/io/coded_stream_inl.h \
+ google/protobuf/io/zero_copy_stream.cc \
+ google/protobuf/io/zero_copy_stream_impl_lite.cc
+
+libprotobuf_la_LIBADD = $(PTHREAD_LIBS)
+libprotobuf_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
+libprotobuf_la_SOURCES = \
+ $(libprotobuf_lite_la_SOURCES) \
+ google/protobuf/stubs/strutil.cc \
+ google/protobuf/stubs/strutil.h \
+ google/protobuf/stubs/substitute.cc \
+ google/protobuf/stubs/substitute.h \
+ google/protobuf/stubs/structurally_valid.cc \
+ google/protobuf/descriptor.cc \
+ google/protobuf/descriptor.pb.cc \
+ google/protobuf/descriptor_database.cc \
+ google/protobuf/dynamic_message.cc \
+ google/protobuf/extension_set_heavy.cc \
+ google/protobuf/generated_message_reflection.cc \
+ google/protobuf/message.cc \
+ google/protobuf/reflection_ops.cc \
+ google/protobuf/service.cc \
+ google/protobuf/text_format.cc \
+ google/protobuf/unknown_field_set.cc \
+ google/protobuf/wire_format.cc \
+ google/protobuf/io/gzip_stream.cc \
+ google/protobuf/io/printer.cc \
+ google/protobuf/io/tokenizer.cc \
+ google/protobuf/io/zero_copy_stream_impl.cc \
+ google/protobuf/compiler/importer.cc \
+ google/protobuf/compiler/parser.cc
+
+libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
+libprotoc_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined
+libprotoc_la_SOURCES = \
+ google/protobuf/compiler/code_generator.cc \
+ google/protobuf/compiler/command_line_interface.cc \
+ google/protobuf/compiler/plugin.cc \
+ google/protobuf/compiler/plugin.pb.cc \
+ google/protobuf/compiler/subprocess.cc \
+ google/protobuf/compiler/subprocess.h \
+ google/protobuf/compiler/zip_writer.cc \
+ google/protobuf/compiler/zip_writer.h \
+ google/protobuf/compiler/cpp/cpp_enum.cc \
+ google/protobuf/compiler/cpp/cpp_enum.h \
+ google/protobuf/compiler/cpp/cpp_enum_field.cc \
+ google/protobuf/compiler/cpp/cpp_enum_field.h \
+ google/protobuf/compiler/cpp/cpp_extension.cc \
+ google/protobuf/compiler/cpp/cpp_extension.h \
+ google/protobuf/compiler/cpp/cpp_field.cc \
+ google/protobuf/compiler/cpp/cpp_field.h \
+ google/protobuf/compiler/cpp/cpp_file.cc \
+ google/protobuf/compiler/cpp/cpp_file.h \
+ google/protobuf/compiler/cpp/cpp_generator.cc \
+ google/protobuf/compiler/cpp/cpp_helpers.cc \
+ google/protobuf/compiler/cpp/cpp_helpers.h \
+ google/protobuf/compiler/cpp/cpp_message.cc \
+ google/protobuf/compiler/cpp/cpp_message.h \
+ google/protobuf/compiler/cpp/cpp_message_field.cc \
+ google/protobuf/compiler/cpp/cpp_message_field.h \
+ google/protobuf/compiler/cpp/cpp_primitive_field.cc \
+ google/protobuf/compiler/cpp/cpp_primitive_field.h \
+ google/protobuf/compiler/cpp/cpp_service.cc \
+ google/protobuf/compiler/cpp/cpp_service.h \
+ google/protobuf/compiler/cpp/cpp_string_field.cc \
+ google/protobuf/compiler/cpp/cpp_string_field.h \
+ google/protobuf/compiler/java/java_enum.cc \
+ google/protobuf/compiler/java/java_enum.h \
+ google/protobuf/compiler/java/java_enum_field.cc \
+ google/protobuf/compiler/java/java_enum_field.h \
+ google/protobuf/compiler/java/java_extension.cc \
+ google/protobuf/compiler/java/java_extension.h \
+ google/protobuf/compiler/java/java_field.cc \
+ google/protobuf/compiler/java/java_field.h \
+ google/protobuf/compiler/java/java_file.cc \
+ google/protobuf/compiler/java/java_file.h \
+ google/protobuf/compiler/java/java_generator.cc \
+ google/protobuf/compiler/java/java_helpers.cc \
+ google/protobuf/compiler/java/java_helpers.h \
+ google/protobuf/compiler/java/java_message.cc \
+ google/protobuf/compiler/java/java_message.h \
+ google/protobuf/compiler/java/java_message_field.cc \
+ google/protobuf/compiler/java/java_message_field.h \
+ google/protobuf/compiler/java/java_primitive_field.cc \
+ google/protobuf/compiler/java/java_primitive_field.h \
+ google/protobuf/compiler/java/java_service.cc \
+ google/protobuf/compiler/java/java_service.h \
+ google/protobuf/compiler/java/java_string_field.cc \
+ google/protobuf/compiler/java/java_string_field.h \
+ google/protobuf/compiler/python/python_generator.cc
+
+bin_PROGRAMS = protoc
+protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la
+protoc_SOURCES = google/protobuf/compiler/main.cc
+
+# Tests ==============================================================
+
+protoc_inputs = \
+ google/protobuf/unittest.proto \
+ google/protobuf/unittest_empty.proto \
+ google/protobuf/unittest_import.proto \
+ google/protobuf/unittest_mset.proto \
+ google/protobuf/unittest_optimize_for.proto \
+ google/protobuf/unittest_embed_optimize_for.proto \
+ google/protobuf/unittest_custom_options.proto \
+ google/protobuf/unittest_lite.proto \
+ google/protobuf/unittest_import_lite.proto \
+ google/protobuf/unittest_lite_imports_nonlite.proto \
+ google/protobuf/unittest_no_generic_services.proto \
+ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
+
+EXTRA_DIST = \
+ $(protoc_inputs) \
+ solaris/libstdc++.la \
+ google/protobuf/io/gzip_stream.h \
+ google/protobuf/io/gzip_stream_unittest.sh \
+ google/protobuf/testdata/golden_message \
+ google/protobuf/testdata/golden_packed_fields_message \
+ google/protobuf/testdata/text_format_unittest_data.txt \
+ google/protobuf/testdata/text_format_unittest_extensions_data.txt \
+ google/protobuf/package_info.h \
+ google/protobuf/io/package_info.h \
+ google/protobuf/compiler/package_info.h \
+ google/protobuf/compiler/zip_output_unittest.sh \
+ google/protobuf/unittest_enormous_descriptor.proto
+
+protoc_lite_outputs = \
+ google/protobuf/unittest_lite.pb.cc \
+ google/protobuf/unittest_lite.pb.h \
+ google/protobuf/unittest_import_lite.pb.cc \
+ google/protobuf/unittest_import_lite.pb.h
+
+protoc_outputs = \
+ $(protoc_lite_outputs) \
+ google/protobuf/unittest.pb.cc \
+ google/protobuf/unittest.pb.h \
+ google/protobuf/unittest_empty.pb.cc \
+ google/protobuf/unittest_empty.pb.h \
+ google/protobuf/unittest_import.pb.cc \
+ google/protobuf/unittest_import.pb.h \
+ google/protobuf/unittest_mset.pb.cc \
+ google/protobuf/unittest_mset.pb.h \
+ google/protobuf/unittest_optimize_for.pb.cc \
+ google/protobuf/unittest_optimize_for.pb.h \
+ google/protobuf/unittest_embed_optimize_for.pb.cc \
+ google/protobuf/unittest_embed_optimize_for.pb.h \
+ google/protobuf/unittest_custom_options.pb.cc \
+ google/protobuf/unittest_custom_options.pb.h \
+ google/protobuf/unittest_lite_imports_nonlite.pb.cc \
+ google/protobuf/unittest_lite_imports_nonlite.pb.h \
+ google/protobuf/unittest_no_generic_services.pb.cc \
+ google/protobuf/unittest_no_generic_services.pb.h \
+ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \
+ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h
+
+BUILT_SOURCES = $(protoc_outputs)
+
+if USE_EXTERNAL_PROTOC
+
+unittest_proto_middleman: $(protoc_inputs)
+ $(PROTOC) -I$(srcdir) --cpp_out=. $^
+ touch unittest_proto_middleman
+
+else
+
+# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
+# relative to srcdir, which may not be the same as the current directory when
+# building out-of-tree.
+unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs)
+ oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) )
+ touch unittest_proto_middleman
+
+endif
+
+$(protoc_outputs): unittest_proto_middleman
+
+COMMON_TEST_SOURCES = \
+ google/protobuf/test_util.cc \
+ google/protobuf/test_util.h \
+ google/protobuf/testing/googletest.cc \
+ google/protobuf/testing/googletest.h \
+ google/protobuf/testing/file.cc \
+ google/protobuf/testing/file.h
+
+check_PROGRAMS = protoc protobuf-test protobuf-lazy-descriptor-test \
+ protobuf-lite-test test_plugin $(GZCHECKPROGRAMS)
+protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
+ $(top_builddir)/gtest/lib/libgtest.la \
+ $(top_builddir)/gtest/lib/libgtest_main.la
+protobuf_test_CPPFLAGS = -I$(top_srcdir)/gtest/include \
+ -I$(top_builddir)/gtest/include
+# Disable optimization for tests unless the user explicitly asked for it,
+# since test_util.cc takes forever to compile with optimization (with GCC).
+# See configure.ac for more info.
+protobuf_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_test_SOURCES = \
+ google/protobuf/stubs/common_unittest.cc \
+ google/protobuf/stubs/once_unittest.cc \
+ google/protobuf/stubs/strutil_unittest.cc \
+ google/protobuf/stubs/structurally_valid_unittest.cc \
+ google/protobuf/descriptor_database_unittest.cc \
+ google/protobuf/descriptor_unittest.cc \
+ google/protobuf/dynamic_message_unittest.cc \
+ google/protobuf/extension_set_unittest.cc \
+ google/protobuf/generated_message_reflection_unittest.cc \
+ google/protobuf/message_unittest.cc \
+ google/protobuf/reflection_ops_unittest.cc \
+ google/protobuf/repeated_field_unittest.cc \
+ google/protobuf/text_format_unittest.cc \
+ google/protobuf/unknown_field_set_unittest.cc \
+ google/protobuf/wire_format_unittest.cc \
+ google/protobuf/io/coded_stream_unittest.cc \
+ google/protobuf/io/printer_unittest.cc \
+ google/protobuf/io/tokenizer_unittest.cc \
+ google/protobuf/io/zero_copy_stream_unittest.cc \
+ google/protobuf/compiler/command_line_interface_unittest.cc \
+ google/protobuf/compiler/importer_unittest.cc \
+ google/protobuf/compiler/mock_code_generator.cc \
+ google/protobuf/compiler/mock_code_generator.h \
+ google/protobuf/compiler/parser_unittest.cc \
+ google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc \
+ google/protobuf/compiler/cpp/cpp_unittest.cc \
+ google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \
+ google/protobuf/compiler/java/java_plugin_unittest.cc \
+ google/protobuf/compiler/python/python_plugin_unittest.cc \
+ $(COMMON_TEST_SOURCES)
+nodist_protobuf_test_SOURCES = $(protoc_outputs)
+
+# Run cpp_unittest again with PROTOBUF_TEST_NO_DESCRIPTORS defined.
+protobuf_lazy_descriptor_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \
+ $(top_builddir)/gtest/lib/libgtest.la \
+ $(top_builddir)/gtest/lib/libgtest_main.la
+protobuf_lazy_descriptor_test_CPPFLAGS = -I$(top_srcdir)/gtest/include \
+ -I$(top_builddir)/gtest/include \
+ -DPROTOBUF_TEST_NO_DESCRIPTORS
+protobuf_lazy_descriptor_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_lazy_descriptor_test_SOURCES = \
+ google/protobuf/compiler/cpp/cpp_unittest.cc \
+ $(COMMON_TEST_SOURCES)
+nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs)
+
+# Build lite_unittest separately, since it doesn't use gtest.
+protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la
+protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_lite_test_SOURCES = \
+ google/protobuf/lite_unittest.cc \
+ google/protobuf/test_util_lite.cc \
+ google/protobuf/test_util_lite.h
+nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs)
+
+# Test plugin binary.
+test_plugin_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
+ $(top_builddir)/gtest/lib/libgtest.la
+test_plugin_CPPFLAGS = -I$(top_srcdir)/gtest/include \
+ -I$(top_builddir)/gtest/include
+test_plugin_SOURCES = \
+ google/protobuf/compiler/mock_code_generator.cc \
+ google/protobuf/testing/file.cc \
+ google/protobuf/testing/file.h \
+ google/protobuf/compiler/test_plugin.cc
+
+if HAVE_ZLIB
+zcgzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la
+zcgzip_SOURCES = google/protobuf/testing/zcgzip.cc
+
+zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la
+zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc
+endif
+
+TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \
+ google/protobuf/compiler/zip_output_unittest.sh $(GZTESTS)
diff --git a/src/third_party/protobuf/src/google/protobuf/SEBS b/src/third_party/protobuf/src/google/protobuf/SEBS
new file mode 100644
index 0000000..ba33c73
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/SEBS
@@ -0,0 +1,240 @@
+# **EXPERIMENTAL**
+#
+# See http://sebs.googlecode.com
+#
+# This is an experimental build definition file using the SEBS build system.
+# I (Kenton Varda, maintainer of Protocol Buffers) happen to be the author of
+# SEBS, though SEBS is not a Google project. I'm sticking this file in
+# protobuf's SVN because that's the easiest place for me to put it, and it
+# shouldn't harm anyone. This file is not included in the distribution.
+#
+# Currently, to use this file, you must generate config.h and put it at the
+# top level of the source tree.
+
+_cpp = sebs.import_("//sebs/cpp.sebs")
+
+# ====================================================================
+# Public targets
+
+protobuf_lite = _cpp.Library(
+ name = "protobuf-lite",
+ srcs = [ "stubs/common.cc",
+ "stubs/once.cc",
+ "stubs/hash.cc",
+ "stubs/hash.h",
+ "stubs/map-util.h",
+ "stubs/stl_util-inl.h",
+ "extension_set.cc",
+ "generated_message_util.cc",
+ "message_lite.cc",
+ "repeated_field.cc",
+ "wire_format_lite.cc",
+ "io/coded_stream.cc",
+ "io/zero_copy_stream.cc",
+ "io/zero_copy_stream_impl_lite.cc" ],
+ deps = [ _cpp.SystemLibrary(name = "pthread") ])
+
+protobuf = _cpp.Library(
+ name = "protobuf",
+ srcs = [ "stubs/strutil.cc",
+ "stubs/strutil.h",
+ "stubs/substitute.cc",
+ "stubs/substitute.h",
+ "stubs/structurally_valid.cc",
+ "descriptor.cc",
+ "descriptor.pb.cc",
+ "descriptor_database.cc",
+ "dynamic_message.cc",
+ "extension_set_heavy.cc",
+ "generated_message_reflection.cc",
+ "message.cc",
+ "reflection_ops.cc",
+ "service.cc",
+ "text_format.cc",
+ "unknown_field_set.cc",
+ "wire_format.cc",
+ "io/gzip_stream.cc",
+ "io/printer.cc",
+ "io/tokenizer.cc",
+ "io/zero_copy_stream_impl.cc",
+ "compiler/importer.cc",
+ "compiler/parser.cc" ],
+ deps = [ protobuf_lite,
+ _cpp.SystemLibrary(name = "z") ])
+
+libprotoc = _cpp.Library(
+ name = "protoc",
+ srcs = [ "compiler/code_generator.cc",
+ "compiler/command_line_interface.cc",
+ "compiler/cpp/cpp_enum.cc",
+ "compiler/cpp/cpp_enum.h",
+ "compiler/cpp/cpp_enum_field.cc",
+ "compiler/cpp/cpp_enum_field.h",
+ "compiler/cpp/cpp_extension.cc",
+ "compiler/cpp/cpp_extension.h",
+ "compiler/cpp/cpp_field.cc",
+ "compiler/cpp/cpp_field.h",
+ "compiler/cpp/cpp_file.cc",
+ "compiler/cpp/cpp_file.h",
+ "compiler/cpp/cpp_generator.cc",
+ "compiler/cpp/cpp_helpers.cc",
+ "compiler/cpp/cpp_helpers.h",
+ "compiler/cpp/cpp_message.cc",
+ "compiler/cpp/cpp_message.h",
+ "compiler/cpp/cpp_message_field.cc",
+ "compiler/cpp/cpp_message_field.h",
+ "compiler/cpp/cpp_primitive_field.cc",
+ "compiler/cpp/cpp_primitive_field.h",
+ "compiler/cpp/cpp_service.cc",
+ "compiler/cpp/cpp_service.h",
+ "compiler/cpp/cpp_string_field.cc",
+ "compiler/cpp/cpp_string_field.h",
+ "compiler/java/java_enum.cc",
+ "compiler/java/java_enum.h",
+ "compiler/java/java_enum_field.cc",
+ "compiler/java/java_enum_field.h",
+ "compiler/java/java_extension.cc",
+ "compiler/java/java_extension.h",
+ "compiler/java/java_field.cc",
+ "compiler/java/java_field.h",
+ "compiler/java/java_file.cc",
+ "compiler/java/java_file.h",
+ "compiler/java/java_generator.cc",
+ "compiler/java/java_helpers.cc",
+ "compiler/java/java_helpers.h",
+ "compiler/java/java_message.cc",
+ "compiler/java/java_message.h",
+ "compiler/java/java_message_field.cc",
+ "compiler/java/java_message_field.h",
+ "compiler/java/java_primitive_field.cc",
+ "compiler/java/java_primitive_field.h",
+ "compiler/java/java_service.cc",
+ "compiler/java/java_service.h",
+ "compiler/python/python_generator.cc" ],
+ deps = [ protobuf ])
+
+protoc = _cpp.Binary(
+ name = "protoc",
+ srcs = [ "compiler/main.cc" ],
+ deps = [ libprotoc ])
+
+# ====================================================================
+# ProtobufLibrary rule class
+
+class ProtobufLibrary(sebs.Rule):
+ argument_spec = sebs.ArgumentSpec(srcs = [sebs.Artifact],
+ deps = ([sebs.Rule], []),
+ lite = (bool, False))
+
+ def _expand(self, args):
+ for dep in args.deps:
+ if not isinstance(dep, ProtobufLibrary):
+ raise sebs.DefinitionError(
+ "Dependency of ProtobufLibrary is not a ProtobufLibrary: %s" % dep)
+
+ protoc.expand_once()
+
+ # We must build protoc for the host configuration to allow cross-compiling.
+ host_protoc = self.context.configured_artifact(protoc.binary, "host")
+
+ protoc_action = self.context.action(self, "protobuf")
+ protoc_args = [host_protoc, "-Isrc", "-Itmp", "-Iinclude","--cpp_out=tmp"]
+
+ cpp_srcs = []
+ for src in args.srcs:
+ protoc_args.append(src)
+
+ # We cannot build .proto files from other packages because the .pb.cc
+ # and .pb.h files would be written to that package, and we aren't allowed
+ # to write to other packages.
+ if self.context.local_filename(src) is None:
+ raise sebs.DefinitionError(
+ "Source file is not in this package: %s" % src)
+
+ cc_artifact = self.context.derived_artifact(src, ".pb.cc", protoc_action)
+ header_artifact = self.context.derived_artifact(
+ src, ".pb.h", protoc_action)
+
+ cpp_srcs.append(cc_artifact)
+ cpp_srcs.append(header_artifact)
+
+ protoc_action.set_command(
+ sebs.SubprocessCommand(protoc_action, protoc_args, implicit = cpp_srcs))
+
+ deps = list(args.deps)
+ if args.lite:
+ deps.append(protobuf_lite)
+ else:
+ deps.append(protobuf)
+
+ self.__cpp_library = _cpp.Library(srcs = cpp_srcs, deps = deps,
+ context = self.context)
+ self.__cpp_library.label = self.label
+ self.outputs = []
+
+ def as_cpp_library(self):
+ self.expand_once()
+ return self.__cpp_library
+
+# ====================================================================
+# Tests
+
+_lite_test_protos = ProtobufLibrary(
+ srcs = [ "unittest_lite.proto",
+ "unittest_import_lite.proto" ],
+ lite = True)
+_test_protos = ProtobufLibrary(
+ srcs = [ "unittest.proto",
+ "unittest_empty.proto",
+ "unittest_import.proto",
+ "unittest_mset.proto",
+ "unittest_optimize_for.proto",
+ "unittest_embed_optimize_for.proto",
+ "unittest_custom_options.proto",
+ "unittest_lite_imports_nonlite.proto",
+ "compiler/cpp/cpp_test_bad_identifiers.proto" ],
+ deps = [ _lite_test_protos ])
+
+_test_util = _cpp.Library(
+ name = "test_util",
+ srcs = [ "test_util.cc",
+ "test_util.h",
+ "testing/googletest.cc",
+ "testing/googletest.h",
+ "testing/file.cc",
+ "testing/file.h" ],
+ deps = [ protobuf, _test_protos, _cpp.SystemLibrary(name = "gtest")] )
+
+protobuf_lite_test = _cpp.Test(
+ srcs = [ "lite_unittest.cc",
+ "test_util_lite.cc",
+ "test_util_lite.h" ],
+ deps = [ _lite_test_protos ])
+
+protobuf_test = _cpp.Test(
+ srcs = [ "stubs/common_unittest.cc",
+ "stubs/once_unittest.cc",
+ "stubs/strutil_unittest.cc",
+ "stubs/structurally_valid_unittest.cc",
+ "descriptor_database_unittest.cc",
+ "descriptor_unittest.cc",
+ "dynamic_message_unittest.cc",
+ "extension_set_unittest.cc",
+ "generated_message_reflection_unittest.cc",
+ "message_unittest.cc",
+ "reflection_ops_unittest.cc",
+ "repeated_field_unittest.cc",
+ "text_format_unittest.cc",
+ "unknown_field_set_unittest.cc",
+ "wire_format_unittest.cc",
+ "io/coded_stream_unittest.cc",
+ "io/printer_unittest.cc",
+ "io/tokenizer_unittest.cc",
+ "io/zero_copy_stream_unittest.cc",
+ "compiler/command_line_interface_unittest.cc",
+ "compiler/importer_unittest.cc",
+ "compiler/parser_unittest.cc",
+ "compiler/cpp/cpp_bootstrap_unittest.cc",
+ "compiler/cpp/cpp_unittest.cc" ],
+ deps = [ protobuf, libprotoc, _test_util,
+ _cpp.SystemLibrary(name = "gtest_main") ])
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc b/src/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc
new file mode 100644
index 0000000..455c239
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/code_generator.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+CodeGenerator::~CodeGenerator() {}
+GeneratorContext::~GeneratorContext() {}
+
+io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert(
+ const string& filename, const string& insertion_point) {
+ GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion.";
+ return NULL; // make compiler happy
+}
+
+void GeneratorContext::ListParsedFiles(
+ vector<const FileDescriptor*>* output) {
+ GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
+}
+
+// Parses a set of comma-delimited name/value pairs.
+void ParseGeneratorParameter(const string& text,
+ vector<pair<string, string> >* output) {
+ vector<string> parts;
+ SplitStringUsing(text, ",", &parts);
+
+ for (int i = 0; i < parts.size(); i++) {
+ string::size_type equals_pos = parts[i].find_first_of('=');
+ pair<string, string> value;
+ if (equals_pos == string::npos) {
+ value.first = parts[i];
+ value.second = "";
+ } else {
+ value.first = parts[i].substr(0, equals_pos);
+ value.second = parts[i].substr(equals_pos + 1);
+ }
+ output->push_back(value);
+ }
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/code_generator.h b/src/third_party/protobuf/src/google/protobuf/compiler/code_generator.h
new file mode 100644
index 0000000..252f68d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/code_generator.h
@@ -0,0 +1,142 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines the abstract interface implemented by each of the language-specific
+// code generators.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
+
+#include <google/protobuf/stubs/common.h>
+#include <string>
+#include <vector>
+#include <utility>
+
+namespace google {
+namespace protobuf {
+
+namespace io { class ZeroCopyOutputStream; }
+class FileDescriptor;
+
+namespace compiler {
+
+// Defined in this file.
+class CodeGenerator;
+class GeneratorContext;
+
+// The abstract interface to a class which generates code implementing a
+// particular proto file in a particular language. A number of these may
+// be registered with CommandLineInterface to support various languages.
+class LIBPROTOC_EXPORT CodeGenerator {
+ public:
+ inline CodeGenerator() {}
+ virtual ~CodeGenerator();
+
+ // Generates code for the given proto file, generating one or more files in
+ // the given output directory.
+ //
+ // A parameter to be passed to the generator can be specified on the
+ // command line. This is intended to be used by Java and similar languages
+ // to specify which specific class from the proto file is to be generated,
+ // though it could have other uses as well. It is empty if no parameter was
+ // given.
+ //
+ // Returns true if successful. Otherwise, sets *error to a description of
+ // the problem (e.g. "invalid parameter") and returns false.
+ virtual bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* generator_context,
+ string* error) const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodeGenerator);
+};
+
+// CodeGenerators generate one or more files in a given directory. This
+// abstract interface represents the directory to which the CodeGenerator is
+// to write and other information about the context in which the Generator
+// runs.
+class LIBPROTOC_EXPORT GeneratorContext {
+ public:
+ inline GeneratorContext() {}
+ virtual ~GeneratorContext();
+
+ // Opens the given file, truncating it if it exists, and returns a
+ // ZeroCopyOutputStream that writes to the file. The caller takes ownership
+ // of the returned object. This method never fails (a dummy stream will be
+ // returned instead).
+ //
+ // The filename given should be relative to the root of the source tree.
+ // E.g. the C++ generator, when generating code for "foo/bar.proto", will
+ // generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that
+ // "foo/" is included in these filenames. The filename is not allowed to
+ // contain "." or ".." components.
+ virtual io::ZeroCopyOutputStream* Open(const string& filename) = 0;
+
+ // Creates a ZeroCopyOutputStream which will insert code into the given file
+ // at the given insertion point. See plugin.proto (plugin.pb.h) for more
+ // information on insertion points. The default implementation
+ // assert-fails -- it exists only for backwards-compatibility.
+ //
+ // WARNING: This feature is currently EXPERIMENTAL and is subject to change.
+ virtual io::ZeroCopyOutputStream* OpenForInsert(
+ const string& filename, const string& insertion_point);
+
+ // Returns a vector of FileDescriptors for all the files being compiled
+ // in this run. Useful for languages, such as Go, that treat files
+ // differently when compiled as a set rather than individually.
+ virtual void ListParsedFiles(vector<const FileDescriptor*>* output);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
+};
+
+// The type GeneratorContext was once called OutputDirectory. This typedef
+// provides backward compatibility.
+typedef GeneratorContext OutputDirectory;
+
+// Several code generators treat the parameter argument as holding a
+// list of options separated by commas. This helper function parses
+// a set of comma-delimited name/value pairs: e.g.,
+// "foo=bar,baz,qux=corge"
+// parses to the pairs:
+// ("foo", "bar"), ("baz", ""), ("qux", "corge")
+extern void ParseGeneratorParameter(const string&,
+ vector<pair<string, string> >*);
+
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc b/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc
new file mode 100644
index 0000000..c5be9b4
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc
@@ -0,0 +1,1357 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/command_line_interface.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef _MSC_VER
+#include <io.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <iostream>
+#include <ctype.h>
+
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/plugin.pb.h>
+#include <google/protobuf/compiler/subprocess.h>
+#include <google/protobuf/compiler/zip_writer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#if defined(_WIN32)
+#define mkdir(name, mode) mkdir(name)
+#ifndef W_OK
+#define W_OK 02 // not defined by MSVC for whatever reason
+#endif
+#ifndef F_OK
+#define F_OK 00 // not defined by MSVC for whatever reason
+#endif
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+namespace {
+#if defined(_WIN32) && !defined(__CYGWIN__)
+static const char* kPathSeparator = ";";
+#else
+static const char* kPathSeparator = ":";
+#endif
+
+// Returns true if the text looks like a Windows-style absolute path, starting
+// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with
+// copy in importer.cc?
+static bool IsWindowsAbsolutePath(const string& text) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ return text.size() >= 3 && text[1] == ':' &&
+ isalpha(text[0]) &&
+ (text[2] == '/' || text[2] == '\\') &&
+ text.find_last_of(':') == 1;
+#else
+ return false;
+#endif
+}
+
+void SetFdToTextMode(int fd) {
+#ifdef _WIN32
+ if (_setmode(fd, _O_TEXT) == -1) {
+ // This should never happen, I think.
+ GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_TEXT): " << strerror(errno);
+ }
+#endif
+ // (Text and binary are the same on non-Windows platforms.)
+}
+
+void SetFdToBinaryMode(int fd) {
+#ifdef _WIN32
+ if (_setmode(fd, _O_BINARY) == -1) {
+ // This should never happen, I think.
+ GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_BINARY): " << strerror(errno);
+ }
+#endif
+ // (Text and binary are the same on non-Windows platforms.)
+}
+
+void AddTrailingSlash(string* path) {
+ if (!path->empty() && path->at(path->size() - 1) != '/') {
+ path->push_back('/');
+ }
+}
+
+bool VerifyDirectoryExists(const string& path) {
+ if (path.empty()) return true;
+
+ if (access(path.c_str(), W_OK) == -1) {
+ cerr << path << ": " << strerror(errno) << endl;
+ return false;
+ } else {
+ return true;
+ }
+}
+
+// Try to create the parent directory of the given file, creating the parent's
+// parent if necessary, and so on. The full file name is actually
+// (prefix + filename), but we assume |prefix| already exists and only create
+// directories listed in |filename|.
+bool TryCreateParentDirectory(const string& prefix, const string& filename) {
+ // Recursively create parent directories to the output file.
+ vector<string> parts;
+ SplitStringUsing(filename, "/", &parts);
+ string path_so_far = prefix;
+ for (int i = 0; i < parts.size() - 1; i++) {
+ path_so_far += parts[i];
+ if (mkdir(path_so_far.c_str(), 0777) != 0) {
+ if (errno != EEXIST) {
+ cerr << filename << ": while trying to create directory "
+ << path_so_far << ": " << strerror(errno) << endl;
+ return false;
+ }
+ }
+ path_so_far += '/';
+ }
+
+ return true;
+}
+
+} // namespace
+
+// A MultiFileErrorCollector that prints errors to stderr.
+class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
+ public io::ErrorCollector {
+ public:
+ ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL)
+ : format_(format), tree_(tree) {}
+ ~ErrorPrinter() {}
+
+ // implements MultiFileErrorCollector ------------------------------
+ void AddError(const string& filename, int line, int column,
+ const string& message) {
+
+ // Print full path when running under MSVS
+ string dfile;
+ if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS &&
+ tree_ != NULL &&
+ tree_->VirtualFileToDiskFile(filename, &dfile)) {
+ cerr << dfile;
+ } else {
+ cerr << filename;
+ }
+
+ // Users typically expect 1-based line/column numbers, so we add 1
+ // to each here.
+ if (line != -1) {
+ // Allow for both GCC- and Visual-Studio-compatible output.
+ switch (format_) {
+ case CommandLineInterface::ERROR_FORMAT_GCC:
+ cerr << ":" << (line + 1) << ":" << (column + 1);
+ break;
+ case CommandLineInterface::ERROR_FORMAT_MSVS:
+ cerr << "(" << (line + 1) << ") : error in column=" << (column + 1);
+ break;
+ }
+ }
+
+ cerr << ": " << message << endl;
+ }
+
+ // implements io::ErrorCollector -----------------------------------
+ void AddError(int line, int column, const string& message) {
+ AddError("input", line, column, message);
+ }
+
+ private:
+ const ErrorFormat format_;
+ DiskSourceTree *tree_;
+};
+
+// -------------------------------------------------------------------
+
+// A GeneratorContext implementation that buffers files in memory, then dumps
+// them all to disk on demand.
+class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
+ public:
+ GeneratorContextImpl(const vector<const FileDescriptor*>& parsed_files);
+ ~GeneratorContextImpl();
+
+ // Write all files in the directory to disk at the given output location,
+ // which must end in a '/'.
+ bool WriteAllToDisk(const string& prefix);
+
+ // Write the contents of this directory to a ZIP-format archive with the
+ // given name.
+ bool WriteAllToZip(const string& filename);
+
+ // Add a boilerplate META-INF/MANIFEST.MF file as required by the Java JAR
+ // format, unless one has already been written.
+ void AddJarManifest();
+
+ // implements GeneratorContext --------------------------------------
+ io::ZeroCopyOutputStream* Open(const string& filename);
+ io::ZeroCopyOutputStream* OpenForInsert(
+ const string& filename, const string& insertion_point);
+ void ListParsedFiles(vector<const FileDescriptor*>* output) {
+ *output = parsed_files_;
+ }
+
+ private:
+ friend class MemoryOutputStream;
+
+ // map instead of hash_map so that files are written in order (good when
+ // writing zips).
+ map<string, string*> files_;
+ const vector<const FileDescriptor*>& parsed_files_;
+ bool had_error_;
+};
+
+class CommandLineInterface::MemoryOutputStream
+ : public io::ZeroCopyOutputStream {
+ public:
+ MemoryOutputStream(GeneratorContextImpl* directory, const string& filename);
+ MemoryOutputStream(GeneratorContextImpl* directory, const string& filename,
+ const string& insertion_point);
+ virtual ~MemoryOutputStream();
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ virtual bool Next(void** data, int* size) { return inner_->Next(data, size); }
+ virtual void BackUp(int count) { inner_->BackUp(count); }
+ virtual int64 ByteCount() const { return inner_->ByteCount(); }
+
+ private:
+ // Where to insert the string when it's done.
+ GeneratorContextImpl* directory_;
+ string filename_;
+ string insertion_point_;
+
+ // The string we're building.
+ string data_;
+
+ // StringOutputStream writing to data_.
+ scoped_ptr<io::StringOutputStream> inner_;
+};
+
+// -------------------------------------------------------------------
+
+CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl(
+ const vector<const FileDescriptor*>& parsed_files)
+ : parsed_files_(parsed_files),
+ had_error_(false) {
+}
+
+CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() {
+ STLDeleteValues(&files_);
+}
+
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
+ const string& prefix) {
+ if (had_error_) {
+ return false;
+ }
+
+ if (!VerifyDirectoryExists(prefix)) {
+ return false;
+ }
+
+ for (map<string, string*>::const_iterator iter = files_.begin();
+ iter != files_.end(); ++iter) {
+ const string& relative_filename = iter->first;
+ const char* data = iter->second->data();
+ int size = iter->second->size();
+
+ if (!TryCreateParentDirectory(prefix, relative_filename)) {
+ return false;
+ }
+ string filename = prefix + relative_filename;
+
+ // Create the output file.
+ int file_descriptor;
+ do {
+ file_descriptor =
+ open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ } while (file_descriptor < 0 && errno == EINTR);
+
+ if (file_descriptor < 0) {
+ int error = errno;
+ cerr << filename << ": " << strerror(error);
+ return false;
+ }
+
+ // Write the file.
+ while (size > 0) {
+ int write_result;
+ do {
+ write_result = write(file_descriptor, data, size);
+ } while (write_result < 0 && errno == EINTR);
+
+ if (write_result <= 0) {
+ // Write error.
+
+ // FIXME(kenton): According to the man page, if write() returns zero,
+ // there was no error; write() simply did not write anything. It's
+ // unclear under what circumstances this might happen, but presumably
+ // errno won't be set in this case. I am confused as to how such an
+ // event should be handled. For now I'm treating it as an error,
+ // since retrying seems like it could lead to an infinite loop. I
+ // suspect this never actually happens anyway.
+
+ if (write_result < 0) {
+ int error = errno;
+ cerr << filename << ": write: " << strerror(error);
+ } else {
+ cerr << filename << ": write() returned zero?" << endl;
+ }
+ return false;
+ }
+
+ data += write_result;
+ size -= write_result;
+ }
+
+ if (close(file_descriptor) != 0) {
+ int error = errno;
+ cerr << filename << ": close: " << strerror(error);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
+ const string& filename) {
+ if (had_error_) {
+ return false;
+ }
+
+ // Create the output file.
+ int file_descriptor;
+ do {
+ file_descriptor =
+ open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ } while (file_descriptor < 0 && errno == EINTR);
+
+ if (file_descriptor < 0) {
+ int error = errno;
+ cerr << filename << ": " << strerror(error);
+ return false;
+ }
+
+ // Create the ZipWriter
+ io::FileOutputStream stream(file_descriptor);
+ ZipWriter zip_writer(&stream);
+
+ for (map<string, string*>::const_iterator iter = files_.begin();
+ iter != files_.end(); ++iter) {
+ zip_writer.Write(iter->first, *iter->second);
+ }
+
+ zip_writer.WriteDirectory();
+
+ if (stream.GetErrno() != 0) {
+ cerr << filename << ": " << strerror(stream.GetErrno()) << endl;
+ }
+
+ if (!stream.Close()) {
+ cerr << filename << ": " << strerror(stream.GetErrno()) << endl;
+ }
+
+ return true;
+}
+
+void CommandLineInterface::GeneratorContextImpl::AddJarManifest() {
+ string** map_slot = &files_["META-INF/MANIFEST.MF"];
+ if (*map_slot == NULL) {
+ *map_slot = new string(
+ "Manifest-Version: 1.0\n"
+ "Created-By: 1.6.0 (protoc)\n"
+ "\n");
+ }
+}
+
+io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open(
+ const string& filename) {
+ return new MemoryOutputStream(this, filename);
+}
+
+io::ZeroCopyOutputStream*
+CommandLineInterface::GeneratorContextImpl::OpenForInsert(
+ const string& filename, const string& insertion_point) {
+ return new MemoryOutputStream(this, filename, insertion_point);
+}
+
+// -------------------------------------------------------------------
+
+CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
+ GeneratorContextImpl* directory, const string& filename)
+ : directory_(directory),
+ filename_(filename),
+ inner_(new io::StringOutputStream(&data_)) {
+}
+
+CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
+ GeneratorContextImpl* directory, const string& filename,
+ const string& insertion_point)
+ : directory_(directory),
+ filename_(filename),
+ insertion_point_(insertion_point),
+ inner_(new io::StringOutputStream(&data_)) {
+}
+
+CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
+ // Make sure all data has been written.
+ inner_.reset();
+
+ // Insert into the directory.
+ string** map_slot = &directory_->files_[filename_];
+
+ if (insertion_point_.empty()) {
+ // This was just a regular Open().
+ if (*map_slot != NULL) {
+ cerr << filename_ << ": Tried to write the same file twice." << endl;
+ directory_->had_error_ = true;
+ return;
+ }
+
+ *map_slot = new string;
+ (*map_slot)->swap(data_);
+ } else {
+ // This was an OpenForInsert().
+
+ // If the data doens't end with a clean line break, add one.
+ if (!data_.empty() && data_[data_.size() - 1] != '\n') {
+ data_.push_back('\n');
+ }
+
+ // Find the file we are going to insert into.
+ if (*map_slot == NULL) {
+ cerr << filename_ << ": Tried to insert into file that doesn't exist."
+ << endl;
+ directory_->had_error_ = true;
+ return;
+ }
+ string* target = *map_slot;
+
+ // Find the insertion point.
+ string magic_string = strings::Substitute(
+ "@@protoc_insertion_point($0)", insertion_point_);
+ string::size_type pos = target->find(magic_string);
+
+ if (pos == string::npos) {
+ cerr << filename_ << ": insertion point \"" << insertion_point_
+ << "\" not found." << endl;
+ directory_->had_error_ = true;
+ return;
+ }
+
+ // Seek backwards to the beginning of the line, which is where we will
+ // insert the data. Note that this has the effect of pushing the insertion
+ // point down, so the data is inserted before it. This is intentional
+ // because it means that multiple insertions at the same point will end
+ // up in the expected order in the final output.
+ pos = target->find_last_of('\n', pos);
+ if (pos == string::npos) {
+ // Insertion point is on the first line.
+ pos = 0;
+ } else {
+ // Advance to character after '\n'.
+ ++pos;
+ }
+
+ // Extract indent.
+ string indent_(*target, pos, target->find_first_not_of(" \t", pos) - pos);
+
+ if (indent_.empty()) {
+ // No indent. This makes things easier.
+ target->insert(pos, data_);
+ } else {
+ // Calculate how much space we need.
+ int indent_size = 0;
+ for (int i = 0; i < data_.size(); i++) {
+ if (data_[i] == '\n') indent_size += indent_.size();
+ }
+
+ // Make a hole for it.
+ target->insert(pos, data_.size() + indent_size, '\0');
+
+ // Now copy in the data.
+ string::size_type data_pos = 0;
+ char* target_ptr = string_as_array(target) + pos;
+ while (data_pos < data_.size()) {
+ // Copy indent.
+ memcpy(target_ptr, indent_.data(), indent_.size());
+ target_ptr += indent_.size();
+
+ // Copy line from data_.
+ // We already guaranteed that data_ ends with a newline (above), so this
+ // search can't fail.
+ string::size_type line_length =
+ data_.find_first_of('\n', data_pos) + 1 - data_pos;
+ memcpy(target_ptr, data_.data() + data_pos, line_length);
+ target_ptr += line_length;
+ data_pos += line_length;
+ }
+
+ GOOGLE_CHECK_EQ(target_ptr,
+ string_as_array(target) + pos + data_.size() + indent_size);
+ }
+ }
+}
+
+// ===================================================================
+
+CommandLineInterface::CommandLineInterface()
+ : mode_(MODE_COMPILE),
+ error_format_(ERROR_FORMAT_GCC),
+ imports_in_descriptor_set_(false),
+ disallow_services_(false),
+ inputs_are_proto_path_relative_(false) {}
+CommandLineInterface::~CommandLineInterface() {}
+
+void CommandLineInterface::RegisterGenerator(const string& flag_name,
+ CodeGenerator* generator,
+ const string& help_text) {
+ GeneratorInfo info;
+ info.generator = generator;
+ info.help_text = help_text;
+ generators_[flag_name] = info;
+}
+
+void CommandLineInterface::AllowPlugins(const string& exe_name_prefix) {
+ plugin_prefix_ = exe_name_prefix;
+}
+
+int CommandLineInterface::Run(int argc, const char* const argv[]) {
+ Clear();
+ if (!ParseArguments(argc, argv)) return 1;
+
+ // Set up the source tree.
+ DiskSourceTree source_tree;
+ for (int i = 0; i < proto_path_.size(); i++) {
+ source_tree.MapPath(proto_path_[i].first, proto_path_[i].second);
+ }
+
+ // Map input files to virtual paths if necessary.
+ if (!inputs_are_proto_path_relative_) {
+ if (!MakeInputsBeProtoPathRelative(&source_tree)) {
+ return 1;
+ }
+ }
+
+ // Allocate the Importer.
+ ErrorPrinter error_collector(error_format_, &source_tree);
+ Importer importer(&source_tree, &error_collector);
+
+ vector<const FileDescriptor*> parsed_files;
+
+ // Parse each file.
+ for (int i = 0; i < input_files_.size(); i++) {
+ // Import the file.
+ const FileDescriptor* parsed_file = importer.Import(input_files_[i]);
+ if (parsed_file == NULL) return 1;
+ parsed_files.push_back(parsed_file);
+
+ // Enforce --disallow_services.
+ if (disallow_services_ && parsed_file->service_count() > 0) {
+ cerr << parsed_file->name() << ": This file contains services, but "
+ "--disallow_services was used." << endl;
+ return 1;
+ }
+ }
+
+ // We construct a separate GeneratorContext for each output location. Note
+ // that two code generators may output to the same location, in which case
+ // they should share a single GeneratorContext so that OpenForInsert() works.
+ typedef hash_map<string, GeneratorContextImpl*> GeneratorContextMap;
+ GeneratorContextMap output_directories;
+
+ // Generate output.
+ if (mode_ == MODE_COMPILE) {
+ for (int i = 0; i < output_directives_.size(); i++) {
+ string output_location = output_directives_[i].output_location;
+ if (!HasSuffixString(output_location, ".zip") &&
+ !HasSuffixString(output_location, ".jar")) {
+ AddTrailingSlash(&output_location);
+ }
+ GeneratorContextImpl** map_slot = &output_directories[output_location];
+
+ if (*map_slot == NULL) {
+ // First time we've seen this output location.
+ *map_slot = new GeneratorContextImpl(parsed_files);
+ }
+
+ if (!GenerateOutput(parsed_files, output_directives_[i], *map_slot)) {
+ STLDeleteValues(&output_directories);
+ return 1;
+ }
+ }
+ }
+
+ // Write all output to disk.
+ for (GeneratorContextMap::iterator iter = output_directories.begin();
+ iter != output_directories.end(); ++iter) {
+ const string& location = iter->first;
+ GeneratorContextImpl* directory = iter->second;
+ if (HasSuffixString(location, "/")) {
+ if (!directory->WriteAllToDisk(location)) {
+ STLDeleteValues(&output_directories);
+ return 1;
+ }
+ } else {
+ if (HasSuffixString(location, ".jar")) {
+ directory->AddJarManifest();
+ }
+
+ if (!directory->WriteAllToZip(location)) {
+ STLDeleteValues(&output_directories);
+ return 1;
+ }
+ }
+ }
+
+ STLDeleteValues(&output_directories);
+
+ if (!descriptor_set_name_.empty()) {
+ if (!WriteDescriptorSet(parsed_files)) {
+ return 1;
+ }
+ }
+
+ if (mode_ == MODE_ENCODE || mode_ == MODE_DECODE) {
+ if (codec_type_.empty()) {
+ // HACK: Define an EmptyMessage type to use for decoding.
+ DescriptorPool pool;
+ FileDescriptorProto file;
+ file.set_name("empty_message.proto");
+ file.add_message_type()->set_name("EmptyMessage");
+ GOOGLE_CHECK(pool.BuildFile(file) != NULL);
+ codec_type_ = "EmptyMessage";
+ if (!EncodeOrDecode(&pool)) {
+ return 1;
+ }
+ } else {
+ if (!EncodeOrDecode(importer.pool())) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void CommandLineInterface::Clear() {
+ // Clear all members that are set by Run(). Note that we must not clear
+ // members which are set by other methods before Run() is called.
+ executable_name_.clear();
+ proto_path_.clear();
+ input_files_.clear();
+ output_directives_.clear();
+ codec_type_.clear();
+ descriptor_set_name_.clear();
+
+ mode_ = MODE_COMPILE;
+ imports_in_descriptor_set_ = false;
+ disallow_services_ = false;
+}
+
+bool CommandLineInterface::MakeInputsBeProtoPathRelative(
+ DiskSourceTree* source_tree) {
+ for (int i = 0; i < input_files_.size(); i++) {
+ string virtual_file, shadowing_disk_file;
+ switch (source_tree->DiskFileToVirtualFile(
+ input_files_[i], &virtual_file, &shadowing_disk_file)) {
+ case DiskSourceTree::SUCCESS:
+ input_files_[i] = virtual_file;
+ break;
+ case DiskSourceTree::SHADOWED:
+ cerr << input_files_[i] << ": Input is shadowed in the --proto_path "
+ "by \"" << shadowing_disk_file << "\". Either use the latter "
+ "file as your input or reorder the --proto_path so that the "
+ "former file's location comes first." << endl;
+ return false;
+ case DiskSourceTree::CANNOT_OPEN:
+ cerr << input_files_[i] << ": " << strerror(errno) << endl;
+ return false;
+ case DiskSourceTree::NO_MAPPING:
+ // First check if the file exists at all.
+ if (access(input_files_[i].c_str(), F_OK) < 0) {
+ // File does not even exist.
+ cerr << input_files_[i] << ": " << strerror(ENOENT) << endl;
+ } else {
+ cerr << input_files_[i] << ": File does not reside within any path "
+ "specified using --proto_path (or -I). You must specify a "
+ "--proto_path which encompasses this file. Note that the "
+ "proto_path must be an exact prefix of the .proto file "
+ "names -- protoc is too dumb to figure out when two paths "
+ "(e.g. absolute and relative) are equivalent (it's harder "
+ "than you think)." << endl;
+ }
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
+ executable_name_ = argv[0];
+
+ // Iterate through all arguments and parse them.
+ for (int i = 1; i < argc; i++) {
+ string name, value;
+
+ if (ParseArgument(argv[i], &name, &value)) {
+ // Returned true => Use the next argument as the flag value.
+ if (i + 1 == argc || argv[i+1][0] == '-') {
+ cerr << "Missing value for flag: " << name << endl;
+ if (name == "--decode") {
+ cerr << "To decode an unknown message, use --decode_raw." << endl;
+ }
+ return false;
+ } else {
+ ++i;
+ value = argv[i];
+ }
+ }
+
+ if (!InterpretArgument(name, value)) return false;
+ }
+
+ // If no --proto_path was given, use the current working directory.
+ if (proto_path_.empty()) {
+ proto_path_.push_back(make_pair<string, string>("", "."));
+ }
+
+ // Check some errror cases.
+ bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty();
+ if (decoding_raw && !input_files_.empty()) {
+ cerr << "When using --decode_raw, no input files should be given." << endl;
+ return false;
+ } else if (!decoding_raw && input_files_.empty()) {
+ cerr << "Missing input file." << endl;
+ return false;
+ }
+ if (mode_ == MODE_COMPILE && output_directives_.empty() &&
+ descriptor_set_name_.empty()) {
+ cerr << "Missing output directives." << endl;
+ return false;
+ }
+ if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) {
+ cerr << "--include_imports only makes sense when combined with "
+ "--descriptor_set_out." << endl;
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::ParseArgument(const char* arg,
+ string* name, string* value) {
+ bool parsed_value = false;
+
+ if (arg[0] != '-') {
+ // Not a flag.
+ name->clear();
+ parsed_value = true;
+ *value = arg;
+ } else if (arg[1] == '-') {
+ // Two dashes: Multi-character name, with '=' separating name and
+ // value.
+ const char* equals_pos = strchr(arg, '=');
+ if (equals_pos != NULL) {
+ *name = string(arg, equals_pos - arg);
+ *value = equals_pos + 1;
+ parsed_value = true;
+ } else {
+ *name = arg;
+ }
+ } else {
+ // One dash: One-character name, all subsequent characters are the
+ // value.
+ if (arg[1] == '\0') {
+ // arg is just "-". We treat this as an input file, except that at
+ // present this will just lead to a "file not found" error.
+ name->clear();
+ *value = arg;
+ parsed_value = true;
+ } else {
+ *name = string(arg, 2);
+ *value = arg + 2;
+ parsed_value = !value->empty();
+ }
+ }
+
+ // Need to return true iff the next arg should be used as the value for this
+ // one, false otherwise.
+
+ if (parsed_value) {
+ // We already parsed a value for this flag.
+ return false;
+ }
+
+ if (*name == "-h" || *name == "--help" ||
+ *name == "--disallow_services" ||
+ *name == "--include_imports" ||
+ *name == "--version" ||
+ *name == "--decode_raw") {
+ // HACK: These are the only flags that don't take a value.
+ // They probably should not be hard-coded like this but for now it's
+ // not worth doing better.
+ return false;
+ }
+
+ // Next argument is the flag value.
+ return true;
+}
+
+bool CommandLineInterface::InterpretArgument(const string& name,
+ const string& value) {
+ if (name.empty()) {
+ // Not a flag. Just a filename.
+ if (value.empty()) {
+ cerr << "You seem to have passed an empty string as one of the "
+ "arguments to " << executable_name_ << ". This is actually "
+ "sort of hard to do. Congrats. Unfortunately it is not valid "
+ "input so the program is going to die now." << endl;
+ return false;
+ }
+
+ input_files_.push_back(value);
+
+ } else if (name == "-I" || name == "--proto_path") {
+ // Java's -classpath (and some other languages) delimits path components
+ // with colons. Let's accept that syntax too just to make things more
+ // intuitive.
+ vector<string> parts;
+ SplitStringUsing(value, kPathSeparator, &parts);
+
+ for (int i = 0; i < parts.size(); i++) {
+ string virtual_path;
+ string disk_path;
+
+ string::size_type equals_pos = parts[i].find_first_of('=');
+ if (equals_pos == string::npos) {
+ virtual_path = "";
+ disk_path = parts[i];
+ } else {
+ virtual_path = parts[i].substr(0, equals_pos);
+ disk_path = parts[i].substr(equals_pos + 1);
+ }
+
+ if (disk_path.empty()) {
+ cerr << "--proto_path passed empty directory name. (Use \".\" for "
+ "current directory.)" << endl;
+ return false;
+ }
+
+ // Make sure disk path exists, warn otherwise.
+ if (access(disk_path.c_str(), F_OK) < 0) {
+ cerr << disk_path << ": warning: directory does not exist." << endl;
+ }
+
+ proto_path_.push_back(make_pair(virtual_path, disk_path));
+ }
+
+ } else if (name == "-o" || name == "--descriptor_set_out") {
+ if (!descriptor_set_name_.empty()) {
+ cerr << name << " may only be passed once." << endl;
+ return false;
+ }
+ if (value.empty()) {
+ cerr << name << " requires a non-empty value." << endl;
+ return false;
+ }
+ if (mode_ != MODE_COMPILE) {
+ cerr << "Cannot use --encode or --decode and generate descriptors at the "
+ "same time." << endl;
+ return false;
+ }
+ descriptor_set_name_ = value;
+
+ } else if (name == "--include_imports") {
+ if (imports_in_descriptor_set_) {
+ cerr << name << " may only be passed once." << endl;
+ return false;
+ }
+ imports_in_descriptor_set_ = true;
+
+ } else if (name == "-h" || name == "--help") {
+ PrintHelpText();
+ return false; // Exit without running compiler.
+
+ } else if (name == "--version") {
+ if (!version_info_.empty()) {
+ cout << version_info_ << endl;
+ }
+ cout << "libprotoc "
+ << protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION)
+ << endl;
+ return false; // Exit without running compiler.
+
+ } else if (name == "--disallow_services") {
+ disallow_services_ = true;
+
+ } else if (name == "--encode" || name == "--decode" ||
+ name == "--decode_raw") {
+ if (mode_ != MODE_COMPILE) {
+ cerr << "Only one of --encode and --decode can be specified." << endl;
+ return false;
+ }
+ if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
+ cerr << "Cannot use " << name
+ << " and generate code or descriptors at the same time." << endl;
+ return false;
+ }
+
+ mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
+
+ if (value.empty() && name != "--decode_raw") {
+ cerr << "Type name for " << name << " cannot be blank." << endl;
+ if (name == "--decode") {
+ cerr << "To decode an unknown message, use --decode_raw." << endl;
+ }
+ return false;
+ } else if (!value.empty() && name == "--decode_raw") {
+ cerr << "--decode_raw does not take a parameter." << endl;
+ return false;
+ }
+
+ codec_type_ = value;
+
+ } else if (name == "--error_format") {
+ if (value == "gcc") {
+ error_format_ = ERROR_FORMAT_GCC;
+ } else if (value == "msvs") {
+ error_format_ = ERROR_FORMAT_MSVS;
+ } else {
+ cerr << "Unknown error format: " << value << endl;
+ return false;
+ }
+
+ } else if (name == "--plugin") {
+ if (plugin_prefix_.empty()) {
+ cerr << "This compiler does not support plugins." << endl;
+ return false;
+ }
+
+ string name;
+ string path;
+
+ string::size_type equals_pos = value.find_first_of('=');
+ if (equals_pos == string::npos) {
+ // Use the basename of the file.
+ string::size_type slash_pos = value.find_last_of('/');
+ if (slash_pos == string::npos) {
+ name = value;
+ } else {
+ name = value.substr(slash_pos + 1);
+ }
+ path = value;
+ } else {
+ name = value.substr(0, equals_pos);
+ path = value.substr(equals_pos + 1);
+ }
+
+ plugins_[name] = path;
+
+ } else {
+ // Some other flag. Look it up in the generators list.
+ const GeneratorInfo* generator_info = FindOrNull(generators_, name);
+ if (generator_info == NULL &&
+ (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) {
+ cerr << "Unknown flag: " << name << endl;
+ return false;
+ }
+
+ // It's an output flag. Add it to the output directives.
+ if (mode_ != MODE_COMPILE) {
+ cerr << "Cannot use --encode or --decode and generate code at the "
+ "same time." << endl;
+ return false;
+ }
+
+ OutputDirective directive;
+ directive.name = name;
+ if (generator_info == NULL) {
+ directive.generator = NULL;
+ } else {
+ directive.generator = generator_info->generator;
+ }
+
+ // Split value at ':' to separate the generator parameter from the
+ // filename. However, avoid doing this if the colon is part of a valid
+ // Windows-style absolute path.
+ string::size_type colon_pos = value.find_first_of(':');
+ if (colon_pos == string::npos || IsWindowsAbsolutePath(value)) {
+ directive.output_location = value;
+ } else {
+ directive.parameter = value.substr(0, colon_pos);
+ directive.output_location = value.substr(colon_pos + 1);
+ }
+
+ output_directives_.push_back(directive);
+ }
+
+ return true;
+}
+
+void CommandLineInterface::PrintHelpText() {
+ // Sorry for indentation here; line wrapping would be uglier.
+ cerr <<
+"Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n"
+"Parse PROTO_FILES and generate output based on the options given:\n"
+" -IPATH, --proto_path=PATH Specify the directory in which to search for\n"
+" imports. May be specified multiple times;\n"
+" directories will be searched in order. If not\n"
+" given, the current working directory is used.\n"
+" --version Show version info and exit.\n"
+" -h, --help Show this text and exit.\n"
+" --encode=MESSAGE_TYPE Read a text-format message of the given type\n"
+" from standard input and write it in binary\n"
+" to standard output. The message type must\n"
+" be defined in PROTO_FILES or their imports.\n"
+" --decode=MESSAGE_TYPE Read a binary message of the given type from\n"
+" standard input and write it in text format\n"
+" to standard output. The message type must\n"
+" be defined in PROTO_FILES or their imports.\n"
+" --decode_raw Read an arbitrary protocol message from\n"
+" standard input and write the raw tag/value\n"
+" pairs in text format to standard output. No\n"
+" PROTO_FILES should be given when using this\n"
+" flag.\n"
+" -oFILE, Writes a FileDescriptorSet (a protocol buffer,\n"
+" --descriptor_set_out=FILE defined in descriptor.proto) containing all of\n"
+" the input files to FILE.\n"
+" --include_imports When using --descriptor_set_out, also include\n"
+" all dependencies of the input files in the\n"
+" set, so that the set is self-contained.\n"
+" --error_format=FORMAT Set the format in which to print errors.\n"
+" FORMAT may be 'gcc' (the default) or 'msvs'\n"
+" (Microsoft Visual Studio format)." << endl;
+ if (!plugin_prefix_.empty()) {
+ cerr <<
+" --plugin=EXECUTABLE Specifies a plugin executable to use.\n"
+" Normally, protoc searches the PATH for\n"
+" plugins, but you may specify additional\n"
+" executables not in the path using this flag.\n"
+" Additionally, EXECUTABLE may be of the form\n"
+" NAME=PATH, in which case the given plugin name\n"
+" is mapped to the given executable even if\n"
+" the executable's own name differs." << endl;
+ }
+
+ for (GeneratorMap::iterator iter = generators_.begin();
+ iter != generators_.end(); ++iter) {
+ // FIXME(kenton): If the text is long enough it will wrap, which is ugly,
+ // but fixing this nicely (e.g. splitting on spaces) is probably more
+ // trouble than it's worth.
+ cerr << " " << iter->first << "=OUT_DIR "
+ << string(19 - iter->first.size(), ' ') // Spaces for alignment.
+ << iter->second.help_text << endl;
+ }
+}
+
+bool CommandLineInterface::GenerateOutput(
+ const vector<const FileDescriptor*>& parsed_files,
+ const OutputDirective& output_directive,
+ GeneratorContext* generator_context) {
+ // Call the generator.
+ string error;
+ if (output_directive.generator == NULL) {
+ // This is a plugin.
+ GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") &&
+ HasSuffixString(output_directive.name, "_out"))
+ << "Bad name for plugin generator: " << output_directive.name;
+
+ // Strip the "--" and "_out" and add the plugin prefix.
+ string plugin_name = plugin_prefix_ + "gen-" +
+ output_directive.name.substr(2, output_directive.name.size() - 6);
+
+ if (!GeneratePluginOutput(parsed_files, plugin_name,
+ output_directive.parameter,
+ generator_context, &error)) {
+ cerr << output_directive.name << ": " << error << endl;
+ return false;
+ }
+ } else {
+ // Regular generator.
+ for (int i = 0; i < parsed_files.size(); i++) {
+ if (!output_directive.generator->Generate(
+ parsed_files[i], output_directive.parameter,
+ generator_context, &error)) {
+ // Generator returned an error.
+ cerr << output_directive.name << ": " << parsed_files[i]->name() << ": "
+ << error << endl;
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::GeneratePluginOutput(
+ const vector<const FileDescriptor*>& parsed_files,
+ const string& plugin_name,
+ const string& parameter,
+ GeneratorContext* generator_context,
+ string* error) {
+ CodeGeneratorRequest request;
+ CodeGeneratorResponse response;
+
+ // Build the request.
+ if (!parameter.empty()) {
+ request.set_parameter(parameter);
+ }
+
+ set<const FileDescriptor*> already_seen;
+ for (int i = 0; i < parsed_files.size(); i++) {
+ request.add_file_to_generate(parsed_files[i]->name());
+ GetTransitiveDependencies(parsed_files[i], &already_seen,
+ request.mutable_proto_file());
+ }
+
+ // Invoke the plugin.
+ Subprocess subprocess;
+
+ if (plugins_.count(plugin_name) > 0) {
+ subprocess.Start(plugins_[plugin_name], Subprocess::EXACT_NAME);
+ } else {
+ subprocess.Start(plugin_name, Subprocess::SEARCH_PATH);
+ }
+
+ string communicate_error;
+ if (!subprocess.Communicate(request, &response, &communicate_error)) {
+ *error = strings::Substitute("$0: $1", plugin_name, communicate_error);
+ return false;
+ }
+
+ // Write the files. We do this even if there was a generator error in order
+ // to match the behavior of a compiled-in generator.
+ scoped_ptr<io::ZeroCopyOutputStream> current_output;
+ for (int i = 0; i < response.file_size(); i++) {
+ const CodeGeneratorResponse::File& output_file = response.file(i);
+
+ if (!output_file.insertion_point().empty()) {
+ // Open a file for insert.
+ // We reset current_output to NULL first so that the old file is closed
+ // before the new one is opened.
+ current_output.reset();
+ current_output.reset(generator_context->OpenForInsert(
+ output_file.name(), output_file.insertion_point()));
+ } else if (!output_file.name().empty()) {
+ // Starting a new file. Open it.
+ // We reset current_output to NULL first so that the old file is closed
+ // before the new one is opened.
+ current_output.reset();
+ current_output.reset(generator_context->Open(output_file.name()));
+ } else if (current_output == NULL) {
+ *error = strings::Substitute(
+ "$0: First file chunk returned by plugin did not specify a file name.",
+ plugin_name);
+ return false;
+ }
+
+ // Use CodedOutputStream for convenience; otherwise we'd need to provide
+ // our own buffer-copying loop.
+ io::CodedOutputStream writer(current_output.get());
+ writer.WriteString(output_file.content());
+ }
+
+ // Check for errors.
+ if (!response.error().empty()) {
+ // Generator returned an error.
+ *error = response.error();
+ return false;
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
+ // Look up the type.
+ const Descriptor* type = pool->FindMessageTypeByName(codec_type_);
+ if (type == NULL) {
+ cerr << "Type not defined: " << codec_type_ << endl;
+ return false;
+ }
+
+ DynamicMessageFactory dynamic_factory(pool);
+ scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
+
+ if (mode_ == MODE_ENCODE) {
+ SetFdToTextMode(STDIN_FILENO);
+ SetFdToBinaryMode(STDOUT_FILENO);
+ } else {
+ SetFdToBinaryMode(STDIN_FILENO);
+ SetFdToTextMode(STDOUT_FILENO);
+ }
+
+ io::FileInputStream in(STDIN_FILENO);
+ io::FileOutputStream out(STDOUT_FILENO);
+
+ if (mode_ == MODE_ENCODE) {
+ // Input is text.
+ ErrorPrinter error_collector(error_format_);
+ TextFormat::Parser parser;
+ parser.RecordErrorsTo(&error_collector);
+ parser.AllowPartialMessage(true);
+
+ if (!parser.Parse(&in, message.get())) {
+ cerr << "Failed to parse input." << endl;
+ return false;
+ }
+ } else {
+ // Input is binary.
+ if (!message->ParsePartialFromZeroCopyStream(&in)) {
+ cerr << "Failed to parse input." << endl;
+ return false;
+ }
+ }
+
+ if (!message->IsInitialized()) {
+ cerr << "warning: Input message is missing required fields: "
+ << message->InitializationErrorString() << endl;
+ }
+
+ if (mode_ == MODE_ENCODE) {
+ // Output is binary.
+ if (!message->SerializePartialToZeroCopyStream(&out)) {
+ cerr << "output: I/O error." << endl;
+ return false;
+ }
+ } else {
+ // Output is text.
+ if (!TextFormat::Print(*message, &out)) {
+ cerr << "output: I/O error." << endl;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool CommandLineInterface::WriteDescriptorSet(
+ const vector<const FileDescriptor*> parsed_files) {
+ FileDescriptorSet file_set;
+
+ if (imports_in_descriptor_set_) {
+ set<const FileDescriptor*> already_seen;
+ for (int i = 0; i < parsed_files.size(); i++) {
+ GetTransitiveDependencies(
+ parsed_files[i], &already_seen, file_set.mutable_file());
+ }
+ } else {
+ for (int i = 0; i < parsed_files.size(); i++) {
+ parsed_files[i]->CopyTo(file_set.add_file());
+ }
+ }
+
+ int fd;
+ do {
+ fd = open(descriptor_set_name_.c_str(),
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+ } while (fd < 0 && errno == EINTR);
+
+ if (fd < 0) {
+ perror(descriptor_set_name_.c_str());
+ return false;
+ }
+
+ io::FileOutputStream out(fd);
+ if (!file_set.SerializeToZeroCopyStream(&out)) {
+ cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
+ out.Close();
+ return false;
+ }
+ if (!out.Close()) {
+ cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
+ return false;
+ }
+
+ return true;
+}
+
+void CommandLineInterface::GetTransitiveDependencies(
+ const FileDescriptor* file,
+ set<const FileDescriptor*>* already_seen,
+ RepeatedPtrField<FileDescriptorProto>* output) {
+ if (!already_seen->insert(file).second) {
+ // Already saw this file. Skip.
+ return;
+ }
+
+ // Add all dependencies.
+ for (int i = 0; i < file->dependency_count(); i++) {
+ GetTransitiveDependencies(file->dependency(i), already_seen, output);
+ }
+
+ // Add this file.
+ file->CopyTo(output->Add());
+}
+
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h b/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h
new file mode 100644
index 0000000..0b507d8
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h
@@ -0,0 +1,318 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Implements the Protocol Compiler front-end such that it may be reused by
+// custom compilers written to support other languages.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
+#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
+
+#include <google/protobuf/stubs/common.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <utility>
+
+namespace google {
+namespace protobuf {
+
+class FileDescriptor; // descriptor.h
+class DescriptorPool; // descriptor.h
+class FileDescriptorProto; // descriptor.pb.h
+template<typename T> class RepeatedPtrField; // repeated_field.h
+
+namespace compiler {
+
+class CodeGenerator; // code_generator.h
+class GeneratorContext; // code_generator.h
+class DiskSourceTree; // importer.h
+
+// This class implements the command-line interface to the protocol compiler.
+// It is designed to make it very easy to create a custom protocol compiler
+// supporting the languages of your choice. For example, if you wanted to
+// create a custom protocol compiler binary which includes both the regular
+// C++ support plus support for your own custom output "Foo", you would
+// write a class "FooGenerator" which implements the CodeGenerator interface,
+// then write a main() procedure like this:
+//
+// int main(int argc, char* argv[]) {
+// google::protobuf::compiler::CommandLineInterface cli;
+//
+// // Support generation of C++ source and headers.
+// google::protobuf::compiler::cpp::CppGenerator cpp_generator;
+// cli.RegisterGenerator("--cpp_out", &cpp_generator,
+// "Generate C++ source and header.");
+//
+// // Support generation of Foo code.
+// FooGenerator foo_generator;
+// cli.RegisterGenerator("--foo_out", &foo_generator,
+// "Generate Foo file.");
+//
+// return cli.Run(argc, argv);
+// }
+//
+// The compiler is invoked with syntax like:
+// protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto
+//
+// For a full description of the command-line syntax, invoke it with --help.
+class LIBPROTOC_EXPORT CommandLineInterface {
+ public:
+ CommandLineInterface();
+ ~CommandLineInterface();
+
+ // Register a code generator for a language.
+ //
+ // Parameters:
+ // * flag_name: The command-line flag used to specify an output file of
+ // this type. The name must start with a '-'. If the name is longer
+ // than one letter, it must start with two '-'s.
+ // * generator: The CodeGenerator which will be called to generate files
+ // of this type.
+ // * help_text: Text describing this flag in the --help output.
+ //
+ // Some generators accept extra parameters. You can specify this parameter
+ // on the command-line by placing it before the output directory, separated
+ // by a colon:
+ // protoc --foo_out=enable_bar:outdir
+ // The text before the colon is passed to CodeGenerator::Generate() as the
+ // "parameter".
+ void RegisterGenerator(const string& flag_name,
+ CodeGenerator* generator,
+ const string& help_text);
+
+ // Enables "plugins". In this mode, if a command-line flag ends with "_out"
+ // but does not match any registered generator, the compiler will attempt to
+ // find a "plugin" to implement the generator. Plugins are just executables.
+ // They should live somewhere in the PATH.
+ //
+ // The compiler determines the executable name to search for by concatenating
+ // exe_name_prefix with the unrecognized flag name, removing "_out". So, for
+ // example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out,
+ // the compiler will try to run the program "protoc-foo".
+ //
+ // The plugin program should implement the following usage:
+ // plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS
+ // --out indicates the output directory (as passed to the --foo_out
+ // parameter); if omitted, the current directory should be used. --parameter
+ // gives the generator parameter, if any was provided. The PROTO_FILES list
+ // the .proto files which were given on the compiler command-line; these are
+ // the files for which the plugin is expected to generate output code.
+ // Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in
+ // descriptor.proto). This is piped to the plugin's stdin. The set will
+ // include descriptors for all the files listed in PROTO_FILES as well as
+ // all files that they import. The plugin MUST NOT attempt to read the
+ // PROTO_FILES directly -- it must use the FileDescriptorSet.
+ //
+ // The plugin should generate whatever files are necessary, as code generators
+ // normally do. It should write the names of all files it generates to
+ // stdout. The names should be relative to the output directory, NOT absolute
+ // names or relative to the current directory. If any errors occur, error
+ // messages should be written to stderr. If an error is fatal, the plugin
+ // should exit with a non-zero exit code.
+ void AllowPlugins(const string& exe_name_prefix);
+
+ // Run the Protocol Compiler with the given command-line parameters.
+ // Returns the error code which should be returned by main().
+ //
+ // It may not be safe to call Run() in a multi-threaded environment because
+ // it calls strerror(). I'm not sure why you'd want to do this anyway.
+ int Run(int argc, const char* const argv[]);
+
+ // Call SetInputsAreCwdRelative(true) if the input files given on the command
+ // line should be interpreted relative to the proto import path specified
+ // using --proto_path or -I flags. Otherwise, input file names will be
+ // interpreted relative to the current working directory (or as absolute
+ // paths if they start with '/'), though they must still reside inside
+ // a directory given by --proto_path or the compiler will fail. The latter
+ // mode is generally more intuitive and easier to use, especially e.g. when
+ // defining implicit rules in Makefiles.
+ void SetInputsAreProtoPathRelative(bool enable) {
+ inputs_are_proto_path_relative_ = enable;
+ }
+
+ // Provides some text which will be printed when the --version flag is
+ // used. The version of libprotoc will also be printed on the next line
+ // after this text.
+ void SetVersionInfo(const string& text) {
+ version_info_ = text;
+ }
+
+
+ private:
+ // -----------------------------------------------------------------
+
+ class ErrorPrinter;
+ class GeneratorContextImpl;
+ class MemoryOutputStream;
+
+ // Clear state from previous Run().
+ void Clear();
+
+ // Remaps each file in input_files_ so that it is relative to one of the
+ // directories in proto_path_. Returns false if an error occurred. This
+ // is only used if inputs_are_proto_path_relative_ is false.
+ bool MakeInputsBeProtoPathRelative(
+ DiskSourceTree* source_tree);
+
+ // Parse all command-line arguments.
+ bool ParseArguments(int argc, const char* const argv[]);
+
+ // Parses a command-line argument into a name/value pair. Returns
+ // true if the next argument in the argv should be used as the value,
+ // false otherwise.
+ //
+ // Exmaples:
+ // "-Isrc/protos" ->
+ // name = "-I", value = "src/protos"
+ // "--cpp_out=src/foo.pb2.cc" ->
+ // name = "--cpp_out", value = "src/foo.pb2.cc"
+ // "foo.proto" ->
+ // name = "", value = "foo.proto"
+ bool ParseArgument(const char* arg, string* name, string* value);
+
+ // Interprets arguments parsed with ParseArgument.
+ bool InterpretArgument(const string& name, const string& value);
+
+ // Print the --help text to stderr.
+ void PrintHelpText();
+
+ // Generate the given output file from the given input.
+ struct OutputDirective; // see below
+ bool GenerateOutput(const vector<const FileDescriptor*>& parsed_files,
+ const OutputDirective& output_directive,
+ GeneratorContext* generator_context);
+ bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files,
+ const string& plugin_name,
+ const string& parameter,
+ GeneratorContext* generator_context,
+ string* error);
+
+ // Implements --encode and --decode.
+ bool EncodeOrDecode(const DescriptorPool* pool);
+
+ // Implements the --descriptor_set_out option.
+ bool WriteDescriptorSet(const vector<const FileDescriptor*> parsed_files);
+
+ // Get all transitive dependencies of the given file (including the file
+ // itself), adding them to the given list of FileDescriptorProtos. The
+ // protos will be ordered such that every file is listed before any file that
+ // depends on it, so that you can call DescriptorPool::BuildFile() on them
+ // in order. Any files in *already_seen will not be added, and each file
+ // added will be inserted into *already_seen.
+ static void GetTransitiveDependencies(
+ const FileDescriptor* file,
+ set<const FileDescriptor*>* already_seen,
+ RepeatedPtrField<FileDescriptorProto>* output);
+
+ // -----------------------------------------------------------------
+
+ // The name of the executable as invoked (i.e. argv[0]).
+ string executable_name_;
+
+ // Version info set with SetVersionInfo().
+ string version_info_;
+
+ // Map from flag names to registered generators.
+ struct GeneratorInfo {
+ CodeGenerator* generator;
+ string help_text;
+ };
+ typedef map<string, GeneratorInfo> GeneratorMap;
+ GeneratorMap generators_;
+
+ // See AllowPlugins(). If this is empty, plugins aren't allowed.
+ string plugin_prefix_;
+
+ // Maps specific plugin names to files. When executing a plugin, this map
+ // is searched first to find the plugin executable. If not found here, the
+ // PATH (or other OS-specific search strategy) is searched.
+ map<string, string> plugins_;
+
+ // Stuff parsed from command line.
+ enum Mode {
+ MODE_COMPILE, // Normal mode: parse .proto files and compile them.
+ MODE_ENCODE, // --encode: read text from stdin, write binary to stdout.
+ MODE_DECODE // --decode: read binary from stdin, write text to stdout.
+ };
+
+ Mode mode_;
+
+ enum ErrorFormat {
+ ERROR_FORMAT_GCC, // GCC error output format (default).
+ ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs).
+ };
+
+ ErrorFormat error_format_;
+
+ vector<pair<string, string> > proto_path_; // Search path for proto files.
+ vector<string> input_files_; // Names of the input proto files.
+
+ // output_directives_ lists all the files we are supposed to output and what
+ // generator to use for each.
+ struct OutputDirective {
+ string name; // E.g. "--foo_out"
+ CodeGenerator* generator; // NULL for plugins
+ string parameter;
+ string output_location;
+ };
+ vector<OutputDirective> output_directives_;
+
+ // When using --encode or --decode, this names the type we are encoding or
+ // decoding. (Empty string indicates --decode_raw.)
+ string codec_type_;
+
+ // If --descriptor_set_out was given, this is the filename to which the
+ // FileDescriptorSet should be written. Otherwise, empty.
+ string descriptor_set_name_;
+
+ // True if --include_imports was given, meaning that we should
+ // write all transitive dependencies to the DescriptorSet. Otherwise, only
+ // the .proto files listed on the command-line are added.
+ bool imports_in_descriptor_set_;
+
+ // Was the --disallow_services flag used?
+ bool disallow_services_;
+
+ // See SetInputsAreProtoPathRelative().
+ bool inputs_are_proto_path_relative_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface);
+};
+
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc
new file mode 100644
index 0000000..d5b3a1d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -0,0 +1,1452 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <vector>
+
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/mock_code_generator.h>
+#include <google/protobuf/compiler/subprocess.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#if defined(_WIN32)
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#ifndef F_OK
+#define F_OK 00 // not defined by MSVC for whatever reason
+#endif
+#endif
+
+namespace {
+
+class CommandLineInterfaceTest : public testing::Test {
+ protected:
+ virtual void SetUp();
+ virtual void TearDown();
+
+ // Runs the CommandLineInterface with the given command line. The
+ // command is automatically split on spaces, and the string "$tmpdir"
+ // is replaced with TestTempDir().
+ void Run(const string& command);
+
+ // -----------------------------------------------------------------
+ // Methods to set up the test (called before Run()).
+
+ class NullCodeGenerator;
+
+ // Normally plugins are allowed for all tests. Call this to explicitly
+ // disable them.
+ void DisallowPlugins() { disallow_plugins_ = true; }
+
+ // Create a temp file within temp_directory_ with the given name.
+ // The containing directory is also created if necessary.
+ void CreateTempFile(const string& name, const string& contents);
+
+ // Create a subdirectory within temp_directory_.
+ void CreateTempDir(const string& name);
+
+ void SetInputsAreProtoPathRelative(bool enable) {
+ cli_.SetInputsAreProtoPathRelative(enable);
+ }
+
+ // -----------------------------------------------------------------
+ // Methods to check the test results (called after Run()).
+
+ // Checks that no text was written to stderr during Run(), and Run()
+ // returned 0.
+ void ExpectNoErrors();
+
+ // Checks that Run() returned non-zero and the stderr output is exactly
+ // the text given. expected_test may contain references to "$tmpdir",
+ // which will be replaced by the temporary directory path.
+ void ExpectErrorText(const string& expected_text);
+
+ // Checks that Run() returned non-zero and the stderr contains the given
+ // substring.
+ void ExpectErrorSubstring(const string& expected_substring);
+
+ // Returns true if ExpectErrorSubstring(expected_substring) would pass, but
+ // does not fail otherwise.
+ bool HasAlternateErrorSubstring(const string& expected_substring);
+
+ // Checks that MockCodeGenerator::Generate() was called in the given
+ // context (or the generator in test_plugin.cc, which produces the same
+ // output). That is, this tests if the generator with the given name
+ // was called with the given parameter and proto file and produced the
+ // given output file. This is checked by reading the output file and
+ // checking that it contains the content that MockCodeGenerator would
+ // generate given these inputs. message_name is the name of the first
+ // message that appeared in the proto file; this is just to make extra
+ // sure that the correct file was parsed.
+ void ExpectGenerated(const string& generator_name,
+ const string& parameter,
+ const string& proto_name,
+ const string& message_name);
+ void ExpectGenerated(const string& generator_name,
+ const string& parameter,
+ const string& proto_name,
+ const string& message_name,
+ const string& output_directory);
+ void ExpectGeneratedWithMultipleInputs(const string& generator_name,
+ const string& all_proto_names,
+ const string& proto_name,
+ const string& message_name);
+ void ExpectGeneratedWithInsertions(const string& generator_name,
+ const string& parameter,
+ const string& insertions,
+ const string& proto_name,
+ const string& message_name);
+
+ void ExpectNullCodeGeneratorCalled(const string& parameter);
+
+ void ReadDescriptorSet(const string& filename,
+ FileDescriptorSet* descriptor_set);
+
+ private:
+ // The object we are testing.
+ CommandLineInterface cli_;
+
+ // Was DisallowPlugins() called?
+ bool disallow_plugins_;
+
+ // We create a directory within TestTempDir() in order to add extra
+ // protection against accidentally deleting user files (since we recursively
+ // delete this directory during the test). This is the full path of that
+ // directory.
+ string temp_directory_;
+
+ // The result of Run().
+ int return_code_;
+
+ // The captured stderr output.
+ string error_text_;
+
+ // Pointers which need to be deleted later.
+ vector<CodeGenerator*> mock_generators_to_delete_;
+
+ NullCodeGenerator* null_generator_;
+};
+
+class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator {
+ public:
+ NullCodeGenerator() : called_(false) {}
+ ~NullCodeGenerator() {}
+
+ mutable bool called_;
+ mutable string parameter_;
+
+ // implements CodeGenerator ----------------------------------------
+ bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+ called_ = true;
+ parameter_ = parameter;
+ return true;
+ }
+};
+
+// ===================================================================
+
+void CommandLineInterfaceTest::SetUp() {
+ // Most of these tests were written before this option was added, so we
+ // run with the option on (which used to be the only way) except in certain
+ // tests where we turn it off.
+ cli_.SetInputsAreProtoPathRelative(true);
+
+ temp_directory_ = TestTempDir() + "/proto2_cli_test_temp";
+
+ // If the temp directory already exists, it must be left over from a
+ // previous run. Delete it.
+ if (File::Exists(temp_directory_)) {
+ File::DeleteRecursively(temp_directory_, NULL, NULL);
+ }
+
+ // Create the temp directory.
+ GOOGLE_CHECK(File::CreateDir(temp_directory_.c_str(), DEFAULT_FILE_MODE));
+
+ // Register generators.
+ CodeGenerator* generator = new MockCodeGenerator("test_generator");
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--test_out", generator, "Test output.");
+ cli_.RegisterGenerator("-t", generator, "Test output.");
+
+ generator = new MockCodeGenerator("alt_generator");
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--alt_out", generator, "Alt output.");
+
+ generator = null_generator_ = new NullCodeGenerator();
+ mock_generators_to_delete_.push_back(generator);
+ cli_.RegisterGenerator("--null_out", generator, "Null output.");
+
+ disallow_plugins_ = false;
+}
+
+void CommandLineInterfaceTest::TearDown() {
+ // Delete the temp directory.
+ File::DeleteRecursively(temp_directory_, NULL, NULL);
+
+ // Delete all the MockCodeGenerators.
+ for (int i = 0; i < mock_generators_to_delete_.size(); i++) {
+ delete mock_generators_to_delete_[i];
+ }
+ mock_generators_to_delete_.clear();
+}
+
+void CommandLineInterfaceTest::Run(const string& command) {
+ vector<string> args;
+ SplitStringUsing(command, " ", &args);
+
+ if (!disallow_plugins_) {
+ cli_.AllowPlugins("prefix-");
+ const char* possible_paths[] = {
+ // When building with shared libraries, libtool hides the real executable
+ // in .libs and puts a fake wrapper in the current directory.
+ // Unfortunately, due to an apparent bug on Cygwin/MinGW, if one program
+ // wrapped in this way (e.g. protobuf-tests.exe) tries to execute another
+ // program wrapped in this way (e.g. test_plugin.exe), the latter fails
+ // with error code 127 and no explanation message. Presumably the problem
+ // is that the wrapper for protobuf-tests.exe set some environment
+ // variables that confuse the wrapper for test_plugin.exe. Luckily, it
+ // turns out that if we simply invoke the wrapped test_plugin.exe
+ // directly, it works -- I guess the environment variables set by the
+ // protobuf-tests.exe wrapper happen to be correct for it too. So we do
+ // that.
+ ".libs/test_plugin.exe", // Win32 w/autotool (Cygwin / MinGW)
+ "test_plugin.exe", // Other Win32 (MSVC)
+ "test_plugin", // Unix
+ };
+
+ string plugin_path;
+
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(possible_paths); i++) {
+ if (access(possible_paths[i], F_OK) == 0) {
+ plugin_path = possible_paths[i];
+ break;
+ }
+ }
+
+ if (plugin_path.empty()) {
+ GOOGLE_LOG(ERROR)
+ << "Plugin executable not found. Plugin tests are likely to fail.";
+ } else {
+ args.push_back("--plugin=prefix-gen-plug=" + plugin_path);
+ }
+ }
+
+ scoped_array<const char*> argv(new const char*[args.size()]);
+
+ for (int i = 0; i < args.size(); i++) {
+ args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true);
+ argv[i] = args[i].c_str();
+ }
+
+ CaptureTestStderr();
+
+ return_code_ = cli_.Run(args.size(), argv.get());
+
+ error_text_ = GetCapturedTestStderr();
+}
+
+// -------------------------------------------------------------------
+
+void CommandLineInterfaceTest::CreateTempFile(
+ const string& name,
+ const string& contents) {
+ // Create parent directory, if necessary.
+ string::size_type slash_pos = name.find_last_of('/');
+ if (slash_pos != string::npos) {
+ string dir = name.substr(0, slash_pos);
+ File::RecursivelyCreateDir(temp_directory_ + "/" + dir, 0777);
+ }
+
+ // Write file.
+ string full_name = temp_directory_ + "/" + name;
+ File::WriteStringToFileOrDie(contents, full_name);
+}
+
+void CommandLineInterfaceTest::CreateTempDir(const string& name) {
+ File::RecursivelyCreateDir(temp_directory_ + "/" + name, 0777);
+}
+
+// -------------------------------------------------------------------
+
+void CommandLineInterfaceTest::ExpectNoErrors() {
+ EXPECT_EQ(0, return_code_);
+ EXPECT_EQ("", error_text_);
+}
+
+void CommandLineInterfaceTest::ExpectErrorText(const string& expected_text) {
+ EXPECT_NE(0, return_code_);
+ EXPECT_EQ(StringReplace(expected_text, "$tmpdir", temp_directory_, true),
+ error_text_);
+}
+
+void CommandLineInterfaceTest::ExpectErrorSubstring(
+ const string& expected_substring) {
+ EXPECT_NE(0, return_code_);
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_substring, error_text_);
+}
+
+bool CommandLineInterfaceTest::HasAlternateErrorSubstring(
+ const string& expected_substring) {
+ EXPECT_NE(0, return_code_);
+ return error_text_.find(expected_substring) != string::npos;
+}
+
+void CommandLineInterfaceTest::ExpectGenerated(
+ const string& generator_name,
+ const string& parameter,
+ const string& proto_name,
+ const string& message_name) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, parameter, "", proto_name, message_name, proto_name,
+ temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectGenerated(
+ const string& generator_name,
+ const string& parameter,
+ const string& proto_name,
+ const string& message_name,
+ const string& output_directory) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, parameter, "", proto_name, message_name, proto_name,
+ temp_directory_ + "/" + output_directory);
+}
+
+void CommandLineInterfaceTest::ExpectGeneratedWithMultipleInputs(
+ const string& generator_name,
+ const string& all_proto_names,
+ const string& proto_name,
+ const string& message_name) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, "", "", proto_name, message_name,
+ all_proto_names,
+ temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
+ const string& generator_name,
+ const string& parameter,
+ const string& insertions,
+ const string& proto_name,
+ const string& message_name) {
+ MockCodeGenerator::ExpectGenerated(
+ generator_name, parameter, insertions, proto_name, message_name,
+ proto_name, temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled(
+ const string& parameter) {
+ EXPECT_TRUE(null_generator_->called_);
+ EXPECT_EQ(parameter, null_generator_->parameter_);
+}
+
+void CommandLineInterfaceTest::ReadDescriptorSet(
+ const string& filename, FileDescriptorSet* descriptor_set) {
+ string path = temp_directory_ + "/" + filename;
+ string file_contents;
+ if (!File::ReadFileToString(path, &file_contents)) {
+ FAIL() << "File not found: " << path;
+ }
+ if (!descriptor_set->ParseFromString(file_contents)) {
+ FAIL() << "Could not parse file contents: " << path;
+ }
+}
+
+// ===================================================================
+
+TEST_F(CommandLineInterfaceTest, BasicOutput) {
+ // Test that the common case works.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, BasicPlugin) {
+ // Test that basic plugins work.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) {
+ // Invoke a generator and a plugin at the same time.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+ ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputs) {
+ // Test parsing multiple input files.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto bar.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) {
+ // Test parsing multiple input files with an import of a separate file.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"baz.proto\";\n"
+ "message Bar {\n"
+ " optional Baz a = 1;\n"
+ "}\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "message Baz {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto bar.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+ "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest, CreateDirectory) {
+ // Test that when we output to a sub-directory, it is created.
+
+ CreateTempFile("bar/baz/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempDir("out");
+ CreateTempDir("plugout");
+
+ Run("protocol_compiler --test_out=$tmpdir/out --plug_out=$tmpdir/plugout "
+ "--proto_path=$tmpdir bar/baz/foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "bar/baz/foo.proto", "Foo", "out");
+ ExpectGenerated("test_plugin", "", "bar/baz/foo.proto", "Foo", "plugout");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorParameters) {
+ // Test that generator parameters are correctly parsed from the command line.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=TestParameter:$tmpdir "
+ "--plug_out=TestPluginParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "TestParameter", "foo.proto", "Foo");
+ ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, Insert) {
+ // Test running a generator that inserts code into another's output.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler "
+ "--test_out=TestParameter:$tmpdir "
+ "--plug_out=TestPluginParameter:$tmpdir "
+ "--test_out=insert=test_generator,test_plugin:$tmpdir "
+ "--plug_out=insert=test_generator,test_plugin:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGeneratedWithInsertions(
+ "test_generator", "TestParameter", "test_generator,test_plugin",
+ "foo.proto", "Foo");
+ ExpectGeneratedWithInsertions(
+ "test_plugin", "TestPluginParameter", "test_generator,test_plugin",
+ "foo.proto", "Foo");
+}
+
+#if defined(_WIN32)
+
+TEST_F(CommandLineInterfaceTest, WindowsOutputPath) {
+ // Test that the output path can be a Windows-style path.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n");
+
+ Run("protocol_compiler --null_out=C:\\ "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectNullCodeGeneratorCalled("");
+}
+
+TEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) {
+ // Test that we can have a windows-style output path and a parameter.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n");
+
+ Run("protocol_compiler --null_out=bar:C:\\ "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectNullCodeGeneratorCalled("bar");
+}
+
+TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
+ // Test that the directories can end in backslashes. Some users claim this
+ // doesn't work on their system.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir\\ "
+ "--proto_path=$tmpdir\\ foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+#endif // defined(_WIN32) || defined(__CYGWIN__)
+
+TEST_F(CommandLineInterfaceTest, PathLookup) {
+ // Test that specifying multiple directories in the proto search path works.
+
+ CreateTempFile("b/bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+ CreateTempFile("a/foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar a = 1;\n"
+ "}\n");
+ CreateTempFile("b/foo.proto", "this should not be parsed\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/a --proto_path=$tmpdir/b foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) {
+ // Same as PathLookup, but we provide the proto_path in a single flag.
+
+ CreateTempFile("b/bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+ CreateTempFile("a/foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar a = 1;\n"
+ "}\n");
+ CreateTempFile("b/foo.proto", "this should not be parsed\n");
+
+#undef PATH_SEPARATOR
+#if defined(_WIN32)
+#define PATH_SEPARATOR ";"
+#else
+#define PATH_SEPARATOR ":"
+#endif
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/a"PATH_SEPARATOR"$tmpdir/b foo.proto");
+
+#undef PATH_SEPARATOR
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, NonRootMapping) {
+ // Test setting up a search path mapping a directory to a non-root location.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=bar=$tmpdir bar/foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleGenerators) {
+ // Test that we can have multiple generators and use both in one invocation,
+ // each with a different output directory.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ // Create the "a" and "b" sub-directories.
+ CreateTempDir("a");
+ CreateTempDir("b");
+
+ Run("protocol_compiler "
+ "--test_out=$tmpdir/a "
+ "--alt_out=$tmpdir/b "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo", "a");
+ ExpectGenerated("alt_generator", "", "foo.proto", "Foo", "b");
+}
+
+TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) {
+ // Test that --disallow_services doesn't cause a problem when there are no
+ // services.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --disallow_services --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) {
+ // Test that --disallow_services produces an error when there are services.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n"
+ "service Bar {}\n");
+
+ Run("protocol_compiler --disallow_services --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("foo.proto: This file contains services");
+}
+
+TEST_F(CommandLineInterfaceTest, AllowServicesHasService) {
+ // Test that services work fine as long as --disallow_services is not used.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n"
+ "service Bar {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
+ // Test that we can accept working-directory-relative input files.
+
+ SetInputsAreProtoPathRelative(false);
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir $tmpdir/foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ ASSERT_EQ(1, descriptor_set.file_size());
+ EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--include_imports --proto_path=$tmpdir bar.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ ASSERT_EQ(2, descriptor_set.file_size());
+ if (descriptor_set.file(0).name() == "bar.proto") {
+ std::swap(descriptor_set.mutable_file()->mutable_data()[0],
+ descriptor_set.mutable_file()->mutable_data()[1]);
+ }
+ EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+ EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+}
+
+// -------------------------------------------------------------------
+
+TEST_F(CommandLineInterfaceTest, ParseErrors) {
+ // Test that parse errors are reported.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText(
+ "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseErrorsMultipleFiles) {
+ // Test that parse errors are reported from multiple files.
+
+ // We set up files such that foo.proto actually depends on bar.proto in
+ // two ways: Directly and through baz.proto. bar.proto's errors should
+ // only be reported once.
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n");
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "import \"baz.proto\";\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText(
+ "bar.proto:2:1: Expected top-level statement (e.g. \"message\").\n"
+ "baz.proto: Import \"bar.proto\" was not found or had errors.\n"
+ "foo.proto: Import \"bar.proto\" was not found or had errors.\n"
+ "foo.proto: Import \"baz.proto\" was not found or had errors.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InputNotFoundError) {
+ // Test what happens if the input file is not found.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText(
+ "foo.proto: File not found.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundError) {
+ // Test what happens when a working-directory-relative input file is not
+ // found.
+
+ SetInputsAreProtoPathRelative(false);
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir $tmpdir/foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo.proto: No such file or directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotMappedError) {
+ // Test what happens when a working-directory-relative input file is not
+ // mapped to a virtual path.
+
+ SetInputsAreProtoPathRelative(false);
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ // Create a directory called "bar" so that we can point --proto_path at it.
+ CreateTempFile("bar/dummy", "");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/bar $tmpdir/foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo.proto: File does not reside within any path "
+ "specified using --proto_path (or -I). You must specify a "
+ "--proto_path which encompasses this file. Note that the "
+ "proto_path must be an exact prefix of the .proto file "
+ "names -- protoc is too dumb to figure out when two paths "
+ "(e.g. absolute and relative) are equivalent (it's harder "
+ "than you think).\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputNotFoundAndNotMappedError) {
+ // Check what happens if the input file is not found *and* is not mapped
+ // in the proto_path.
+
+ SetInputsAreProtoPathRelative(false);
+
+ // Create a directory called "bar" so that we can point --proto_path at it.
+ CreateTempFile("bar/dummy", "");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/bar $tmpdir/foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo.proto: No such file or directory\n");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputShadowedError) {
+ // Test what happens when a working-directory-relative input file is shadowed
+ // by another file in the virtual path.
+
+ SetInputsAreProtoPathRelative(false);
+
+ CreateTempFile("foo/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar/foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/foo --proto_path=$tmpdir/bar "
+ "$tmpdir/bar/foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/bar/foo.proto: Input is shadowed in the --proto_path "
+ "by \"$tmpdir/foo/foo.proto\". Either use the latter "
+ "file as your input or reorder the --proto_path so that the "
+ "former file's location comes first.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, ProtoPathNotFoundError) {
+ // Test what happens if the input file is not found.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir/foo foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo: warning: directory does not exist.\n"
+ "foo.proto: File not found.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingInputError) {
+ // Test that we get an error if no inputs are given.
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir");
+
+ ExpectErrorText("Missing input file.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingOutputError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText("Missing output directives.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputWriteError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ string output_file =
+ MockCodeGenerator::GetOutputFileName("test_generator", "foo.proto");
+
+ // Create a directory blocking our output location.
+ CreateTempDir(output_file);
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ // MockCodeGenerator no longer detects an error because we actually write to
+ // an in-memory location first, then dump to disk at the end. This is no
+ // big deal.
+ // ExpectErrorSubstring("MockCodeGenerator detected write error.");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Windows with MSVCRT.dll produces EPERM instead of EISDIR.
+ if (HasAlternateErrorSubstring(output_file + ": Permission denied")) {
+ return;
+ }
+#endif
+
+ ExpectErrorSubstring(output_file + ": Is a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, PluginOutputWriteError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ string output_file =
+ MockCodeGenerator::GetOutputFileName("test_plugin", "foo.proto");
+
+ // Create a directory blocking our output location.
+ CreateTempDir(output_file);
+
+ Run("protocol_compiler --plug_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Windows with MSVCRT.dll produces EPERM instead of EISDIR.
+ if (HasAlternateErrorSubstring(output_file + ": Permission denied")) {
+ return;
+ }
+#endif
+
+ ExpectErrorSubstring(output_file + ": Is a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir/nosuchdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("nosuchdir/: No such file or directory");
+}
+
+TEST_F(CommandLineInterfaceTest, PluginOutputDirectoryNotFoundError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --plug_out=$tmpdir/nosuchdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("nosuchdir/: No such file or directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir/foo.proto "
+ "--proto_path=$tmpdir foo.proto");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ // Windows with MSVCRT.dll produces EINVAL instead of ENOTDIR.
+ if (HasAlternateErrorSubstring("foo.proto/: Invalid argument")) {
+ return;
+ }
+#endif
+
+ ExpectErrorSubstring("foo.proto/: Not a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorError) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Error {}\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "--test_out: foo.proto: Saw message type MockCodeGenerator_Error.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginError) {
+ // Test a generator plugin that returns an error.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Error {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring(
+ "--plug_out: foo.proto: Saw message type MockCodeGenerator_Error.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginFail) {
+ // Test a generator plugin that exits with an error code.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Exit {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Saw message type MockCodeGenerator_Exit.");
+ ExpectErrorSubstring(
+ "--plug_out: prefix-gen-plug: Plugin failed with status code 123.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) {
+ // Test a generator plugin that crashes.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message MockCodeGenerator_Abort {}\n");
+
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectErrorSubstring("Saw message type MockCodeGenerator_Abort.");
+
+#ifdef _WIN32
+ // Windows doesn't have signals. It looks like abort()ing causes the process
+ // to exit with status code 3, but let's not depend on the exact number here.
+ ExpectErrorSubstring(
+ "--plug_out: prefix-gen-plug: Plugin failed with status code");
+#else
+ // Don't depend on the exact signal number.
+ ExpectErrorSubstring(
+ "--plug_out: prefix-gen-plug: Plugin killed by signal");
+#endif
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
+ // Test what happens if the plugin isn't found.
+
+ CreateTempFile("error.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --badplug_out=TestParameter:$tmpdir "
+ "--plugin=prefix-gen-badplug=no_such_file "
+ "--proto_path=$tmpdir error.proto");
+
+#ifdef _WIN32
+ ExpectErrorSubstring("--badplug_out: prefix-gen-badplug: " +
+ Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
+#else
+ // Error written to stdout by child process after exec() fails.
+ ExpectErrorSubstring(
+ "no_such_file: program not found or is not executable");
+
+ // Error written by parent process when child fails.
+ ExpectErrorSubstring(
+ "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1.");
+#endif
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) {
+ // Test what happens if plugins aren't allowed.
+
+ CreateTempFile("error.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ DisallowPlugins();
+ Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+ "--proto_path=$tmpdir error.proto");
+
+ ExpectErrorSubstring("Unknown flag: --plug_out");
+}
+
+TEST_F(CommandLineInterfaceTest, HelpText) {
+ Run("test_exec_name --help");
+
+ ExpectErrorSubstring("Usage: test_exec_name ");
+ ExpectErrorSubstring("--test_out=OUT_DIR");
+ ExpectErrorSubstring("Test output.");
+ ExpectErrorSubstring("--alt_out=OUT_DIR");
+ ExpectErrorSubstring("Alt output.");
+}
+
+TEST_F(CommandLineInterfaceTest, GccFormatErrors) {
+ // Test --error_format=gcc (which is the default, but we want to verify
+ // that it can be set explicitly).
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=gcc foo.proto");
+
+ ExpectErrorText(
+ "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) {
+ // Test --error_format=msvs
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=msvs foo.proto");
+
+ ExpectErrorText(
+ "$tmpdir/foo.proto(2) : error in column=1: Expected top-level statement "
+ "(e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) {
+ // Test --error_format=msvs
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=invalid foo.proto");
+
+ ExpectErrorText(
+ "Unknown error format: invalid\n");
+}
+
+// -------------------------------------------------------------------
+// Flag parsing tests
+
+TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) {
+ // Test that a single-character flag works.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler -t$tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) {
+ // Test that separating the flag value with a space works.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler --test_out $tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) {
+ // Test that separating the flag value with a space works for
+ // single-character flags.
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ Run("protocol_compiler -t $tmpdir "
+ "--proto_path=$tmpdir foo.proto");
+
+ ExpectNoErrors();
+ ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingValueError) {
+ // Test that we get an error if a flag is missing its value.
+
+ Run("protocol_compiler --test_out --proto_path=$tmpdir foo.proto");
+
+ ExpectErrorText("Missing value for flag: --test_out\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) {
+ // Test that we get an error if the last argument is a flag requiring a
+ // value.
+
+ Run("protocol_compiler --test_out");
+
+ ExpectErrorText("Missing value for flag: --test_out\n");
+}
+
+// ===================================================================
+
+// Test for --encode and --decode. Note that it would be easier to do this
+// test as a shell script, but we'd like to be able to run the test on
+// platforms that don't have a Bourne-compatible shell available (especially
+// Windows/MSVC).
+class EncodeDecodeTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ duped_stdin_ = dup(STDIN_FILENO);
+ }
+
+ virtual void TearDown() {
+ dup2(duped_stdin_, STDIN_FILENO);
+ close(duped_stdin_);
+ }
+
+ void RedirectStdinFromText(const string& input) {
+ string filename = TestTempDir() + "/test_stdin";
+ File::WriteStringToFileOrDie(input, filename);
+ GOOGLE_CHECK(RedirectStdinFromFile(filename));
+ }
+
+ bool RedirectStdinFromFile(const string& filename) {
+ int fd = open(filename.c_str(), O_RDONLY);
+ if (fd < 0) return false;
+ dup2(fd, STDIN_FILENO);
+ close(fd);
+ return true;
+ }
+
+ // Remove '\r' characters from text.
+ string StripCR(const string& text) {
+ string result;
+
+ for (int i = 0; i < text.size(); i++) {
+ if (text[i] != '\r') {
+ result.push_back(text[i]);
+ }
+ }
+
+ return result;
+ }
+
+ enum Type { TEXT, BINARY };
+ enum ReturnCode { SUCCESS, ERROR };
+
+ bool Run(const string& command) {
+ vector<string> args;
+ args.push_back("protoc");
+ SplitStringUsing(command, " ", &args);
+ args.push_back("--proto_path=" + TestSourceDir());
+
+ scoped_array<const char*> argv(new const char*[args.size()]);
+ for (int i = 0; i < args.size(); i++) {
+ argv[i] = args[i].c_str();
+ }
+
+ CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ CaptureTestStdout();
+ CaptureTestStderr();
+
+ int result = cli.Run(args.size(), argv.get());
+
+ captured_stdout_ = GetCapturedTestStdout();
+ captured_stderr_ = GetCapturedTestStderr();
+
+ return result == 0;
+ }
+
+ void ExpectStdoutMatchesBinaryFile(const string& filename) {
+ string expected_output;
+ ASSERT_TRUE(File::ReadFileToString(filename, &expected_output));
+
+ // Don't use EXPECT_EQ because we don't want to print raw binary data to
+ // stdout on failure.
+ EXPECT_TRUE(captured_stdout_ == expected_output);
+ }
+
+ void ExpectStdoutMatchesTextFile(const string& filename) {
+ string expected_output;
+ ASSERT_TRUE(File::ReadFileToString(filename, &expected_output));
+
+ ExpectStdoutMatchesText(expected_output);
+ }
+
+ void ExpectStdoutMatchesText(const string& expected_text) {
+ EXPECT_EQ(StripCR(expected_text), StripCR(captured_stdout_));
+ }
+
+ void ExpectStderrMatchesText(const string& expected_text) {
+ EXPECT_EQ(StripCR(expected_text), StripCR(captured_stderr_));
+ }
+
+ private:
+ int duped_stdin_;
+ string captured_stdout_;
+ string captured_stderr_;
+};
+
+TEST_F(EncodeDecodeTest, Encode) {
+ RedirectStdinFromFile(TestSourceDir() +
+ "/google/protobuf/testdata/text_format_unittest_data.txt");
+ EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+ "--encode=protobuf_unittest.TestAllTypes"));
+ ExpectStdoutMatchesBinaryFile(TestSourceDir() +
+ "/google/protobuf/testdata/golden_message");
+ ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, Decode) {
+ RedirectStdinFromFile(TestSourceDir() +
+ "/google/protobuf/testdata/golden_message");
+ EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+ "--decode=protobuf_unittest.TestAllTypes"));
+ ExpectStdoutMatchesTextFile(TestSourceDir() +
+ "/google/protobuf/testdata/text_format_unittest_data.txt");
+ ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, Partial) {
+ RedirectStdinFromText("");
+ EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+ "--encode=protobuf_unittest.TestRequired"));
+ ExpectStdoutMatchesText("");
+ ExpectStderrMatchesText(
+ "warning: Input message is missing required fields: a, b, c\n");
+}
+
+TEST_F(EncodeDecodeTest, DecodeRaw) {
+ protobuf_unittest::TestAllTypes message;
+ message.set_optional_int32(123);
+ message.set_optional_string("foo");
+ string data;
+ message.SerializeToString(&data);
+
+ RedirectStdinFromText(data);
+ EXPECT_TRUE(Run("--decode_raw"));
+ ExpectStdoutMatchesText("1: 123\n"
+ "14: \"foo\"\n");
+ ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, UnknownType) {
+ EXPECT_FALSE(Run("google/protobuf/unittest.proto "
+ "--encode=NoSuchType"));
+ ExpectStdoutMatchesText("");
+ ExpectStderrMatchesText("Type not defined: NoSuchType\n");
+}
+
+TEST_F(EncodeDecodeTest, ProtoParseError) {
+ EXPECT_FALSE(Run("google/protobuf/no_such_file.proto "
+ "--encode=NoSuchType"));
+ ExpectStdoutMatchesText("");
+ ExpectStderrMatchesText(
+ "google/protobuf/no_such_file.proto: File not found.\n");
+}
+
+} // anonymous namespace
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
new file mode 100644
index 0000000..bcfa502
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -0,0 +1,158 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This test insures that google/protobuf/descriptor.pb.{h,cc} match exactly
+// what would be generated by the protocol compiler. These files are not
+// generated automatically at build time because they are compiled into the
+// protocol compiler itself. So, if they were auto-generated, you'd have a
+// chicken-and-egg problem.
+//
+// If this test fails, run the script
+// "generate_descriptor_proto.sh" and add
+// descriptor.pb.{h,cc} to your changelist.
+
+#include <map>
+
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const string& filename, int line, int column,
+ const string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
+ filename, line, column, message);
+ }
+};
+
+class MockGeneratorContext : public GeneratorContext {
+ public:
+ MockGeneratorContext() {}
+ ~MockGeneratorContext() {
+ STLDeleteValues(&files_);
+ }
+
+ void ExpectFileMatches(const string& virtual_filename,
+ const string& physical_filename) {
+ string* expected_contents = FindPtrOrNull(files_, virtual_filename);
+ ASSERT_TRUE(expected_contents != NULL)
+ << "Generator failed to generate file: " << virtual_filename;
+
+ string actual_contents;
+ File::ReadFileToStringOrDie(
+ TestSourceDir() + "/" + physical_filename,
+ &actual_contents);
+ EXPECT_TRUE(actual_contents == *expected_contents)
+ << physical_filename << " needs to be regenerated. Please run "
+ "generate_descriptor_proto.sh and add this file "
+ "to your CL.";
+ }
+
+ // implements GeneratorContext --------------------------------------
+
+ virtual io::ZeroCopyOutputStream* Open(const string& filename) {
+ string** map_slot = &files_[filename];
+ if (*map_slot != NULL) delete *map_slot;
+ *map_slot = new string;
+
+ return new io::StringOutputStream(*map_slot);
+ }
+
+ private:
+ map<string, string*> files_;
+};
+
+TEST(BootstrapTest, GeneratedDescriptorMatches) {
+ MockErrorCollector error_collector;
+ DiskSourceTree source_tree;
+ source_tree.MapPath("", TestSourceDir());
+ Importer importer(&source_tree, &error_collector);
+ const FileDescriptor* proto_file =
+ importer.Import("google/protobuf/descriptor.proto");
+ const FileDescriptor* plugin_proto_file =
+ importer.Import("google/protobuf/compiler/plugin.proto");
+ EXPECT_EQ("", error_collector.text_);
+ ASSERT_TRUE(proto_file != NULL);
+ ASSERT_TRUE(plugin_proto_file != NULL);
+
+ CppGenerator generator;
+ MockGeneratorContext context;
+ string error;
+ string parameter;
+ parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
+ ASSERT_TRUE(generator.Generate(proto_file, parameter,
+ &context, &error));
+ parameter = "dllexport_decl=LIBPROTOC_EXPORT";
+ ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter,
+ &context, &error));
+
+ context.ExpectFileMatches("google/protobuf/descriptor.pb.h",
+ "google/protobuf/descriptor.pb.h");
+ context.ExpectFileMatches("google/protobuf/descriptor.pb.cc",
+ "google/protobuf/descriptor.pb.cc");
+ context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h",
+ "google/protobuf/compiler/plugin.pb.h");
+ context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
+ "google/protobuf/compiler/plugin.pb.cc");
+}
+
+} // namespace
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc
new file mode 100644
index 0000000..76d2b79
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -0,0 +1,258 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <set>
+#include <map>
+
+#include <google/protobuf/compiler/cpp/cpp_enum.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+ const string& dllexport_decl)
+ : descriptor_(descriptor),
+ classname_(ClassName(descriptor, false)),
+ dllexport_decl_(dllexport_decl) {
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::GenerateDefinition(io::Printer* printer) {
+ map<string, string> vars;
+ vars["classname"] = classname_;
+ vars["short_name"] = descriptor_->name();
+
+ printer->Print(vars, "enum $classname$ {\n");
+ printer->Indent();
+
+ const EnumValueDescriptor* min_value = descriptor_->value(0);
+ const EnumValueDescriptor* max_value = descriptor_->value(0);
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ vars["name"] = descriptor_->value(i)->name();
+ vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+ vars["prefix"] = (descriptor_->containing_type() == NULL) ?
+ "" : classname_ + "_";
+
+ if (i > 0) printer->Print(",\n");
+ printer->Print(vars, "$prefix$$name$ = $number$");
+
+ if (descriptor_->value(i)->number() < min_value->number()) {
+ min_value = descriptor_->value(i);
+ }
+ if (descriptor_->value(i)->number() > max_value->number()) {
+ max_value = descriptor_->value(i);
+ }
+ }
+
+ printer->Outdent();
+ printer->Print("\n};\n");
+
+ vars["min_name"] = min_value->name();
+ vars["max_name"] = max_value->name();
+
+ if (dllexport_decl_.empty()) {
+ vars["dllexport"] = "";
+ } else {
+ vars["dllexport"] = dllexport_decl_ + " ";
+ }
+
+ printer->Print(vars,
+ "$dllexport$bool $classname$_IsValid(int value);\n"
+ "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
+ "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n"
+ "const int $prefix$$short_name$_ARRAYSIZE = $prefix$$short_name$_MAX + 1;\n"
+ "\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n");
+ // The _Name and _Parse methods
+ printer->Print(vars,
+ "inline const ::std::string& $classname$_Name($classname$ value) {\n"
+ " return ::google::protobuf::internal::NameOfEnum(\n"
+ " $classname$_descriptor(), value);\n"
+ "}\n");
+ printer->Print(vars,
+ "inline bool $classname$_Parse(\n"
+ " const ::std::string& name, $classname$* value) {\n"
+ " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
+ " $classname$_descriptor(), name, value);\n"
+ "}\n");
+ }
+}
+
+void EnumGenerator::
+GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "template <>\n"
+ "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
+ " return $classname$_descriptor();\n"
+ "}\n",
+ "classname", ClassName(descriptor_, true));
+ }
+}
+
+void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
+ map<string, string> vars;
+ vars["nested_name"] = descriptor_->name();
+ vars["classname"] = classname_;
+ printer->Print(vars, "typedef $classname$ $nested_name$;\n");
+
+ for (int j = 0; j < descriptor_->value_count(); j++) {
+ vars["tag"] = descriptor_->value(j)->name();
+ printer->Print(vars,
+ "static const $nested_name$ $tag$ = $classname$_$tag$;\n");
+ }
+
+ printer->Print(vars,
+ "static inline bool $nested_name$_IsValid(int value) {\n"
+ " return $classname$_IsValid(value);\n"
+ "}\n"
+ "static const $nested_name$ $nested_name$_MIN =\n"
+ " $classname$_$nested_name$_MIN;\n"
+ "static const $nested_name$ $nested_name$_MAX =\n"
+ " $classname$_$nested_name$_MAX;\n"
+ "static const int $nested_name$_ARRAYSIZE =\n"
+ " $classname$_$nested_name$_ARRAYSIZE;\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "static inline const ::google::protobuf::EnumDescriptor*\n"
+ "$nested_name$_descriptor() {\n"
+ " return $classname$_descriptor();\n"
+ "}\n");
+ printer->Print(vars,
+ "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n"
+ " return $classname$_Name(value);\n"
+ "}\n");
+ printer->Print(vars,
+ "static inline bool $nested_name$_Parse(const ::std::string& name,\n"
+ " $nested_name$* value) {\n"
+ " return $classname$_Parse(name, value);\n"
+ "}\n");
+ }
+}
+
+void EnumGenerator::GenerateDescriptorInitializer(
+ io::Printer* printer, int index) {
+ map<string, string> vars;
+ vars["classname"] = classname_;
+ vars["index"] = SimpleItoa(index);
+
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(vars,
+ "$classname$_descriptor_ = file->enum_type($index$);\n");
+ } else {
+ vars["parent"] = ClassName(descriptor_->containing_type(), false);
+ printer->Print(vars,
+ "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n");
+ }
+}
+
+void EnumGenerator::GenerateMethods(io::Printer* printer) {
+ map<string, string> vars;
+ vars["classname"] = classname_;
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n");
+ }
+
+ printer->Print(vars,
+ "bool $classname$_IsValid(int value) {\n"
+ " switch(value) {\n");
+
+ // Multiple values may have the same number. Make sure we only cover
+ // each number once by first constructing a set containing all valid
+ // numbers, then printing a case statement for each element.
+
+ set<int> numbers;
+ for (int j = 0; j < descriptor_->value_count(); j++) {
+ const EnumValueDescriptor* value = descriptor_->value(j);
+ numbers.insert(value->number());
+ }
+
+ for (set<int>::iterator iter = numbers.begin();
+ iter != numbers.end(); ++iter) {
+ printer->Print(
+ " case $number$:\n",
+ "number", SimpleItoa(*iter));
+ }
+
+ printer->Print(vars,
+ " return true;\n"
+ " default:\n"
+ " return false;\n"
+ " }\n"
+ "}\n"
+ "\n");
+
+ if (descriptor_->containing_type() != NULL) {
+ // We need to "define" the static constants which were declared in the
+ // header, to give the linker a place to put them. Or at least the C++
+ // standard says we have to. MSVC actually insists tha we do _not_ define
+ // them again in the .cc file.
+ printer->Print("#ifndef _MSC_VER\n");
+
+ vars["parent"] = ClassName(descriptor_->containing_type(), false);
+ vars["nested_name"] = descriptor_->name();
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ vars["value"] = descriptor_->value(i)->name();
+ printer->Print(vars,
+ "const $classname$ $parent$::$value$;\n");
+ }
+ printer->Print(vars,
+ "const $classname$ $parent$::$nested_name$_MIN;\n"
+ "const $classname$ $parent$::$nested_name$_MAX;\n"
+ "const int $parent$::$nested_name$_ARRAYSIZE;\n");
+
+ printer->Print("#endif // _MSC_VER\n");
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h
new file mode 100644
index 0000000..58f7721
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+
+#include <string>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit EnumGenerator(const EnumDescriptor* descriptor,
+ const string& dllexport_decl);
+ ~EnumGenerator();
+
+ // Header stuff.
+
+ // Generate header code defining the enum. This code should be placed
+ // within the enum's package namespace, but NOT within any class, even for
+ // nested enums.
+ void GenerateDefinition(io::Printer* printer);
+
+ // Generate specialization of GetEnumDescriptor<MyEnum>().
+ // Precondition: in ::google::protobuf namespace.
+ void GenerateGetEnumDescriptorSpecializations(io::Printer* printer);
+
+ // For enums nested within a message, generate code to import all the enum's
+ // symbols (e.g. the enum type name, all its values, etc.) into the class's
+ // namespace. This should be placed inside the class definition in the
+ // header.
+ void GenerateSymbolImports(io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate code that initializes the global variable storing the enum's
+ // descriptor.
+ void GenerateDescriptorInitializer(io::Printer* printer, int index);
+
+ // Generate non-inline methods related to the enum, such as IsValidValue().
+ // Goes in the .cc file.
+ void GenerateMethods(io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+ string classname_;
+ string dllexport_decl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
new file mode 100644
index 0000000..a369f41
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -0,0 +1,361 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetEnumVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables) {
+ SetCommonFieldVariables(descriptor, variables);
+ const EnumValueDescriptor* default_value = descriptor->default_value_enum();
+ (*variables)["type"] = ClassName(descriptor->enum_type(), true);
+ (*variables)["default"] = SimpleItoa(default_value->number());
+}
+
+} // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::
+EnumFieldGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ SetEnumVariables(descriptor, &variables_);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "int $name$_;\n");
+}
+
+void EnumFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $name$() const$deprecation$;\n"
+ "inline void set_$name$($type$ value)$deprecation$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$() const {\n"
+ " return static_cast< $type$ >($name$_);\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " GOOGLE_DCHECK($type$_IsValid(value));\n"
+ " set_has_$name$();\n"
+ " $name$_ = value;\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void EnumFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void EnumFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "int value;\n"
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+ " input, &value)));\n"
+ "if ($type$_IsValid(value)) {\n"
+ " set_$name$(static_cast< $type$ >(value));\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(variables_,
+ "} else {\n"
+ " mutable_unknown_fields()->AddVarint($number$, value);\n");
+ }
+ printer->Print(variables_,
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
+ " $number$, this->$name$(), output);\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+ " $number$, this->$name$(), target);\n");
+}
+
+void EnumFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::EnumSize(this->$name$());\n");
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ SetEnumVariables(descriptor, &variables_);
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedField<int> $name$_;\n");
+ if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
+ printer->Print(variables_,
+ "mutable int _$name$_cached_byte_size_;\n");
+ }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $name$(int index) const$deprecation$;\n"
+ "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
+ "inline void add_$name$($type$ value)$deprecation$;\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$(int index) const {\n"
+ " return static_cast< $type$ >($name$_.Get(index));\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+ " GOOGLE_DCHECK($type$_IsValid(value));\n"
+ " $name$_.Set(index, value);\n"
+ "}\n"
+ "inline void $classname$::add_$name$($type$ value) {\n"
+ " GOOGLE_DCHECK($type$_IsValid(value));\n"
+ " $name$_.Add(value);\n"
+ "}\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedField<int>&\n"
+ "$classname$::$name$() const {\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::google::protobuf::RepeatedField<int>*\n"
+ "$classname$::mutable_$name$() {\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ // Don't use ReadRepeatedPrimitive here so that the enum can be validated.
+ printer->Print(variables_,
+ "int value;\n"
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+ " input, &value)));\n"
+ "if ($type$_IsValid(value)) {\n"
+ " add_$name$(static_cast< $type$ >(value));\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(variables_,
+ "} else {\n"
+ " mutable_unknown_fields()->AddVarint($number$, value);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+ if (!descriptor_->options().packed()) {
+ // We use a non-inlined implementation in this case, since this path will
+ // rarely be executed.
+ printer->Print(variables_,
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n"
+ " input,\n"
+ " &$type$_IsValid,\n"
+ " this->mutable_$name$())));\n");
+ } else {
+ printer->Print(variables_,
+ "::google::protobuf::uint32 length;\n"
+ "DO_(input->ReadVarint32(&length));\n"
+ "::google::protobuf::io::CodedInputStream::Limit limit = "
+ "input->PushLimit(length);\n"
+ "while (input->BytesUntilLimit() > 0) {\n"
+ " int value;\n"
+ " DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+ " input, &value)));\n"
+ " if ($type$_IsValid(value)) {\n"
+ " add_$name$(static_cast< $type$ >(value));\n"
+ " }\n"
+ "}\n"
+ "input->PopLimit(limit);\n");
+ }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " ::google::protobuf::internal::WireFormatLite::WriteTag(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " output);\n"
+ " output->WriteVarint32(_$name$_cached_byte_size_);\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n"
+ " this->$name$(i), output);\n");
+ } else {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
+ " $number$, this->$name$(i), output);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " target);\n"
+ " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
+ " _$name$_cached_byte_size_, target);\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
+ " this->$name$(i), target);\n");
+ } else {
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+ " $number$, this->$name$(i), target);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int data_size = 0;\n");
+ printer->Indent();
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n"
+ " this->$name$(i));\n"
+ "}\n");
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (data_size > 0) {\n"
+ " total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
+ "}\n"
+ "_$name$_cached_byte_size_ = data_size;\n"
+ "total_size += data_size;\n");
+ } else {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h
new file mode 100644
index 0000000..0793430
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumFieldGenerator : public FieldGenerator {
+ public:
+ explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
+ ~EnumFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+};
+
+class RepeatedEnumFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
+ ~RepeatedEnumFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc
new file mode 100644
index 0000000..658a7077
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -0,0 +1,210 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_extension.h>
+#include <map>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+// Returns the fully-qualified class name of the message that this field
+// extends. This function is used in the Google-internal code to handle some
+// legacy cases.
+string ExtendeeClassName(const FieldDescriptor* descriptor) {
+ const Descriptor* extendee = descriptor->containing_type();
+ return ClassName(extendee, true);
+}
+
+} // anonymous namespace
+
+ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
+ const string& dllexport_decl)
+ : descriptor_(descriptor),
+ dllexport_decl_(dllexport_decl) {
+ // Construct type_traits_.
+ if (descriptor_->is_repeated()) {
+ type_traits_ = "Repeated";
+ }
+
+ switch (descriptor_->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_ENUM:
+ type_traits_.append("EnumTypeTraits< ");
+ type_traits_.append(ClassName(descriptor_->enum_type(), true));
+ type_traits_.append(", ");
+ type_traits_.append(ClassName(descriptor_->enum_type(), true));
+ type_traits_.append("_IsValid>");
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ type_traits_.append("StringTypeTraits");
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ type_traits_.append("MessageTypeTraits< ");
+ type_traits_.append(ClassName(descriptor_->message_type(), true));
+ type_traits_.append(" >");
+ break;
+ default:
+ type_traits_.append("PrimitiveTypeTraits< ");
+ type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type()));
+ type_traits_.append(" >");
+ break;
+ }
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
+ map<string, string> vars;
+ vars["extendee" ] = ExtendeeClassName(descriptor_);
+ vars["number" ] = SimpleItoa(descriptor_->number());
+ vars["type_traits" ] = type_traits_;
+ vars["name" ] = descriptor_->name();
+ vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+ vars["packed" ] = descriptor_->options().packed() ? "true" : "false";
+ vars["constant_name"] = FieldConstantName(descriptor_);
+
+ // If this is a class member, it needs to be declared "static". Otherwise,
+ // it needs to be "extern". In the latter case, it also needs the DLL
+ // export/import specifier.
+ if (descriptor_->extension_scope() == NULL) {
+ vars["qualifier"] = "extern";
+ if (!dllexport_decl_.empty()) {
+ vars["qualifier"] = dllexport_decl_ + " " + vars["qualifier"];
+ }
+ } else {
+ vars["qualifier"] = "static";
+ }
+
+ printer->Print(vars,
+ "static const int $constant_name$ = $number$;\n"
+ "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
+ " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
+ " $name$;\n"
+ );
+
+}
+
+void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
+ // If this is a class member, it needs to be declared in its class scope.
+ string scope = (descriptor_->extension_scope() == NULL) ? "" :
+ ClassName(descriptor_->extension_scope(), false) + "::";
+ string name = scope + descriptor_->name();
+
+ map<string, string> vars;
+ vars["extendee" ] = ExtendeeClassName(descriptor_);
+ vars["type_traits" ] = type_traits_;
+ vars["name" ] = name;
+ vars["constant_name"] = FieldConstantName(descriptor_);
+ vars["default" ] = DefaultValue(descriptor_);
+ vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+ vars["packed" ] = descriptor_->options().packed() ? "true" : "false";
+ vars["scope" ] = scope;
+
+ if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ // We need to declare a global string which will contain the default value.
+ // We cannot declare it at class scope because that would require exposing
+ // it in the header which would be annoying for other reasons. So we
+ // replace :: with _ in the name and declare it as a global.
+ string global_name = StringReplace(name, "::", "_", true);
+ vars["global_name"] = global_name;
+ printer->Print(vars,
+ "const ::std::string $global_name$_default($default$);\n");
+
+ // Update the default to refer to the string global.
+ vars["default"] = global_name + "_default";
+ }
+
+ // Likewise, class members need to declare the field constant variable.
+ if (descriptor_->extension_scope() != NULL) {
+ printer->Print(vars,
+ "#ifndef _MSC_VER\n"
+ "const int $scope$$constant_name$;\n"
+ "#endif\n");
+ }
+
+ printer->Print(vars,
+ "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
+ " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
+ " $name$($constant_name$, $default$);\n");
+}
+
+void ExtensionGenerator::GenerateRegistration(io::Printer* printer) {
+ map<string, string> vars;
+ vars["extendee" ] = ExtendeeClassName(descriptor_);
+ vars["number" ] = SimpleItoa(descriptor_->number());
+ vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+ vars["is_repeated"] = descriptor_->is_repeated() ? "true" : "false";
+ vars["is_packed" ] = (descriptor_->is_repeated() &&
+ descriptor_->options().packed())
+ ? "true" : "false";
+
+ switch (descriptor_->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_ENUM:
+ printer->Print(vars,
+ "::google::protobuf::internal::ExtensionSet::RegisterEnumExtension(\n"
+ " &$extendee$::default_instance(),\n"
+ " $number$, $field_type$, $is_repeated$, $is_packed$,\n");
+ printer->Print(
+ " &$type$_IsValid);\n",
+ "type", ClassName(descriptor_->enum_type(), true));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ printer->Print(vars,
+ "::google::protobuf::internal::ExtensionSet::RegisterMessageExtension(\n"
+ " &$extendee$::default_instance(),\n"
+ " $number$, $field_type$, $is_repeated$, $is_packed$,\n");
+ printer->Print(
+ " &$type$::default_instance());\n",
+ "type", ClassName(descriptor_->message_type(), true));
+ break;
+ default:
+ printer->Print(vars,
+ "::google::protobuf::internal::ExtensionSet::RegisterExtension(\n"
+ " &$extendee$::default_instance(),\n"
+ " $number$, $field_type$, $is_repeated$, $is_packed$);\n");
+ break;
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h
new file mode 100644
index 0000000..3068b09
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h
@@ -0,0 +1,85 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+ class FieldDescriptor; // descriptor.h
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Generates code for an extension, which may be within the scope of some
+// message or may be at file scope. This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ExtensionGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit ExtensionGenerator(const FieldDescriptor* descriptor,
+ const string& dllexport_decl);
+ ~ExtensionGenerator();
+
+ // Header stuff.
+ void GenerateDeclaration(io::Printer* printer);
+
+ // Source file stuff.
+ void GenerateDefinition(io::Printer* printer);
+
+ // Generate code to register the extension.
+ void GenerateRegistration(io::Printer* printer);
+
+ private:
+ const FieldDescriptor* descriptor_;
+ string type_traits_;
+ string dllexport_decl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc
new file mode 100644
index 0000000..103cac4
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -0,0 +1,139 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
+#include <google/protobuf/compiler/cpp/cpp_string_field.h>
+#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
+#include <google/protobuf/compiler/cpp/cpp_message_field.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables) {
+ (*variables)["name"] = FieldName(descriptor);
+ (*variables)["index"] = SimpleItoa(descriptor->index());
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
+ (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
+
+ (*variables)["tag_size"] = SimpleItoa(
+ WireFormat::TagSize(descriptor->number(), descriptor->type()));
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? " PROTOBUF_DEPRECATED" : "";
+
+}
+
+FieldGenerator::~FieldGenerator() {}
+
+void FieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+ // Reaching here indicates a bug. Cases are:
+ // - This FieldGenerator should support packing, but this method should be
+ // overridden.
+ // - This FieldGenerator doesn't support packing, and this method should
+ // never have been called.
+ GOOGLE_LOG(FATAL) << "GenerateMergeFromCodedStreamWithPacking() "
+ << "called on field generator that does not support packing.";
+
+}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
+ : descriptor_(descriptor),
+ field_generators_(
+ new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
+ // Construct all the FieldGenerators.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
+ }
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return new RepeatedMessageFieldGenerator(field);
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // RepeatedStringFieldGenerator handles unknown ctypes.
+ case FieldOptions::STRING:
+ return new RepeatedStringFieldGenerator(field);
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new RepeatedEnumFieldGenerator(field);
+ default:
+ return new RepeatedPrimitiveFieldGenerator(field);
+ }
+ } else {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return new MessageFieldGenerator(field);
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // StringFieldGenerator handles unknown ctypes.
+ case FieldOptions::STRING:
+ return new StringFieldGenerator(field);
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new EnumFieldGenerator(field);
+ default:
+ return new PrimitiveFieldGenerator(field);
+ }
+ }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+ const FieldDescriptor* field) const {
+ GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ return *field_generators_[field->index()];
+}
+
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h
new file mode 100644
index 0000000..c303a33
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -0,0 +1,167 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Helper function: set variables in the map that are the same for all
+// field code generators.
+// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
+// 'deprecation'].
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables);
+
+class FieldGenerator {
+ public:
+ FieldGenerator() {}
+ virtual ~FieldGenerator();
+
+ // Generate lines of code declaring members fields of the message class
+ // needed to represent this field. These are placed inside the message
+ // class.
+ virtual void GeneratePrivateMembers(io::Printer* printer) const = 0;
+
+ // Generate prototypes for all of the accessor functions related to this
+ // field. These are placed inside the class definition.
+ virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0;
+
+ // Generate inline definitions of accessor functions for this field.
+ // These are placed inside the header after all class definitions.
+ virtual void GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const = 0;
+
+ // Generate definitions of accessors that aren't inlined. These are
+ // placed somewhere in the .cc file.
+ // Most field types don't need this, so the default implementation is empty.
+ virtual void GenerateNonInlineAccessorDefinitions(
+ io::Printer* printer) const {}
+
+ // Generate lines of code (statements, not declarations) which clear the
+ // field. This is used to define the clear_$name$() method as well as
+ // the Clear() method for the whole message.
+ virtual void GenerateClearingCode(io::Printer* printer) const = 0;
+
+ // Generate lines of code (statements, not declarations) which merges the
+ // contents of the field from the current message to the target message,
+ // which is stored in the generated code variable "from".
+ // This is used to fill in the MergeFrom method for the whole message.
+ // Details of this usage can be found in message.cc under the
+ // GenerateMergeFrom method.
+ virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+
+ // Generate lines of code (statements, not declarations) which swaps
+ // this field and the corresponding field of another message, which
+ // is stored in the generated code variable "other". This is used to
+ // define the Swap method. Details of usage can be found in
+ // message.cc under the GenerateSwap method.
+ virtual void GenerateSwappingCode(io::Printer* printer) const = 0;
+
+ // Generate initialization code for private members declared by
+ // GeneratePrivateMembers(). These go into the message class's SharedCtor()
+ // method, invoked by each of the generated constructors.
+ virtual void GenerateConstructorCode(io::Printer* printer) const = 0;
+
+ // Generate any code that needs to go in the class's SharedDtor() method,
+ // invoked by the destructor.
+ // Most field types don't need this, so the default implementation is empty.
+ virtual void GenerateDestructorCode(io::Printer* printer) const {}
+
+ // Generate lines to decode this field, which will be placed inside the
+ // message's MergeFromCodedStream() method.
+ virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0;
+
+ // Generate lines to decode this field from a packed value, which will be
+ // placed inside the message's MergeFromCodedStream() method.
+ virtual void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer)
+ const;
+
+ // Generate lines to serialize this field, which are placed within the
+ // message's SerializeWithCachedSizes() method.
+ virtual void GenerateSerializeWithCachedSizes(io::Printer* printer) const = 0;
+
+ // Generate lines to serialize this field directly to the array "target",
+ // which are placed within the message's SerializeWithCachedSizesToArray()
+ // method. This must also advance "target" past the written bytes.
+ virtual void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const = 0;
+
+ // Generate lines to compute the serialized size of this field, which
+ // are placed in the message's ByteSize() method.
+ virtual void GenerateByteSize(io::Printer* printer) const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+ explicit FieldGeneratorMap(const Descriptor* descriptor);
+ ~FieldGeneratorMap();
+
+ const FieldGenerator& get(const FieldDescriptor* field) const;
+
+ private:
+ const Descriptor* descriptor_;
+ scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
+
+ static FieldGenerator* MakeGenerator(const FieldDescriptor* field);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc
new file mode 100644
index 0000000..3e6d414
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -0,0 +1,631 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_file.h>
+#include <google/protobuf/compiler/cpp/cpp_enum.h>
+#include <google/protobuf/compiler/cpp/cpp_service.h>
+#include <google/protobuf/compiler/cpp/cpp_extension.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/cpp/cpp_message.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// ===================================================================
+
+FileGenerator::FileGenerator(const FileDescriptor* file,
+ const string& dllexport_decl)
+ : file_(file),
+ message_generators_(
+ new scoped_ptr<MessageGenerator>[file->message_type_count()]),
+ enum_generators_(
+ new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
+ service_generators_(
+ new scoped_ptr<ServiceGenerator>[file->service_count()]),
+ extension_generators_(
+ new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
+ dllexport_decl_(dllexport_decl) {
+
+ for (int i = 0; i < file->message_type_count(); i++) {
+ message_generators_[i].reset(
+ new MessageGenerator(file->message_type(i), dllexport_decl));
+ }
+
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ enum_generators_[i].reset(
+ new EnumGenerator(file->enum_type(i), dllexport_decl));
+ }
+
+ for (int i = 0; i < file->service_count(); i++) {
+ service_generators_[i].reset(
+ new ServiceGenerator(file->service(i), dllexport_decl));
+ }
+
+ for (int i = 0; i < file->extension_count(); i++) {
+ extension_generators_[i].reset(
+ new ExtensionGenerator(file->extension(i), dllexport_decl));
+ }
+
+ SplitStringUsing(file_->package(), ".", &package_parts_);
+}
+
+FileGenerator::~FileGenerator() {}
+
+void FileGenerator::GenerateHeader(io::Printer* printer) {
+ string filename_identifier = FilenameIdentifier(file_->name());
+
+ // Generate top of header.
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n"
+ "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
+ "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
+ "\n"
+ "#include <string>\n"
+ "\n",
+ "filename", file_->name(),
+ "filename_identifier", filename_identifier);
+
+ printer->Print(
+ "#include <google/protobuf/stubs/common.h>\n"
+ "\n");
+
+ // Verify the protobuf library header version is compatible with the protoc
+ // version before going any further.
+ printer->Print(
+ "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
+ "#error This file was generated by a newer version of protoc which is\n"
+ "#error incompatible with your Protocol Buffer headers. Please update\n"
+ "#error your headers.\n"
+ "#endif\n"
+ "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
+ "#error This file was generated by an older version of protoc which is\n"
+ "#error incompatible with your Protocol Buffer headers. Please\n"
+ "#error regenerate this file with a newer version of protoc.\n"
+ "#endif\n"
+ "\n",
+ "min_header_version",
+ SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
+ "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
+
+ // OK, it's now safe to #include other files.
+ printer->Print(
+ "#include <google/protobuf/generated_message_util.h>\n"
+ "#include <google/protobuf/repeated_field.h>\n"
+ "#include <google/protobuf/extension_set.h>\n");
+
+ if (HasUnknownFields(file_)) {
+ printer->Print(
+ "#include <google/protobuf/unknown_field_set.h>\n");
+ }
+
+ if (HasDescriptorMethods(file_)) {
+ printer->Print(
+ "#include <google/protobuf/generated_message_reflection.h>\n");
+ }
+
+ if (HasGenericServices(file_)) {
+ printer->Print(
+ "#include <google/protobuf/service.h>\n");
+ }
+
+
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ printer->Print(
+ "#include \"$dependency$.pb.h\"\n",
+ "dependency", StripProto(file_->dependency(i)->name()));
+ }
+
+ printer->Print(
+ "// @@protoc_insertion_point(includes)\n");
+
+ // Open namespace.
+ GenerateNamespaceOpeners(printer);
+
+ // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile
+ // functions, so that we can declare them to be friends of each class.
+ printer->Print(
+ "\n"
+ "// Internal implementation detail -- do not call these.\n"
+ "void $dllexport_decl$ $adddescriptorsname$();\n",
+ "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
+ "dllexport_decl", dllexport_decl_);
+
+ printer->Print(
+ // Note that we don't put dllexport_decl on these because they are only
+ // called by the .pb.cc file in which they are defined.
+ "void $assigndescriptorsname$();\n"
+ "void $shutdownfilename$();\n"
+ "\n",
+ "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()),
+ "shutdownfilename", GlobalShutdownFileName(file_->name()));
+
+ // Generate forward declarations of classes.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateForwardDeclaration(printer);
+ }
+
+ printer->Print("\n");
+
+ // Generate enum definitions.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateEnumDefinitions(printer);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateDefinition(printer);
+ }
+
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+
+ // Generate class definitions.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ if (i > 0) {
+ printer->Print("\n");
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+ message_generators_[i]->GenerateClassDefinition(printer);
+ }
+
+ printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+
+ if (HasGenericServices(file_)) {
+ // Generate service definitions.
+ for (int i = 0; i < file_->service_count(); i++) {
+ if (i > 0) {
+ printer->Print("\n");
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+ service_generators_[i]->GenerateDeclarations(printer);
+ }
+
+ printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+ }
+
+ // Declare extension identifiers.
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_[i]->GenerateDeclaration(printer);
+ }
+
+ printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+
+ // Generate class inline methods.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ if (i > 0) {
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+ message_generators_[i]->GenerateInlineMethods(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n");
+
+ // Close up namespace.
+ GenerateNamespaceClosers(printer);
+
+ // Emit GetEnumDescriptor specializations into google::protobuf namespace:
+ if (HasDescriptorMethods(file_)) {
+ // The SWIG conditional is to avoid a null-pointer dereference
+ // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
+ // namespace X { void Y<Z::W>(); }
+ // which appears in GetEnumDescriptor() specializations.
+ printer->Print(
+ "\n"
+ "#ifndef SWIG\n"
+ "namespace google {\nnamespace protobuf {\n"
+ "\n");
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+ printer->Print(
+ "\n"
+ "} // namespace google\n} // namespace protobuf\n"
+ "#endif // SWIG\n");
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n"
+ "\n");
+
+ printer->Print(
+ "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n",
+ "filename_identifier", filename_identifier);
+}
+
+void FileGenerator::GenerateSource(io::Printer* printer) {
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "\n"
+
+ // The generated code calls accessors that might be deprecated. We don't
+ // want the compiler to warn in generated code.
+ "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
+ "#include \"$basename$.pb.h\"\n"
+ "\n"
+ "#include <algorithm>\n" // for swap()
+ "\n"
+ "#include <google/protobuf/stubs/once.h>\n"
+ "#include <google/protobuf/io/coded_stream.h>\n"
+ "#include <google/protobuf/wire_format_lite_inl.h>\n",
+ "basename", StripProto(file_->name()));
+
+ if (HasDescriptorMethods(file_)) {
+ printer->Print(
+ "#include <google/protobuf/descriptor.h>\n"
+ "#include <google/protobuf/reflection_ops.h>\n"
+ "#include <google/protobuf/wire_format.h>\n");
+ }
+
+ printer->Print(
+ "// @@protoc_insertion_point(includes)\n");
+
+ GenerateNamespaceOpeners(printer);
+
+ if (HasDescriptorMethods(file_)) {
+ printer->Print(
+ "\n"
+ "namespace {\n"
+ "\n");
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateDescriptorDeclarations(printer);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ printer->Print(
+ "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
+ "name", ClassName(file_->enum_type(i), false));
+ }
+
+ if (HasGenericServices(file_)) {
+ for (int i = 0; i < file_->service_count(); i++) {
+ printer->Print(
+ "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
+ "name", file_->service(i)->name());
+ }
+ }
+
+ printer->Print(
+ "\n"
+ "} // namespace\n"
+ "\n");
+ }
+
+ // Define our externally-visible BuildDescriptors() function. (For the lite
+ // library, all this does is initialize default instances.)
+ GenerateBuildDescriptors(printer);
+
+ // Generate enums.
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateMethods(printer);
+ }
+
+ // Generate classes.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+ message_generators_[i]->GenerateClassMethods(printer);
+ }
+
+ if (HasGenericServices(file_)) {
+ // Generate services.
+ for (int i = 0; i < file_->service_count(); i++) {
+ if (i == 0) printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+ service_generators_[i]->GenerateImplementation(printer);
+ }
+ }
+
+ // Define extensions.
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_[i]->GenerateDefinition(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n");
+
+ GenerateNamespaceClosers(printer);
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n");
+}
+
+void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
+ // AddDescriptors() is a file-level procedure which adds the encoded
+ // FileDescriptorProto for this .proto file to the global DescriptorPool for
+ // generated files (DescriptorPool::generated_pool()). It either runs at
+ // static initialization time (by default) or when default_instance() is
+ // called for the first time (in LITE_RUNTIME mode with
+ // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also
+ // constructs default instances and registers extensions.
+ //
+ // Its sibling, AssignDescriptors(), actually pulls the compiled
+ // FileDescriptor from the DescriptorPool and uses it to populate all of
+ // the global variables which store pointers to the descriptor objects.
+ // It also constructs the reflection objects. It is called the first time
+ // anyone calls descriptor() or GetReflection() on one of the types defined
+ // in the file.
+
+ // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
+ // and we only use AddDescriptors() to allocate default instances.
+ if (HasDescriptorMethods(file_)) {
+ printer->Print(
+ "\n"
+ "void $assigndescriptorsname$() {\n",
+ "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+ printer->Indent();
+
+ // Make sure the file has found its way into the pool. If a descriptor
+ // is requested *during* static init then AddDescriptors() may not have
+ // been called yet, so we call it manually. Note that it's fine if
+ // AddDescriptors() is called multiple times.
+ printer->Print(
+ "$adddescriptorsname$();\n",
+ "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
+
+ // Get the file's descriptor from the pool.
+ printer->Print(
+ "const ::google::protobuf::FileDescriptor* file =\n"
+ " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
+ " \"$filename$\");\n"
+ // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
+ // being unused when compiling an empty .proto file.
+ "GOOGLE_CHECK(file != NULL);\n",
+ "filename", file_->name());
+
+ // Go through all the stuff defined in this file and generated code to
+ // assign the global descriptor pointers based on the file descriptor.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+ if (HasGenericServices(file_)) {
+ for (int i = 0; i < file_->service_count(); i++) {
+ service_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ // ---------------------------------------------------------------
+
+ // protobuf_AssignDescriptorsOnce(): The first time it is called, calls
+ // AssignDescriptors(). All later times, waits for the first call to
+ // complete and then returns.
+ printer->Print(
+ "namespace {\n"
+ "\n"
+ "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
+ "inline void protobuf_AssignDescriptorsOnce() {\n"
+ " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
+ " &$assigndescriptorsname$);\n"
+ "}\n"
+ "\n",
+ "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+
+ // protobuf_RegisterTypes(): Calls
+ // MessageFactory::InternalRegisterGeneratedType() for each message type.
+ printer->Print(
+ "void protobuf_RegisterTypes(const ::std::string&) {\n"
+ " protobuf_AssignDescriptorsOnce();\n");
+ printer->Indent();
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateTypeRegistrations(printer);
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n"
+ "} // namespace\n");
+ }
+
+ // -----------------------------------------------------------------
+
+ // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown.
+ printer->Print(
+ "\n"
+ "void $shutdownfilename$() {\n",
+ "shutdownfilename", GlobalShutdownFileName(file_->name()));
+ printer->Indent();
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateShutdownCode(printer);
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n\n");
+
+ // -----------------------------------------------------------------
+
+ // Now generate the AddDescriptors() function.
+ PrintHandlingOptionalStaticInitializers(
+ file_, printer,
+ // With static initializers.
+ // Note that we don't need any special synchronization in the following code
+ // because it is called at static init time before any threads exist.
+ "void $adddescriptorsname$() {\n"
+ " static bool already_here = false;\n"
+ " if (already_here) return;\n"
+ " already_here = true;\n"
+ " GOOGLE_PROTOBUF_VERIFY_VERSION;\n",
+ // Without.
+ "void $adddescriptorsname$_impl() {\n"
+ " GOOGLE_PROTOBUF_VERIFY_VERSION;\n",
+ // Vars.
+ "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
+
+ printer->Indent();
+
+ // Call the AddDescriptors() methods for all of our dependencies, to make
+ // sure they get added first.
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ const FileDescriptor* dependency = file_->dependency(i);
+ // Print the namespace prefix for the dependency.
+ vector<string> dependency_package_parts;
+ SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
+ printer->Print("::");
+ for (int i = 0; i < dependency_package_parts.size(); i++) {
+ printer->Print("$name$::",
+ "name", dependency_package_parts[i]);
+ }
+ // Call its AddDescriptors function.
+ printer->Print(
+ "$name$();\n",
+ "name", GlobalAddDescriptorsName(dependency->name()));
+ }
+
+ if (HasDescriptorMethods(file_)) {
+ // Embed the descriptor. We simply serialize the entire FileDescriptorProto
+ // and embed it as a string literal, which is parsed and built into real
+ // descriptors at initialization time.
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+ string file_data;
+ file_proto.SerializeToString(&file_data);
+
+ printer->Print(
+ "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
+
+ // Only write 40 bytes per line.
+ static const int kBytesPerLine = 40;
+ for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+ printer->Print("\n \"$data$\"",
+ "data", EscapeTrigraphs(CEscape(file_data.substr(i, kBytesPerLine))));
+ }
+ printer->Print(
+ ", $size$);\n",
+ "size", SimpleItoa(file_data.size()));
+
+ // Call MessageFactory::InternalRegisterGeneratedFile().
+ printer->Print(
+ "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
+ " \"$filename$\", &protobuf_RegisterTypes);\n",
+ "filename", file_->name());
+ }
+
+ // Allocate and initialize default instances. This can't be done lazily
+ // since default instances are returned by simple accessors and are used with
+ // extensions. Speaking of which, we also register extensions at this time.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
+ }
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_[i]->GenerateRegistration(printer);
+ }
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
+ }
+
+ printer->Print(
+ "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n",
+ "shutdownfilename", GlobalShutdownFileName(file_->name()));
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ PrintHandlingOptionalStaticInitializers(
+ file_, printer,
+ // With static initializers.
+ "// Force AddDescriptors() to be called at static initialization time.\n"
+ "struct StaticDescriptorInitializer_$filename$ {\n"
+ " StaticDescriptorInitializer_$filename$() {\n"
+ " $adddescriptorsname$();\n"
+ " }\n"
+ "} static_descriptor_initializer_$filename$_;\n",
+ // Without.
+ "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
+ "void $adddescriptorsname$() {\n"
+ " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
+ " &$adddescriptorsname$_impl);\n"
+ "}\n",
+ // Vars.
+ "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
+ "filename", FilenameIdentifier(file_->name()));
+}
+
+void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) {
+ if (package_parts_.size() > 0) printer->Print("\n");
+
+ for (int i = 0; i < package_parts_.size(); i++) {
+ printer->Print("namespace $part$ {\n",
+ "part", package_parts_[i]);
+ }
+}
+
+void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
+ if (package_parts_.size() > 0) printer->Print("\n");
+
+ for (int i = package_parts_.size() - 1; i >= 0; i--) {
+ printer->Print("} // namespace $part$\n",
+ "part", package_parts_[i]);
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h
new file mode 100644
index 0000000..b4e0128
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+ class FileDescriptor; // descriptor.h
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator; // enum.h
+class MessageGenerator; // message.h
+class ServiceGenerator; // service.h
+class ExtensionGenerator; // extension.h
+
+class FileGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit FileGenerator(const FileDescriptor* file,
+ const string& dllexport_decl);
+ ~FileGenerator();
+
+ void GenerateHeader(io::Printer* printer);
+ void GenerateSource(io::Printer* printer);
+
+ private:
+ // Generate the BuildDescriptors() procedure, which builds all descriptors
+ // for types defined in the file.
+ void GenerateBuildDescriptors(io::Printer* printer);
+
+ void GenerateNamespaceOpeners(io::Printer* printer);
+ void GenerateNamespaceClosers(io::Printer* printer);
+
+ const FileDescriptor* file_;
+
+ scoped_array<scoped_ptr<MessageGenerator> > message_generators_;
+ scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
+ scoped_array<scoped_ptr<ServiceGenerator> > service_generators_;
+ scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+
+ // E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
+ vector<string> package_parts_;
+
+ string dllexport_decl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc
new file mode 100644
index 0000000..bb84e2a
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+
+#include <vector>
+#include <utility>
+
+#include <google/protobuf/compiler/cpp/cpp_file.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+CppGenerator::CppGenerator() {}
+CppGenerator::~CppGenerator() {}
+
+bool CppGenerator::Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* generator_context,
+ string* error) const {
+ vector<pair<string, string> > options;
+ ParseGeneratorParameter(parameter, &options);
+
+ // -----------------------------------------------------------------
+ // parse generator options
+
+ // TODO(kenton): If we ever have more options, we may want to create a
+ // class that encapsulates them which we can pass down to all the
+ // generator classes. Currently we pass dllexport_decl down to all of
+ // them via the constructors, but we don't want to have to add another
+ // constructor parameter for every option.
+
+ // If the dllexport_decl option is passed to the compiler, we need to write
+ // it in front of every symbol that should be exported if this .proto is
+ // compiled into a Windows DLL. E.g., if the user invokes the protocol
+ // compiler as:
+ // protoc --cpp_out=dllexport_decl=FOO_EXPORT:outdir foo.proto
+ // then we'll define classes like this:
+ // class FOO_EXPORT Foo {
+ // ...
+ // }
+ // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
+ // __declspec(dllimport) depending on what is being compiled.
+ string dllexport_decl;
+
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "dllexport_decl") {
+ dllexport_decl = options[i].second;
+ } else {
+ *error = "Unknown generator option: " + options[i].first;
+ return false;
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+
+ string basename = StripProto(file->name());
+ basename.append(".pb");
+
+ FileGenerator file_generator(file, dllexport_decl);
+
+ // Generate header.
+ {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".h"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateHeader(&printer);
+ }
+
+ // Generate cc file.
+ {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".cc"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateSource(&printer);
+ }
+
+ return true;
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h
new file mode 100644
index 0000000..a90e84d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Generates C++ code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
+
+#include <string>
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// CodeGenerator implementation which generates a C++ source file and
+// header. If you create your own protocol compiler binary and you want
+// it to support C++ output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator {
+ public:
+ CppGenerator();
+ ~CppGenerator();
+
+ // implements CodeGenerator ----------------------------------------
+ bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* generator_context,
+ string* error) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc
new file mode 100644
index 0000000..c4b868c
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -0,0 +1,407 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <limits>
+#include <map>
+#include <vector>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+string DotsToUnderscores(const string& name) {
+ return StringReplace(name, ".", "_", true);
+}
+
+string DotsToColons(const string& name) {
+ return StringReplace(name, ".", "::", true);
+}
+
+const char* const kKeywordList[] = {
+ "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case",
+ "catch", "char", "class", "compl", "const", "const_cast", "continue",
+ "default", "delete", "do", "double", "dynamic_cast", "else", "enum",
+ "explicit", "extern", "false", "float", "for", "friend", "goto", "if",
+ "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq",
+ "operator", "or", "or_eq", "private", "protected", "public", "register",
+ "reinterpret_cast", "return", "short", "signed", "sizeof", "static",
+ "static_cast", "struct", "switch", "template", "this", "throw", "true", "try",
+ "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual",
+ "void", "volatile", "wchar_t", "while", "xor", "xor_eq"
+};
+
+hash_set<string> MakeKeywordsMap() {
+ hash_set<string> result;
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) {
+ result.insert(kKeywordList[i]);
+ }
+ return result;
+}
+
+hash_set<string> kKeywords = MakeKeywordsMap();
+
+string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
+ string result;
+ // Note: I distrust ctype.h due to locales.
+ for (int i = 0; i < input.size(); i++) {
+ if ('a' <= input[i] && input[i] <= 'z') {
+ if (cap_next_letter) {
+ result += input[i] + ('A' - 'a');
+ } else {
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('A' <= input[i] && input[i] <= 'Z') {
+ // Capital letters are left as-is.
+ result += input[i];
+ cap_next_letter = false;
+ } else if ('0' <= input[i] && input[i] <= '9') {
+ result += input[i];
+ cap_next_letter = true;
+ } else {
+ cap_next_letter = true;
+ }
+ }
+ return result;
+}
+
+// Returns whether the provided descriptor has an extension. This includes its
+// nested types.
+bool HasExtension(const Descriptor* descriptor) {
+ if (descriptor->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ if (HasExtension(descriptor->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+const char kThickSeparator[] =
+ "// ===================================================================\n";
+const char kThinSeparator[] =
+ "// -------------------------------------------------------------------\n";
+
+string ClassName(const Descriptor* descriptor, bool qualified) {
+
+ // Find "outer", the descriptor of the top-level message in which
+ // "descriptor" is embedded.
+ const Descriptor* outer = descriptor;
+ while (outer->containing_type() != NULL) outer = outer->containing_type();
+
+ const string& outer_name = outer->full_name();
+ string inner_name = descriptor->full_name().substr(outer_name.size());
+
+ if (qualified) {
+ return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name);
+ } else {
+ return outer->name() + DotsToUnderscores(inner_name);
+ }
+}
+
+string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) {
+ if (enum_descriptor->containing_type() == NULL) {
+ if (qualified) {
+ return DotsToColons(enum_descriptor->full_name());
+ } else {
+ return enum_descriptor->name();
+ }
+ } else {
+ string result = ClassName(enum_descriptor->containing_type(), qualified);
+ result += '_';
+ result += enum_descriptor->name();
+ return result;
+ }
+}
+
+
+string SuperClassName(const Descriptor* descriptor) {
+ return HasDescriptorMethods(descriptor->file()) ?
+ "::google::protobuf::Message" : "::google::protobuf::MessageLite";
+}
+
+string FieldName(const FieldDescriptor* field) {
+ string result = field->name();
+ LowerString(&result);
+ if (kKeywords.count(result) > 0) {
+ result.append("_");
+ }
+ return result;
+}
+
+string FieldConstantName(const FieldDescriptor *field) {
+ string field_name = UnderscoresToCamelCase(field->name(), true);
+ string result = "k" + field_name + "FieldNumber";
+
+ if (!field->is_extension() &&
+ field->containing_type()->FindFieldByCamelcaseName(
+ field->camelcase_name()) != field) {
+ // This field's camelcase name is not unique. As a hack, add the field
+ // number to the constant name. This makes the constant rather useless,
+ // but what can we do?
+ result += "_" + SimpleItoa(field->number());
+ }
+
+ return result;
+}
+
+string FieldMessageTypeName(const FieldDescriptor* field) {
+ // Note: The Google-internal version of Protocol Buffers uses this function
+ // as a hook point for hacks to support legacy code.
+ return ClassName(field->message_type(), true);
+}
+
+string StripProto(const string& filename) {
+ if (HasSuffixString(filename, ".protodevel")) {
+ return StripSuffixString(filename, ".protodevel");
+ } else {
+ return StripSuffixString(filename, ".proto");
+ }
+}
+
+const char* PrimitiveTypeName(FieldDescriptor::CppType type) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32 : return "::google::protobuf::int32";
+ case FieldDescriptor::CPPTYPE_INT64 : return "::google::protobuf::int64";
+ case FieldDescriptor::CPPTYPE_UINT32 : return "::google::protobuf::uint32";
+ case FieldDescriptor::CPPTYPE_UINT64 : return "::google::protobuf::uint64";
+ case FieldDescriptor::CPPTYPE_DOUBLE : return "double";
+ case FieldDescriptor::CPPTYPE_FLOAT : return "float";
+ case FieldDescriptor::CPPTYPE_BOOL : return "bool";
+ case FieldDescriptor::CPPTYPE_ENUM : return "int";
+ case FieldDescriptor::CPPTYPE_STRING : return "::std::string";
+ case FieldDescriptor::CPPTYPE_MESSAGE: return NULL;
+
+ // No default because we want the compiler to complain if any new
+ // CppTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32 : return "Int32";
+ case FieldDescriptor::TYPE_INT64 : return "Int64";
+ case FieldDescriptor::TYPE_UINT32 : return "UInt32";
+ case FieldDescriptor::TYPE_UINT64 : return "UInt64";
+ case FieldDescriptor::TYPE_SINT32 : return "SInt32";
+ case FieldDescriptor::TYPE_SINT64 : return "SInt64";
+ case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
+ case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
+ case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
+ case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
+ case FieldDescriptor::TYPE_FLOAT : return "Float";
+ case FieldDescriptor::TYPE_DOUBLE : return "Double";
+
+ case FieldDescriptor::TYPE_BOOL : return "Bool";
+ case FieldDescriptor::TYPE_ENUM : return "Enum";
+
+ case FieldDescriptor::TYPE_STRING : return "String";
+ case FieldDescriptor::TYPE_BYTES : return "Bytes";
+ case FieldDescriptor::TYPE_GROUP : return "Group";
+ case FieldDescriptor::TYPE_MESSAGE : return "Message";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+string DefaultValue(const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return SimpleItoa(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return SimpleItoa(field->default_value_uint32()) + "u";
+ case FieldDescriptor::CPPTYPE_INT64:
+ return "GOOGLE_LONGLONG(" + SimpleItoa(field->default_value_int64()) + ")";
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field->default_value_double();
+ if (value == numeric_limits<double>::infinity()) {
+ return "::google::protobuf::internal::Infinity()";
+ } else if (value == -numeric_limits<double>::infinity()) {
+ return "-::google::protobuf::internal::Infinity()";
+ } else if (value != value) {
+ return "::google::protobuf::internal::NaN()";
+ } else {
+ return SimpleDtoa(value);
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ {
+ float value = field->default_value_float();
+ if (value == numeric_limits<float>::infinity()) {
+ return "static_cast<float>(::google::protobuf::internal::Infinity())";
+ } else if (value == -numeric_limits<float>::infinity()) {
+ return "static_cast<float>(-::google::protobuf::internal::Infinity())";
+ } else if (value != value) {
+ return "static_cast<float>(::google::protobuf::internal::NaN())";
+ } else {
+ string float_value = SimpleFtoa(value);
+ // If floating point value contains a period (.) or an exponent
+ // (either E or e), then append suffix 'f' to make it a float
+ // literal.
+ if (float_value.find_first_of(".eE") != string::npos) {
+ float_value.push_back('f');
+ }
+ return float_value;
+ }
+ }
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ // Lazy: Generate a static_cast because we don't have a helper function
+ // that constructs the full name of an enum value.
+ return strings::Substitute(
+ "static_cast< $0 >($1)",
+ ClassName(field->enum_type(), true),
+ field->default_value_enum()->number());
+ case FieldDescriptor::CPPTYPE_STRING:
+ return "\"" + EscapeTrigraphs(CEscape(field->default_value_string())) +
+ "\"";
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return FieldMessageTypeName(field) + "::default_instance()";
+ }
+ // Can't actually get here; make compiler happy. (We could add a default
+ // case above but then we wouldn't get the nice compiler warning when a
+ // new type is added.)
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+// Convert a file name into a valid identifier.
+string FilenameIdentifier(const string& filename) {
+ string result;
+ for (int i = 0; i < filename.size(); i++) {
+ if (ascii_isalnum(filename[i])) {
+ result.push_back(filename[i]);
+ } else {
+ // Not alphanumeric. To avoid any possibility of name conflicts we
+ // use the hex code for the character.
+ result.push_back('_');
+ char buffer[kFastToBufferSize];
+ result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer));
+ }
+ }
+ return result;
+}
+
+// Return the name of the AddDescriptors() function for a given file.
+string GlobalAddDescriptorsName(const string& filename) {
+ return "protobuf_AddDesc_" + FilenameIdentifier(filename);
+}
+
+// Return the name of the AssignDescriptors() function for a given file.
+string GlobalAssignDescriptorsName(const string& filename) {
+ return "protobuf_AssignDesc_" + FilenameIdentifier(filename);
+}
+
+// Return the name of the ShutdownFile() function for a given file.
+string GlobalShutdownFileName(const string& filename) {
+ return "protobuf_ShutdownFile_" + FilenameIdentifier(filename);
+}
+
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape) {
+ return StringReplace(to_escape, "?", "\\?", true);
+}
+
+bool StaticInitializersForced(const FileDescriptor* file) {
+ if (HasDescriptorMethods(file) || file->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasExtension(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void PrintHandlingOptionalStaticInitializers(
+ const FileDescriptor* file, io::Printer* printer,
+ const char* with_static_init, const char* without_static_init,
+ const char* var1, const string& val1,
+ const char* var2, const string& val2) {
+ map<string, string> vars;
+ if (var1) {
+ vars[var1] = val1;
+ }
+ if (var2) {
+ vars[var2] = val2;
+ }
+ PrintHandlingOptionalStaticInitializers(
+ vars, file, printer, with_static_init, without_static_init);
+}
+
+void PrintHandlingOptionalStaticInitializers(
+ const map<string, string>& vars, const FileDescriptor* file,
+ io::Printer* printer, const char* with_static_init,
+ const char* without_static_init) {
+ if (StaticInitializersForced(file)) {
+ printer->Print(vars, with_static_init);
+ } else {
+ printer->Print(vars, (string(
+ "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n") +
+ without_static_init +
+ "#else\n" +
+ with_static_init +
+ "#endif\n").c_str());
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h
new file mode 100644
index 0000000..690fbec
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -0,0 +1,182 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+class Printer;
+}
+
+namespace compiler {
+namespace cpp {
+
+// Commonly-used separator comments. Thick is a line of '=', thin is a line
+// of '-'.
+extern const char kThickSeparator[];
+extern const char kThinSeparator[];
+
+// Returns the non-nested type name for the given type. If "qualified" is
+// true, prefix the type with the full namespace. For example, if you had:
+// package foo.bar;
+// message Baz { message Qux {} }
+// Then the qualified ClassName for Qux would be:
+// ::foo::bar::Baz_Qux
+// While the non-qualified version would be:
+// Baz_Qux
+string ClassName(const Descriptor* descriptor, bool qualified);
+string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
+
+string SuperClassName(const Descriptor* descriptor);
+
+// Get the (unqualified) name that should be used for this field in C++ code.
+// The name is coerced to lower-case to emulate proto1 behavior. People
+// should be using lowercase-with-underscores style for proto field names
+// anyway, so normally this just returns field->name().
+string FieldName(const FieldDescriptor* field);
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(const FieldDescriptor *field);
+
+// Returns the scope where the field was defined (for extensions, this is
+// different from the message type to which the field applies).
+inline const Descriptor* FieldScope(const FieldDescriptor* field) {
+ return field->is_extension() ?
+ field->extension_scope() : field->containing_type();
+}
+
+// Returns the fully-qualified type name field->message_type(). Usually this
+// is just ClassName(field->message_type(), true);
+string FieldMessageTypeName(const FieldDescriptor* field);
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+string StripProto(const string& filename);
+
+// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
+// Note: non-built-in type names will be qualified, meaning they will start
+// with a ::. If you are using the type as a template parameter, you will
+// need to insure there is a space between the < and the ::, because the
+// ridiculous C++ standard defines "<:" to be a synonym for "[".
+const char* PrimitiveTypeName(FieldDescriptor::CppType type);
+
+// Get the declared type name in CamelCase format, as is used e.g. for the
+// methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
+const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
+
+// Get code that evaluates to the field's default value.
+string DefaultValue(const FieldDescriptor* field);
+
+// Convert a file name into a valid identifier.
+string FilenameIdentifier(const string& filename);
+
+// Return the name of the AddDescriptors() function for a given file.
+string GlobalAddDescriptorsName(const string& filename);
+
+// Return the name of the AssignDescriptors() function for a given file.
+string GlobalAssignDescriptorsName(const string& filename);
+
+// Return the name of the ShutdownFile() function for a given file.
+string GlobalShutdownFileName(const string& filename);
+
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape);
+
+// Do message classes in this file keep track of unknown fields?
+inline bool HasUnknownFields(const FileDescriptor *file) {
+ return file->options().optimize_for() != FileOptions::LITE_RUNTIME ||
+ file->options().retain_unknown_fields();
+}
+
+// Does this file have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+inline bool HasGeneratedMethods(const FileDescriptor *file) {
+ return file->options().optimize_for() != FileOptions::CODE_SIZE;
+}
+
+// Do message classes in this file have descriptor and refelction methods?
+inline bool HasDescriptorMethods(const FileDescriptor *file) {
+ return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor *file) {
+ return file->service_count() > 0 &&
+ file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
+ file->options().cc_generic_services();
+}
+
+// Should string fields in this file verify that their contents are UTF-8?
+inline bool HasUtf8Verification(const FileDescriptor* file) {
+ return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate a separate, super-optimized code path for serializing to
+// flat arrays? We don't do this in Lite mode because we'd rather reduce code
+// size.
+inline bool HasFastArraySerialization(const FileDescriptor* file) {
+ return file->options().optimize_for() == FileOptions::SPEED;
+}
+
+// Returns whether we have to generate code with static initializers.
+bool StaticInitializersForced(const FileDescriptor* file);
+
+// Prints 'with_static_init' if static initializers have to be used for the
+// provided file. Otherwise emits both 'with_static_init' and
+// 'without_static_init' using #ifdef.
+void PrintHandlingOptionalStaticInitializers(
+ const FileDescriptor* file, io::Printer* printer,
+ const char* with_static_init, const char* without_static_init,
+ const char* var1 = NULL, const string& val1 = "",
+ const char* var2 = NULL, const string& val2 = "");
+
+void PrintHandlingOptionalStaticInitializers(
+ const map<string, string>& vars, const FileDescriptor* file,
+ io::Printer* printer, const char* with_static_init,
+ const char* without_static_init);
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
new file mode 100644
index 0000000..4248747
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -0,0 +1,1992 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
+#include <map>
+#include <utility>
+#include <vector>
+#include <google/protobuf/compiler/cpp/cpp_message.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_enum.h>
+#include <google/protobuf/compiler/cpp/cpp_extension.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
+ // Print the field's proto-syntax definition as a comment. We don't want to
+ // print group bodies so we cut off after the first line.
+ string def = field->DebugString();
+ printer->Print("// $def$\n",
+ "def", def.substr(0, def.find_first_of('\n')));
+}
+
+struct FieldOrderingByNumber {
+ inline bool operator()(const FieldDescriptor* a,
+ const FieldDescriptor* b) const {
+ return a->number() < b->number();
+ }
+};
+
+const char* kWireTypeNames[] = {
+ "VARINT",
+ "FIXED64",
+ "LENGTH_DELIMITED",
+ "START_GROUP",
+ "END_GROUP",
+ "FIXED32",
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
+ const FieldDescriptor** fields =
+ new const FieldDescriptor*[descriptor->field_count()];
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields[i] = descriptor->field(i);
+ }
+ sort(fields, fields + descriptor->field_count(),
+ FieldOrderingByNumber());
+ return fields;
+}
+
+// Functor for sorting extension ranges by their "start" field number.
+struct ExtensionRangeSorter {
+ bool operator()(const Descriptor::ExtensionRange* left,
+ const Descriptor::ExtensionRange* right) const {
+ return left->start < right->start;
+ }
+};
+
+// Returns true if the message type has any required fields. If it doesn't,
+// we can optimize out calls to its IsInitialized() method.
+//
+// already_seen is used to avoid checking the same type multiple times
+// (and also to protect against recursion).
+static bool HasRequiredFields(
+ const Descriptor* type,
+ hash_set<const Descriptor*>* already_seen) {
+ if (already_seen->count(type) > 0) {
+ // Since the first occurrence of a required field causes the whole
+ // function to return true, we can assume that if the type is already
+ // in the cache it didn't have any required fields.
+ return false;
+ }
+ already_seen->insert(type);
+
+ // If the type has extensions, an extension with message type could contain
+ // required fields, so we have to be conservative and assume such an
+ // extension exists.
+ if (type->extension_range_count() > 0) return true;
+
+ for (int i = 0; i < type->field_count(); i++) {
+ const FieldDescriptor* field = type->field(i);
+ if (field->is_required()) {
+ return true;
+ }
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (HasRequiredFields(field->message_type(), already_seen)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool HasRequiredFields(const Descriptor* type) {
+ hash_set<const Descriptor*> already_seen;
+ return HasRequiredFields(type, &already_seen);
+}
+
+// This returns an estimate of the compiler's alignment for the field. This
+// can't guarantee to be correct because the generated code could be compiled on
+// different systems with different alignment rules. The estimates below assume
+// 64-bit pointers.
+int EstimateAlignmentSize(const FieldDescriptor* field) {
+ if (field == NULL) return 0;
+ if (field->is_repeated()) return 8;
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return 1;
+
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return 4;
+
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return 8;
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1; // Make compiler happy.
+}
+
+// FieldGroup is just a helper for OptimizePadding below. It holds a vector of
+// fields that are grouped together because they have compatible alignment, and
+// a preferred location in the final field ordering.
+class FieldGroup {
+ public:
+ FieldGroup()
+ : preferred_location_(0) {}
+
+ // A group with a single field.
+ FieldGroup(float preferred_location, const FieldDescriptor* field)
+ : preferred_location_(preferred_location),
+ fields_(1, field) {}
+
+ // Append the fields in 'other' to this group.
+ void Append(const FieldGroup& other) {
+ if (other.fields_.empty()) {
+ return;
+ }
+ // Preferred location is the average among all the fields, so we weight by
+ // the number of fields on each FieldGroup object.
+ preferred_location_ =
+ (preferred_location_ * fields_.size() +
+ (other.preferred_location_ * other.fields_.size())) /
+ (fields_.size() + other.fields_.size());
+ fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
+ }
+
+ void SetPreferredLocation(float location) { preferred_location_ = location; }
+ const vector<const FieldDescriptor*>& fields() const { return fields_; }
+
+ // FieldGroup objects sort by their preferred location.
+ bool operator<(const FieldGroup& other) const {
+ return preferred_location_ < other.preferred_location_;
+ }
+
+ private:
+ // "preferred_location_" is an estimate of where this group should go in the
+ // final list of fields. We compute this by taking the average index of each
+ // field in this group in the original ordering of fields. This is very
+ // approximate, but should put this group close to where its member fields
+ // originally went.
+ float preferred_location_;
+ vector<const FieldDescriptor*> fields_;
+ // We rely on the default copy constructor and operator= so this type can be
+ // used in a vector.
+};
+
+// Reorder 'fields' so that if the fields are output into a c++ class in the new
+// order, the alignment padding is minimized. We try to do this while keeping
+// each field as close as possible to its original position so that we don't
+// reduce cache locality much for function that access each field in order.
+void OptimizePadding(vector<const FieldDescriptor*>* fields) {
+ // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
+ vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
+ for (int i = 0; i < fields->size(); ++i) {
+ switch (EstimateAlignmentSize((*fields)[i])) {
+ case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
+ case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
+ case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
+ default:
+ GOOGLE_LOG(FATAL) << "Unknown alignment size.";
+ }
+ }
+
+ // Now group fields aligned to 1 byte into sets of 4, and treat those like a
+ // single field aligned to 4 bytes.
+ for (int i = 0; i < aligned_to_1.size(); i += 4) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
+ field_group.Append(aligned_to_1[j]);
+ }
+ aligned_to_4.push_back(field_group);
+ }
+ // Sort by preferred location to keep fields as close to their original
+ // location as possible.
+ sort(aligned_to_4.begin(), aligned_to_4.end());
+
+ // Now group fields aligned to 4 bytes (or the 4-field groups created above)
+ // into pairs, and treat those like a single field aligned to 8 bytes.
+ for (int i = 0; i < aligned_to_4.size(); i += 2) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
+ field_group.Append(aligned_to_4[j]);
+ }
+ if (i == aligned_to_4.size() - 1) {
+ // Move incomplete 4-byte block to the end.
+ field_group.SetPreferredLocation(fields->size() + 1);
+ }
+ aligned_to_8.push_back(field_group);
+ }
+ // Sort by preferred location to keep fields as close to their original
+ // location as possible.
+ sort(aligned_to_8.begin(), aligned_to_8.end());
+
+ // Now pull out all the FieldDescriptors in order.
+ fields->clear();
+ for (int i = 0; i < aligned_to_8.size(); ++i) {
+ fields->insert(fields->end(),
+ aligned_to_8[i].fields().begin(),
+ aligned_to_8[i].fields().end());
+ }
+}
+
+}
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor,
+ const string& dllexport_decl)
+ : descriptor_(descriptor),
+ classname_(ClassName(descriptor, false)),
+ dllexport_decl_(dllexport_decl),
+ field_generators_(descriptor),
+ nested_generators_(new scoped_ptr<MessageGenerator>[
+ descriptor->nested_type_count()]),
+ enum_generators_(new scoped_ptr<EnumGenerator>[
+ descriptor->enum_type_count()]),
+ extension_generators_(new scoped_ptr<ExtensionGenerator>[
+ descriptor->extension_count()]) {
+
+ for (int i = 0; i < descriptor->nested_type_count(); i++) {
+ nested_generators_[i].reset(
+ new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
+ }
+
+ for (int i = 0; i < descriptor->enum_type_count(); i++) {
+ enum_generators_[i].reset(
+ new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
+ }
+
+ for (int i = 0; i < descriptor->extension_count(); i++) {
+ extension_generators_[i].reset(
+ new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
+ }
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::
+GenerateForwardDeclaration(io::Printer* printer) {
+ printer->Print("class $classname$;\n",
+ "classname", classname_);
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateForwardDeclaration(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateEnumDefinitions(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateEnumDefinitions(printer);
+ }
+
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateDefinition(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateFieldAccessorDeclarations(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ PrintFieldComment(printer, field);
+
+ map<string, string> vars;
+ SetCommonFieldVariables(field, &vars);
+ vars["constant_name"] = FieldConstantName(field);
+
+ if (field->is_repeated()) {
+ printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
+ } else {
+ printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
+ }
+
+ printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
+ printer->Print(vars, "static const int $constant_name$ = $number$;\n");
+
+ // Generate type-specific accessor declarations.
+ field_generators_.get(field).GenerateAccessorDeclarations(printer);
+
+ printer->Print("\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ // Generate accessors for extensions. We just call a macro located in
+ // extension_set.h since the accessors about 80 lines of static code.
+ printer->Print(
+ "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
+ "classname", classname_);
+ }
+}
+
+void MessageGenerator::
+GenerateFieldAccessorDefinitions(io::Printer* printer) {
+ printer->Print("// $classname$\n\n", "classname", classname_);
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ PrintFieldComment(printer, field);
+
+ map<string, string> vars;
+ SetCommonFieldVariables(field, &vars);
+
+ // Generate has_$name$() or $name$_size().
+ if (field->is_repeated()) {
+ printer->Print(vars,
+ "inline int $classname$::$name$_size() const {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ } else {
+ // Singular field.
+ char buffer[kFastToBufferSize];
+ vars["has_array_index"] = SimpleItoa(field->index() / 32);
+ vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer);
+ printer->Print(vars,
+ "inline bool $classname$::has_$name$() const {\n"
+ " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
+ "}\n"
+ "inline void $classname$::set_has_$name$() {\n"
+ " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
+ "}\n"
+ "inline void $classname$::clear_has_$name$() {\n"
+ " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
+ "}\n"
+ );
+ }
+
+ // Generate clear_$name$()
+ printer->Print(vars,
+ "inline void $classname$::clear_$name$() {\n");
+
+ printer->Indent();
+ field_generators_.get(field).GenerateClearingCode(printer);
+ printer->Outdent();
+
+ if (!field->is_repeated()) {
+ printer->Print(vars,
+ " clear_has_$name$();\n");
+ }
+
+ printer->Print("}\n");
+
+ // Generate type-specific accessors.
+ field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
+
+ printer->Print("\n");
+ }
+}
+
+void MessageGenerator::
+GenerateClassDefinition(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateClassDefinition(printer);
+ printer->Print("\n");
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+
+ map<string, string> vars;
+ vars["classname"] = classname_;
+ vars["field_count"] = SimpleItoa(descriptor_->field_count());
+ if (dllexport_decl_.empty()) {
+ vars["dllexport"] = "";
+ } else {
+ vars["dllexport"] = dllexport_decl_ + " ";
+ }
+ vars["superclass"] = SuperClassName(descriptor_);
+
+ printer->Print(vars,
+ "class $dllexport$$classname$ : public $superclass$ {\n"
+ " public:\n");
+ printer->Indent();
+
+ printer->Print(vars,
+ "$classname$();\n"
+ "virtual ~$classname$();\n"
+ "\n"
+ "$classname$(const $classname$& from);\n"
+ "\n"
+ "inline $classname$& operator=(const $classname$& from) {\n"
+ " CopyFrom(from);\n"
+ " return *this;\n"
+ "}\n"
+ "\n");
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
+ " return _unknown_fields_;\n"
+ "}\n"
+ "\n"
+ "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
+ " return &_unknown_fields_;\n"
+ "}\n"
+ "\n");
+ }
+
+ // Only generate this member if it's not disabled.
+ if (HasDescriptorMethods(descriptor_->file()) &&
+ !descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(vars,
+ "static const ::google::protobuf::Descriptor* descriptor();\n");
+ }
+
+ printer->Print(vars,
+ "static const $classname$& default_instance();\n"
+ "\n");
+
+ if (!StaticInitializersForced(descriptor_->file())) {
+ printer->Print(vars,
+ "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
+ "// Returns the internal default instance pointer. This function can\n"
+ "// return NULL thus should not be used by the user. This is intended\n"
+ "// for Protobuf internal code. Please use default_instance() declared\n"
+ "// above instead.\n"
+ "static inline const $classname$* internal_default_instance() {\n"
+ " return default_instance_;\n"
+ "}\n"
+ "#endif\n"
+ "\n");
+ }
+
+ printer->Print(vars,
+ "void Swap($classname$* other);\n"
+ "\n"
+ "// implements Message ----------------------------------------------\n"
+ "\n"
+ "$classname$* New() const;\n");
+
+ if (HasGeneratedMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "void CopyFrom(const ::google::protobuf::Message& from);\n"
+ "void MergeFrom(const ::google::protobuf::Message& from);\n");
+ } else {
+ printer->Print(vars,
+ "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
+ }
+
+ printer->Print(vars,
+ "void CopyFrom(const $classname$& from);\n"
+ "void MergeFrom(const $classname$& from);\n"
+ "void Clear();\n"
+ "bool IsInitialized() const;\n"
+ "\n"
+ "int ByteSize() const;\n"
+ "bool MergePartialFromCodedStream(\n"
+ " ::google::protobuf::io::CodedInputStream* input);\n"
+ "void SerializeWithCachedSizes(\n"
+ " ::google::protobuf::io::CodedOutputStream* output) const;\n");
+ if (HasFastArraySerialization(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
+ }
+ }
+
+ printer->Print(vars,
+ "int GetCachedSize() const { return _cached_size_; }\n"
+ "private:\n"
+ "void SharedCtor();\n"
+ "void SharedDtor();\n"
+ "void SetCachedSize(int size) const;\n"
+ "public:\n"
+ "\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::Metadata GetMetadata() const;\n"
+ "\n");
+ } else {
+ printer->Print(
+ "::std::string GetTypeName() const;\n"
+ "\n");
+ }
+
+ printer->Print(
+ "// nested types ----------------------------------------------------\n"
+ "\n");
+
+ // Import all nested message classes into this class's scope with typedefs.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ const Descriptor* nested_type = descriptor_->nested_type(i);
+ printer->Print("typedef $nested_full_name$ $nested_name$;\n",
+ "nested_name", nested_type->name(),
+ "nested_full_name", ClassName(nested_type, false));
+ }
+
+ if (descriptor_->nested_type_count() > 0) {
+ printer->Print("\n");
+ }
+
+ // Import all nested enums and their values into this class's scope with
+ // typedefs and constants.
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateSymbolImports(printer);
+ printer->Print("\n");
+ }
+
+ printer->Print(
+ "// accessors -------------------------------------------------------\n"
+ "\n");
+
+ // Generate accessor methods for all fields.
+ GenerateFieldAccessorDeclarations(printer);
+
+ // Declare extension identifiers.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_[i]->GenerateDeclaration(printer);
+ }
+
+
+ printer->Print(
+ "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ // Generate private members.
+ printer->Outdent();
+ printer->Print(" private:\n");
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->is_repeated()) {
+ printer->Print(
+ "inline void set_has_$name$();\n",
+ "name", FieldName(descriptor_->field(i)));
+ printer->Print(
+ "inline void clear_has_$name$();\n",
+ "name", FieldName(descriptor_->field(i)));
+ }
+ }
+ printer->Print("\n");
+
+ // To minimize padding, data members are divided into three sections:
+ // (1) members assumed to align to 8 bytes
+ // (2) members corresponding to message fields, re-ordered to optimize
+ // alignment.
+ // (3) members assumed to align to 4 bytes.
+
+ // Members assumed to align to 8 bytes:
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "::google::protobuf::internal::ExtensionSet _extensions_;\n"
+ "\n");
+ }
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
+ "\n");
+ }
+
+ // Field members:
+
+ vector<const FieldDescriptor*> fields;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ fields.push_back(descriptor_->field(i));
+ }
+ OptimizePadding(&fields);
+ for (int i = 0; i < fields.size(); ++i) {
+ field_generators_.get(fields[i]).GeneratePrivateMembers(printer);
+ }
+
+ // Members assumed to align to 4 bytes:
+
+ // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
+ printer->Print(
+ "\n"
+ "mutable int _cached_size_;\n");
+
+ // Generate _has_bits_.
+ if (descriptor_->field_count() > 0) {
+ printer->Print(vars,
+ "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n"
+ "\n");
+ } else {
+ // Zero-size arrays aren't technically allowed, and MSVC in particular
+ // doesn't like them. We still need to declare these arrays to make
+ // other code compile. Since this is an uncommon case, we'll just declare
+ // them with size 1 and waste some space. Oh well.
+ printer->Print(
+ "::google::protobuf::uint32 _has_bits_[1];\n"
+ "\n");
+ }
+
+ // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
+ // friends so that they can access private static variables like
+ // default_instance_ and reflection_.
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ "friend void $dllexport_decl$ $adddescriptorsname$();\n",
+ // Without.
+ "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
+ // Vars.
+ "dllexport_decl", dllexport_decl_,
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+
+ printer->Print(
+ "friend void $assigndescriptorsname$();\n"
+ "friend void $shutdownfilename$();\n"
+ "\n",
+ "assigndescriptorsname",
+ GlobalAssignDescriptorsName(descriptor_->file()->name()),
+ "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
+
+ printer->Print(
+ "void InitAsDefaultInstance();\n"
+ "static $classname$* default_instance_;\n",
+ "classname", classname_);
+
+ printer->Outdent();
+ printer->Print(vars, "};");
+}
+
+void MessageGenerator::
+GenerateInlineMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateInlineMethods(printer);
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+
+ GenerateFieldAccessorDefinitions(printer);
+}
+
+void MessageGenerator::
+GenerateDescriptorDeclarations(io::Printer* printer) {
+ printer->Print(
+ "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
+ "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
+ " $name$_reflection_ = NULL;\n",
+ "name", classname_);
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateDescriptorDeclarations(printer);
+ }
+
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ printer->Print(
+ "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
+ "name", ClassName(descriptor_->enum_type(i), false));
+ }
+}
+
+void MessageGenerator::
+GenerateDescriptorInitializer(io::Printer* printer, int index) {
+ // TODO(kenton): Passing the index to this method is redundant; just use
+ // descriptor_->index() instead.
+ map<string, string> vars;
+ vars["classname"] = classname_;
+ vars["index"] = SimpleItoa(index);
+
+ // Obtain the descriptor from the parent's descriptor.
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(vars,
+ "$classname$_descriptor_ = file->message_type($index$);\n");
+ } else {
+ vars["parent"] = ClassName(descriptor_->containing_type(), false);
+ printer->Print(vars,
+ "$classname$_descriptor_ = "
+ "$parent$_descriptor_->nested_type($index$);\n");
+ }
+
+ // Generate the offsets.
+ GenerateOffsets(printer);
+
+ // Construct the reflection object.
+ printer->Print(vars,
+ "$classname$_reflection_ =\n"
+ " new ::google::protobuf::internal::GeneratedMessageReflection(\n"
+ " $classname$_descriptor_,\n"
+ " $classname$::default_instance_,\n"
+ " $classname$_offsets_,\n"
+ " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
+ " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+ "$classname$, _unknown_fields_),\n");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(vars,
+ " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+ "$classname$, _extensions_),\n");
+ } else {
+ // No extensions.
+ printer->Print(vars,
+ " -1,\n");
+ }
+ printer->Print(vars,
+ " ::google::protobuf::DescriptorPool::generated_pool(),\n"
+ " ::google::protobuf::MessageFactory::generated_factory(),\n"
+ " sizeof($classname$));\n");
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+}
+
+void MessageGenerator::
+GenerateTypeRegistrations(io::Printer* printer) {
+ // Register this message type with the message factory.
+ printer->Print(
+ "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
+ " $classname$_descriptor_, &$classname$::default_instance());\n",
+ "classname", classname_);
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateTypeRegistrations(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateDefaultInstanceAllocator(io::Printer* printer) {
+ // Construct the default instance. We can't call InitAsDefaultInstance() yet
+ // because we need to make sure all default instances that this one might
+ // depend on are constructed first.
+ printer->Print(
+ "$classname$::default_instance_ = new $classname$();\n",
+ "classname", classname_);
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
+ }
+
+}
+
+void MessageGenerator::
+GenerateDefaultInstanceInitializer(io::Printer* printer) {
+ printer->Print(
+ "$classname$::default_instance_->InitAsDefaultInstance();\n",
+ "classname", classname_);
+
+ // Register extensions.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_[i]->GenerateRegistration(printer);
+ }
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateShutdownCode(io::Printer* printer) {
+ printer->Print(
+ "delete $classname$::default_instance_;\n",
+ "classname", classname_);
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "delete $classname$_reflection_;\n",
+ "classname", classname_);
+ }
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateShutdownCode(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateClassMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateMethods(printer);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateClassMethods(printer);
+ printer->Print("\n");
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+
+ // Generate non-inline field definitions.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateNonInlineAccessorDefinitions(printer);
+ }
+
+ // Generate field number constants.
+ printer->Print("#ifndef _MSC_VER\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor *field = descriptor_->field(i);
+ printer->Print(
+ "const int $classname$::$constant_name$;\n",
+ "classname", ClassName(FieldScope(field), false),
+ "constant_name", FieldConstantName(field));
+ }
+ printer->Print(
+ "#endif // !_MSC_VER\n"
+ "\n");
+
+ // Define extension identifiers.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_[i]->GenerateDefinition(printer);
+ }
+
+ GenerateStructors(printer);
+ printer->Print("\n");
+
+ if (HasGeneratedMethods(descriptor_->file())) {
+ GenerateClear(printer);
+ printer->Print("\n");
+
+ GenerateMergeFromCodedStream(printer);
+ printer->Print("\n");
+
+ GenerateSerializeWithCachedSizes(printer);
+ printer->Print("\n");
+
+ if (HasFastArraySerialization(descriptor_->file())) {
+ GenerateSerializeWithCachedSizesToArray(printer);
+ printer->Print("\n");
+ }
+
+ GenerateByteSize(printer);
+ printer->Print("\n");
+
+ GenerateMergeFrom(printer);
+ printer->Print("\n");
+
+ GenerateCopyFrom(printer);
+ printer->Print("\n");
+
+ GenerateIsInitialized(printer);
+ printer->Print("\n");
+ }
+
+ GenerateSwap(printer);
+ printer->Print("\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " ::google::protobuf::Metadata metadata;\n"
+ " metadata.descriptor = $classname$_descriptor_;\n"
+ " metadata.reflection = $classname$_reflection_;\n"
+ " return metadata;\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+ } else {
+ printer->Print(
+ "::std::string $classname$::GetTypeName() const {\n"
+ " return \"$type_name$\";\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "type_name", descriptor_->full_name());
+ }
+
+}
+
+void MessageGenerator::
+GenerateOffsets(io::Printer* printer) {
+ printer->Print(
+ "static const int $classname$_offsets_[$field_count$] = {\n",
+ "classname", classname_,
+ "field_count", SimpleItoa(max(1, descriptor_->field_count())));
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ printer->Print(
+ "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
+ "classname", classname_,
+ "name", FieldName(field));
+ }
+
+ printer->Outdent();
+ printer->Print("};\n");
+}
+
+void MessageGenerator::
+GenerateSharedConstructorCode(io::Printer* printer) {
+ printer->Print(
+ "void $classname$::SharedCtor() {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ printer->Print(
+ "_cached_size_ = 0;\n");
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateConstructorCode(printer);
+ }
+
+ printer->Print(
+ "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void MessageGenerator::
+GenerateSharedDestructorCode(io::Printer* printer) {
+ printer->Print(
+ "void $classname$::SharedDtor() {\n",
+ "classname", classname_);
+ printer->Indent();
+ // Write the destructors for each field.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateDestructorCode(printer);
+ }
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ "if (this != default_instance_) {\n",
+ // Without.
+ "if (this != &default_instance()) {\n");
+
+ // We need to delete all embedded messages.
+ // TODO(kenton): If we make unset messages point at default instances
+ // instead of NULL, then it would make sense to move this code into
+ // MessageFieldGenerator::GenerateDestructorCode().
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(" delete $name$_;\n",
+ "name", FieldName(field));
+ }
+ }
+
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void MessageGenerator::
+GenerateStructors(io::Printer* printer) {
+ string superclass = SuperClassName(descriptor_);
+
+ // Generate the default constructor.
+ printer->Print(
+ "$classname$::$classname$()\n"
+ " : $superclass$() {\n"
+ " SharedCtor();\n"
+ "}\n",
+ "classname", classname_,
+ "superclass", superclass);
+
+ printer->Print(
+ "\n"
+ "void $classname$::InitAsDefaultInstance() {\n",
+ "classname", classname_);
+
+ // The default instance needs all of its embedded message pointers
+ // cross-linked to other default instances. We can't do this initialization
+ // in the constructor because some other default instances may not have been
+ // constructed yet at that time.
+ // TODO(kenton): Maybe all message fields (even for non-default messages)
+ // should be initialized to point at default instances rather than NULL?
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
+ // Without.
+ " $name$_ = const_cast< $type$*>(\n"
+ " $type$::internal_default_instance());\n",
+ // Vars.
+ "name", FieldName(field),
+ "type", FieldMessageTypeName(field));
+ }
+ }
+ printer->Print(
+ "}\n"
+ "\n");
+
+ // Generate the copy constructor.
+ printer->Print(
+ "$classname$::$classname$(const $classname$& from)\n"
+ " : $superclass$() {\n"
+ " SharedCtor();\n"
+ " MergeFrom(from);\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "superclass", superclass);
+
+ // Generate the shared constructor code.
+ GenerateSharedConstructorCode(printer);
+
+ // Generate the destructor.
+ printer->Print(
+ "$classname$::~$classname$() {\n"
+ " SharedDtor();\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+
+ // Generate the shared destructor code.
+ GenerateSharedDestructorCode(printer);
+
+ // Generate SetCachedSize.
+ printer->Print(
+ "void $classname$::SetCachedSize(int size) const {\n"
+ " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+ " _cached_size_ = size;\n"
+ " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+ "}\n",
+ "classname", classname_);
+
+ // Only generate this member if it's not disabled.
+ if (HasDescriptorMethods(descriptor_->file()) &&
+ !descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(
+ "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+ }
+
+ printer->Print(
+ "const $classname$& $classname$::default_instance() {\n",
+ "classname", classname_);
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " if (default_instance_ == NULL) $adddescriptorsname$();\n",
+ // Without.
+ " $adddescriptorsname$();\n",
+ // Vars.
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+
+ printer->Print(
+ " return *default_instance_;\n"
+ "}\n"
+ "\n"
+ "$classname$* $classname$::default_instance_ = NULL;\n"
+ "\n"
+ "$classname$* $classname$::New() const {\n"
+ " return new $classname$;\n"
+ "}\n",
+ "classname", classname_,
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+}
+
+void MessageGenerator::
+GenerateClear(io::Printer* printer) {
+ printer->Print("void $classname$::Clear() {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ int last_index = -1;
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print("_extensions_.Clear();\n");
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated()) {
+ // We can use the fact that _has_bits_ is a giant bitfield to our
+ // advantage: We can check up to 32 bits at a time for equality to
+ // zero, and skip the whole range if so. This can improve the speed
+ // of Clear() for messages which contain a very large number of
+ // optional fields of which only a few are used at a time. Here,
+ // we've chosen to check 8 bits at a time rather than 32.
+ if (i / 8 != last_index / 8 || last_index < 0) {
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print(
+ "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+ "index", SimpleItoa(field->index()));
+ printer->Indent();
+ }
+ last_index = i;
+
+ // It's faster to just overwrite primitive types, but we should
+ // only clear strings and messages if they were set.
+ // TODO(kenton): Let the CppFieldGenerator decide this somehow.
+ bool should_check_bit =
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
+
+ if (should_check_bit) {
+ printer->Print(
+ "if (has_$name$()) {\n",
+ "name", FieldName(field));
+ printer->Indent();
+ }
+
+ field_generators_.get(field).GenerateClearingCode(printer);
+
+ if (should_check_bit) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+ }
+
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ // Repeated fields don't use _has_bits_ so we clear them in a separate
+ // pass.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (field->is_repeated()) {
+ field_generators_.get(field).GenerateClearingCode(printer);
+ }
+ }
+
+ printer->Print(
+ "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "mutable_unknown_fields()->Clear();\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateSwap(io::Printer* printer) {
+ // Generate the Swap member function.
+ printer->Print("void $classname$::Swap($classname$* other) {\n",
+ "classname", classname_);
+ printer->Indent();
+ printer->Print("if (other != this) {\n");
+ printer->Indent();
+
+ if (HasGeneratedMethods(descriptor_->file())) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ field_generators_.get(field).GenerateSwappingCode(printer);
+ }
+
+ for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
+ printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
+ "i", SimpleItoa(i));
+ }
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
+ }
+ printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print("_extensions_.Swap(&other->_extensions_);\n");
+ }
+ } else {
+ printer->Print("GetReflection()->Swap(this, other);");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateMergeFrom(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ // Generate the generalized MergeFrom (aka that which takes in the Message
+ // base class as a parameter).
+ printer->Print(
+ "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
+ " GOOGLE_CHECK_NE(&from, this);\n",
+ "classname", classname_);
+ printer->Indent();
+
+ // Cast the message to the proper type. If we find that the message is
+ // *not* of the proper type, we can still call Merge via the reflection
+ // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
+ // for each message.
+ printer->Print(
+ "const $classname$* source =\n"
+ " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
+ " &from);\n"
+ "if (source == NULL) {\n"
+ " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
+ "} else {\n"
+ " MergeFrom(*source);\n"
+ "}\n",
+ "classname", classname_);
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+ } else {
+ // Generate CheckTypeAndMergeFrom().
+ printer->Print(
+ "void $classname$::CheckTypeAndMergeFrom(\n"
+ " const ::google::protobuf::MessageLite& from) {\n"
+ " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+ }
+
+ // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
+ printer->Print(
+ "void $classname$::MergeFrom(const $classname$& from) {\n"
+ " GOOGLE_CHECK_NE(&from, this);\n",
+ "classname", classname_);
+ printer->Indent();
+
+ // Merge Repeated fields. These fields do not require a
+ // check as we can simply iterate over them.
+ for (int i = 0; i < descriptor_->field_count(); ++i) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (field->is_repeated()) {
+ field_generators_.get(field).GenerateMergingCode(printer);
+ }
+ }
+
+ // Merge Optional and Required fields (after a _has_bit check).
+ int last_index = -1;
+
+ for (int i = 0; i < descriptor_->field_count(); ++i) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated()) {
+ // See above in GenerateClear for an explanation of this.
+ if (i / 8 != last_index / 8 || last_index < 0) {
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print(
+ "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+ "index", SimpleItoa(field->index()));
+ printer->Indent();
+ }
+
+ last_index = i;
+
+ printer->Print(
+ "if (from.has_$name$()) {\n",
+ "name", FieldName(field));
+ printer->Indent();
+
+ field_generators_.get(field).GenerateMergingCode(printer);
+
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
+ }
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateCopyFrom(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ // Generate the generalized CopyFrom (aka that which takes in the Message
+ // base class as a parameter).
+ printer->Print(
+ "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ printer->Print(
+ "if (&from == this) return;\n"
+ "Clear();\n"
+ "MergeFrom(from);\n");
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+ }
+
+ // Generate the class-specific CopyFrom.
+ printer->Print(
+ "void $classname$::CopyFrom(const $classname$& from) {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ printer->Print(
+ "if (&from == this) return;\n"
+ "Clear();\n"
+ "MergeFrom(from);\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "bool $classname$::MergePartialFromCodedStream(\n"
+ " ::google::protobuf::io::CodedInputStream* input) {\n",
+ "classname", classname_);
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " return _extensions_.ParseMessageSet(input, default_instance_,\n"
+ " mutable_unknown_fields());\n",
+ // Without.
+ " return _extensions_.ParseMessageSet(input, &default_instance(),\n"
+ " mutable_unknown_fields());\n",
+ // Vars.
+ "classname", classname_);
+
+ printer->Print(
+ "}\n");
+ return;
+ }
+
+ printer->Print(
+ "bool $classname$::MergePartialFromCodedStream(\n"
+ " ::google::protobuf::io::CodedInputStream* input) {\n"
+ "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
+ " ::google::protobuf::uint32 tag;\n"
+ " while ((tag = input->ReadTag()) != 0) {\n",
+ "classname", classname_);
+
+ printer->Indent();
+ printer->Indent();
+
+ if (descriptor_->field_count() > 0) {
+ // We don't even want to print the switch() if we have no fields because
+ // MSVC dislikes switch() statements that contain only a default value.
+
+ // Note: If we just switched on the tag rather than the field number, we
+ // could avoid the need for the if() to check the wire type at the beginning
+ // of each case. However, this is actually a bit slower in practice as it
+ // creates a jump table that is 8x larger and sparser, and meanwhile the
+ // if()s are highly predictable.
+ printer->Print(
+ "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
+
+ printer->Indent();
+
+ scoped_array<const FieldDescriptor*> ordered_fields(
+ SortFieldsByNumber(descriptor_));
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = ordered_fields[i];
+
+ PrintFieldComment(printer, field);
+
+ printer->Print(
+ "case $number$: {\n",
+ "number", SimpleItoa(field->number()));
+ printer->Indent();
+ const FieldGenerator& field_generator = field_generators_.get(field);
+
+ // Emit code to parse the common, expected case.
+ printer->Print(
+ "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n",
+ "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
+
+ if (i > 0 || (field->is_repeated() && !field->options().packed())) {
+ printer->Print(
+ " parse_$name$:\n",
+ "name", field->name());
+ }
+
+ printer->Indent();
+ if (field->options().packed()) {
+ field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
+ } else {
+ field_generator.GenerateMergeFromCodedStream(printer);
+ }
+ printer->Outdent();
+
+ // Emit code to parse unexpectedly packed or unpacked values.
+ if (field->is_packable() && field->options().packed()) {
+ printer->Print(
+ "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
+ " == ::google::protobuf::internal::WireFormatLite::\n"
+ " WIRETYPE_$wiretype$) {\n",
+ "wiretype",
+ kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]);
+ printer->Indent();
+ field_generator.GenerateMergeFromCodedStream(printer);
+ printer->Outdent();
+ } else if (field->is_packable() && !field->options().packed()) {
+ printer->Print(
+ "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
+ " == ::google::protobuf::internal::WireFormatLite::\n"
+ " WIRETYPE_LENGTH_DELIMITED) {\n");
+ printer->Indent();
+ field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
+ printer->Outdent();
+ }
+
+ printer->Print(
+ "} else {\n"
+ " goto handle_uninterpreted;\n"
+ "}\n");
+
+ // switch() is slow since it can't be predicted well. Insert some if()s
+ // here that attempt to predict the next tag.
+ if (field->is_repeated() && !field->options().packed()) {
+ // Expect repeats of this field.
+ printer->Print(
+ "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
+ "tag", SimpleItoa(WireFormat::MakeTag(field)),
+ "name", field->name());
+ }
+
+ if (i + 1 < descriptor_->field_count()) {
+ // Expect the next field in order.
+ const FieldDescriptor* next_field = ordered_fields[i + 1];
+ printer->Print(
+ "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
+ "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
+ "next_name", next_field->name());
+ } else {
+ // Expect EOF.
+ // TODO(kenton): Expect group end-tag?
+ printer->Print(
+ "if (input->ExpectAtEnd()) return true;\n");
+ }
+
+ printer->Print(
+ "break;\n");
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+ }
+
+ printer->Print(
+ "default: {\n"
+ "handle_uninterpreted:\n");
+ printer->Indent();
+ }
+
+ // Is this an end-group tag? If so, this must be the end of the message.
+ printer->Print(
+ "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
+ " return true;\n"
+ "}\n");
+
+ // Handle extension ranges.
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "if (");
+ for (int i = 0; i < descriptor_->extension_range_count(); i++) {
+ const Descriptor::ExtensionRange* range =
+ descriptor_->extension_range(i);
+ if (i > 0) printer->Print(" ||\n ");
+
+ uint32 start_tag = WireFormatLite::MakeTag(
+ range->start, static_cast<WireFormatLite::WireType>(0));
+ uint32 end_tag = WireFormatLite::MakeTag(
+ range->end, static_cast<WireFormatLite::WireType>(0));
+
+ if (range->end > FieldDescriptor::kMaxNumber) {
+ printer->Print(
+ "($start$u <= tag)",
+ "start", SimpleItoa(start_tag));
+ } else {
+ printer->Print(
+ "($start$u <= tag && tag < $end$u)",
+ "start", SimpleItoa(start_tag),
+ "end", SimpleItoa(end_tag));
+ }
+ }
+ printer->Print(") {\n");
+ if (HasUnknownFields(descriptor_->file())) {
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
+ " mutable_unknown_fields()));\n",
+ // Without.
+ " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
+ " mutable_unknown_fields()));\n");
+ } else {
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " DO_(_extensions_.ParseField(tag, input, default_instance_, NULL));\n",
+ // Without.
+ " DO_(_extensions_.ParseField(tag, input, &default_instance(), NULL));\n");
+ }
+ printer->Print(
+ " continue;\n"
+ "}\n");
+ }
+
+ // We really don't recognize this tag. Skip it.
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));\n");
+ } else {
+ printer->Print(
+ "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, NULL));\n");
+ }
+
+ if (descriptor_->field_count() > 0) {
+ printer->Print("break;\n");
+ printer->Outdent();
+ printer->Print("}\n"); // default:
+ printer->Outdent();
+ printer->Print("}\n"); // switch
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n" // while
+ " return true;\n"
+ "#undef DO_\n"
+ "}\n");
+}
+
+void MessageGenerator::GenerateSerializeOneField(
+ io::Printer* printer, const FieldDescriptor* field, bool to_array) {
+ PrintFieldComment(printer, field);
+
+ if (!field->is_repeated()) {
+ printer->Print(
+ "if (has_$name$()) {\n",
+ "name", FieldName(field));
+ printer->Indent();
+ }
+
+ if (to_array) {
+ field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
+ printer);
+ } else {
+ field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
+ }
+
+ if (!field->is_repeated()) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print("\n");
+}
+
+void MessageGenerator::GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range,
+ bool to_array) {
+ map<string, string> vars;
+ vars["start"] = SimpleItoa(range->start);
+ vars["end"] = SimpleItoa(range->end);
+ printer->Print(vars,
+ "// Extension range [$start$, $end$)\n");
+ if (to_array) {
+ printer->Print(vars,
+ "target = _extensions_.SerializeWithCachedSizesToArray(\n"
+ " $start$, $end$, target);\n\n");
+ } else {
+ printer->Print(vars,
+ "_extensions_.SerializeWithCachedSizes(\n"
+ " $start$, $end$, output);\n\n");
+ }
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "void $classname$::SerializeWithCachedSizes(\n"
+ " ::google::protobuf::io::CodedOutputStream* output) const {\n"
+ " _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
+ "classname", classname_);
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ " ::google::protobuf::internal::WireFormatLite::SerializeUnknownMessageSetItems(\n"
+ " unknown_fields(), output);\n");
+ }
+ printer->Print(
+ "}\n");
+ return;
+ }
+
+ printer->Print(
+ "void $classname$::SerializeWithCachedSizes(\n"
+ " ::google::protobuf::io::CodedOutputStream* output) const {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ GenerateSerializeWithCachedSizesBody(printer, false);
+
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
+ " ::google::protobuf::uint8* target) const {\n"
+ " target =\n"
+ " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
+ "classname", classname_);
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " SerializeUnknownMessageSetItemsToArray(\n"
+ " unknown_fields(), target);\n");
+ }
+ printer->Print(
+ " return target;\n"
+ "}\n");
+ return;
+ }
+
+ printer->Print(
+ "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
+ " ::google::protobuf::uint8* target) const {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ GenerateSerializeWithCachedSizesBody(printer, true);
+
+ printer->Outdent();
+ printer->Print(
+ " return target;\n"
+ "}\n");
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
+ scoped_array<const FieldDescriptor*> ordered_fields(
+ SortFieldsByNumber(descriptor_));
+
+ vector<const Descriptor::ExtensionRange*> sorted_extensions;
+ for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+ sorted_extensions.push_back(descriptor_->extension_range(i));
+ }
+ sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeSorter());
+
+ // Merge the fields and the extension ranges, both sorted by field number.
+ int i, j;
+ for (i = 0, j = 0;
+ i < descriptor_->field_count() || j < sorted_extensions.size();
+ ) {
+ if (i == descriptor_->field_count()) {
+ GenerateSerializeOneExtensionRange(printer,
+ sorted_extensions[j++],
+ to_array);
+ } else if (j == sorted_extensions.size()) {
+ GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
+ } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
+ GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
+ } else {
+ GenerateSerializeOneExtensionRange(printer,
+ sorted_extensions[j++],
+ to_array);
+ }
+ }
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print("if (!unknown_fields().empty()) {\n");
+ printer->Indent();
+ if (to_array) {
+ printer->Print(
+ "target = "
+ "::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(\n"
+ " unknown_fields(), target);\n");
+ } else {
+ printer->Print(
+ "::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(\n"
+ " unknown_fields(), output);\n");
+ }
+ printer->Outdent();
+
+ printer->Print(
+ "}\n");
+ }
+}
+
+void MessageGenerator::
+GenerateByteSize(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "int $classname$::ByteSize() const {\n"
+ " int total_size = _extensions_.MessageSetByteSize();\n",
+ "classname", classname_);
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print(
+ " total_size += ::google::protobuf::internal::WireFormatLite::\n"
+ " ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
+ }
+ printer->Print(
+ " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+ " _cached_size_ = total_size;\n"
+ " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+ " return total_size;\n"
+ "}\n");
+ return;
+ }
+
+ printer->Print(
+ "int $classname$::ByteSize() const {\n",
+ "classname", classname_);
+ printer->Indent();
+ printer->Print(
+ "int total_size = 0;\n"
+ "\n");
+
+ int last_index = -1;
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated()) {
+ // See above in GenerateClear for an explanation of this.
+ // TODO(kenton): Share code? Unclear how to do so without
+ // over-engineering.
+ if ((i / 8) != (last_index / 8) ||
+ last_index < 0) {
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print(
+ "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+ "index", SimpleItoa(field->index()));
+ printer->Indent();
+ }
+ last_index = i;
+
+ PrintFieldComment(printer, field);
+
+ printer->Print(
+ "if (has_$name$()) {\n",
+ "name", FieldName(field));
+ printer->Indent();
+
+ field_generators_.get(field).GenerateByteSize(printer);
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+ }
+ }
+
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ // Repeated fields don't use _has_bits_ so we count them in a separate
+ // pass.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (field->is_repeated()) {
+ PrintFieldComment(printer, field);
+ field_generators_.get(field).GenerateByteSize(printer);
+ printer->Print("\n");
+ }
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "total_size += _extensions_.ByteSize();\n"
+ "\n");
+ }
+
+ if (HasUnknownFields(descriptor_->file())) {
+ printer->Print("if (!unknown_fields().empty()) {\n");
+ printer->Indent();
+ printer->Print(
+ "total_size +=\n"
+ " ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(\n"
+ " unknown_fields());\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ // We update _cached_size_ even though this is a const method. In theory,
+ // this is not thread-compatible, because concurrent writes have undefined
+ // results. In practice, since any concurrent writes will be writing the
+ // exact same value, it works on all common processors. In a future version
+ // of C++, _cached_size_ should be made into an atomic<int>.
+ printer->Print(
+ "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+ "_cached_size_ = total_size;\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+ "return total_size;\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateIsInitialized(io::Printer* printer) {
+ printer->Print(
+ "bool $classname$::IsInitialized() const {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ // Check that all required fields in this message are set. We can do this
+ // most efficiently by checking 32 "has bits" at a time.
+ int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
+ for (int i = 0; i < has_bits_array_size; i++) {
+ uint32 mask = 0;
+ for (int bit = 0; bit < 32; bit++) {
+ int index = i * 32 + bit;
+ if (index >= descriptor_->field_count()) break;
+ const FieldDescriptor* field = descriptor_->field(index);
+
+ if (field->is_required()) {
+ mask |= 1 << bit;
+ }
+ }
+
+ if (mask != 0) {
+ char buffer[kFastToBufferSize];
+ printer->Print(
+ "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
+ "i", SimpleItoa(i),
+ "mask", FastHex32ToBuffer(mask, buffer));
+ }
+ }
+
+ // Now check that all embedded messages are initialized.
+ printer->Print("\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ HasRequiredFields(field->message_type())) {
+ if (field->is_repeated()) {
+ printer->Print(
+ "for (int i = 0; i < $name$_size(); i++) {\n"
+ " if (!this->$name$(i).IsInitialized()) return false;\n"
+ "}\n",
+ "name", FieldName(field));
+ } else {
+ printer->Print(
+ "if (has_$name$()) {\n"
+ " if (!this->$name$().IsInitialized()) return false;\n"
+ "}\n",
+ "name", FieldName(field));
+ }
+ }
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "\n"
+ "if (!_extensions_.IsInitialized()) return false;");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ " return true;\n"
+ "}\n");
+}
+
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h
new file mode 100644
index 0000000..04778f6
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -0,0 +1,170 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator; // enum.h
+class ExtensionGenerator; // extension.h
+
+class MessageGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit MessageGenerator(const Descriptor* descriptor,
+ const string& dllexport_decl);
+ ~MessageGenerator();
+
+ // Header stuff.
+
+ // Generate foward declarations for this class and all its nested types.
+ void GenerateForwardDeclaration(io::Printer* printer);
+
+ // Generate definitions of all nested enums (must come before class
+ // definitions because those classes use the enums definitions).
+ void GenerateEnumDefinitions(io::Printer* printer);
+
+ // Generate specializations of GetEnumDescriptor<MyEnum>().
+ // Precondition: in ::google::protobuf namespace.
+ void GenerateGetEnumDescriptorSpecializations(io::Printer* printer);
+
+ // Generate definitions for this class and all its nested types.
+ void GenerateClassDefinition(io::Printer* printer);
+
+ // Generate definitions of inline methods (placed at the end of the header
+ // file).
+ void GenerateInlineMethods(io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate code which declares all the global descriptor pointers which
+ // will be initialized by the methods below.
+ void GenerateDescriptorDeclarations(io::Printer* printer);
+
+ // Generate code that initializes the global variable storing the message's
+ // descriptor.
+ void GenerateDescriptorInitializer(io::Printer* printer, int index);
+
+ // Generate code that calls MessageFactory::InternalRegisterGeneratedMessage()
+ // for all types.
+ void GenerateTypeRegistrations(io::Printer* printer);
+
+ // Generates code that allocates the message's default instance.
+ void GenerateDefaultInstanceAllocator(io::Printer* printer);
+
+ // Generates code that initializes the message's default instance. This
+ // is separate from allocating because all default instances must be
+ // allocated before any can be initialized.
+ void GenerateDefaultInstanceInitializer(io::Printer* printer);
+
+ // Generates code that should be run when ShutdownProtobufLibrary() is called,
+ // to delete all dynamically-allocated objects.
+ void GenerateShutdownCode(io::Printer* printer);
+
+ // Generate all non-inline methods for this class.
+ void GenerateClassMethods(io::Printer* printer);
+
+ private:
+ // Generate declarations and definitions of accessors for fields.
+ void GenerateFieldAccessorDeclarations(io::Printer* printer);
+ void GenerateFieldAccessorDefinitions(io::Printer* printer);
+
+ // Generate the field offsets array.
+ void GenerateOffsets(io::Printer* printer);
+
+ // Generate constructors and destructor.
+ void GenerateStructors(io::Printer* printer);
+
+ // The compiler typically generates multiple copies of each constructor and
+ // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx
+ // Placing common code in a separate method reduces the generated code size.
+ //
+ // Generate the shared constructor code.
+ void GenerateSharedConstructorCode(io::Printer* printer);
+ // Generate the shared destructor code.
+ void GenerateSharedDestructorCode(io::Printer* printer);
+
+ // Generate standard Message methods.
+ void GenerateClear(io::Printer* printer);
+ void GenerateMergeFromCodedStream(io::Printer* printer);
+ void GenerateSerializeWithCachedSizes(io::Printer* printer);
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer);
+ void GenerateSerializeWithCachedSizesBody(io::Printer* printer,
+ bool to_array);
+ void GenerateByteSize(io::Printer* printer);
+ void GenerateMergeFrom(io::Printer* printer);
+ void GenerateCopyFrom(io::Printer* printer);
+ void GenerateSwap(io::Printer* printer);
+ void GenerateIsInitialized(io::Printer* printer);
+
+ // Helpers for GenerateSerializeWithCachedSizes().
+ void GenerateSerializeOneField(io::Printer* printer,
+ const FieldDescriptor* field,
+ bool unbounded);
+ void GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range,
+ bool unbounded);
+
+
+ const Descriptor* descriptor_;
+ string classname_;
+ string dllexport_decl_;
+ FieldGeneratorMap field_generators_;
+ scoped_array<scoped_ptr<MessageGenerator> > nested_generators_;
+ scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
+ scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc
new file mode 100644
index 0000000..7c785e7
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -0,0 +1,285 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_message_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetMessageVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables) {
+ SetCommonFieldVariables(descriptor, variables);
+ (*variables)["type"] = FieldMessageTypeName(descriptor);
+ (*variables)["stream_writer"] = (*variables)["declared_type"] +
+ (HasFastArraySerialization(descriptor->message_type()->file()) ?
+ "MaybeToArray" :
+ "");
+}
+
+} // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::
+MessageFieldGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ SetMessageVariables(descriptor, &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "$type$* $name$_;\n");
+}
+
+void MessageFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $name$() const$deprecation$;\n"
+ "inline $type$* mutable_$name$()$deprecation$;\n"
+ "inline $type$* release_$name$()$deprecation$;\n");
+}
+
+void MessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $classname$::$name$() const {\n");
+
+ PrintHandlingOptionalStaticInitializers(
+ variables_, descriptor_->file(), printer,
+ // With static initializers.
+ " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
+ // Without.
+ " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
+
+ printer->Print(variables_,
+ "}\n"
+ "inline $type$* $classname$::mutable_$name$() {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == NULL) $name$_ = new $type$;\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline $type$* $classname$::release_$name$() {\n"
+ " clear_has_$name$();\n"
+ " $type$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($name$_ != NULL) $name$_->$type$::Clear();\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
+}
+
+void MessageFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void MessageFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = NULL;\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
+ " input, mutable_$name$()));\n");
+ } else {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
+ " $number$, input, mutable_$name$()));\n");
+ }
+}
+
+void MessageFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
+ " $number$, this->$name$(), output);\n");
+}
+
+void MessageFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoVirtualToArray(\n"
+ " $number$, this->$name$(), target);\n");
+}
+
+void MessageFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
+ " this->$name$());\n");
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ SetMessageVariables(descriptor, &variables_);
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $name$(int index) const$deprecation$;\n"
+ "inline $type$* mutable_$name$(int index)$deprecation$;\n"
+ "inline $type$* add_$name$()$deprecation$;\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ " $name$() const$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ " mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $classname$::$name$(int index) const {\n"
+ " return $name$_.Get(index);\n"
+ "}\n"
+ "inline $type$* $classname$::mutable_$name$(int index) {\n"
+ " return $name$_.Mutable(index);\n"
+ "}\n"
+ "inline $type$* $classname$::add_$name$() {\n"
+ " return $name$_.Add();\n"
+ "}\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ "$classname$::$name$() const {\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
+ " input, add_$name$()));\n");
+ } else {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
+ " $number$, input, add_$name$()));\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
+ " $number$, this->$name$(i), output);\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoVirtualToArray(\n"
+ " $number$, this->$name$(i), target);\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size();\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " total_size +=\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
+ " this->$name$(i));\n"
+ "}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h
new file mode 100644
index 0000000..f514727
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -0,0 +1,102 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class MessageFieldGenerator : public FieldGenerator {
+ public:
+ explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
+ ~MessageFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+};
+
+class RepeatedMessageFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
+ ~RepeatedMessageFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
new file mode 100644
index 0000000..5c4aa4f
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// TODO(kenton): Share code with the versions of this test in other languages?
+// It seemed like parameterizing it would add more complexity than it is
+// worth.
+
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/printer.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+ TestGenerator() {}
+ ~TestGenerator() {}
+
+ virtual bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+ TryInsert("test.pb.h", "includes", context);
+ TryInsert("test.pb.h", "namespace_scope", context);
+ TryInsert("test.pb.h", "global_scope", context);
+ TryInsert("test.pb.h", "class_scope:foo.Bar", context);
+ TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context);
+
+ TryInsert("test.pb.cc", "includes", context);
+ TryInsert("test.pb.cc", "namespace_scope", context);
+ TryInsert("test.pb.cc", "global_scope", context);
+ return true;
+ }
+
+ void TryInsert(const string& filename, const string& insertion_point,
+ GeneratorContext* context) const {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(filename, insertion_point));
+ io::Printer printer(output.get(), '$');
+ printer.Print("// inserted $name$\n", "name", insertion_point);
+ }
+};
+
+// This test verifies that all the expected insertion points exist. It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(CppPluginTest, PluginTest) {
+ File::WriteStringToFileOrDie(
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ "}\n",
+ TestTempDir() + "/test.proto");
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ CppGenerator cpp_generator;
+ TestGenerator test_generator;
+ cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
+ cli.RegisterGenerator("--test_out", &test_generator, "");
+
+ string proto_path = "-I" + TestTempDir();
+ string cpp_out = "--cpp_out=" + TestTempDir();
+ string test_out = "--test_out=" + TestTempDir();
+
+ const char* argv[] = {
+ "protoc",
+ proto_path.c_str(),
+ cpp_out.c_str(),
+ test_out.c_str(),
+ "test.proto"
+ };
+
+ EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+} // namespace
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
new file mode 100644
index 0000000..5e8df0f
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -0,0 +1,382 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_primitive_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormatLite;
+
+namespace {
+
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32 : return -1;
+ case FieldDescriptor::TYPE_INT64 : return -1;
+ case FieldDescriptor::TYPE_UINT32 : return -1;
+ case FieldDescriptor::TYPE_UINT64 : return -1;
+ case FieldDescriptor::TYPE_SINT32 : return -1;
+ case FieldDescriptor::TYPE_SINT64 : return -1;
+ case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
+ case FieldDescriptor::TYPE_ENUM : return -1;
+
+ case FieldDescriptor::TYPE_STRING : return -1;
+ case FieldDescriptor::TYPE_BYTES : return -1;
+ case FieldDescriptor::TYPE_GROUP : return -1;
+ case FieldDescriptor::TYPE_MESSAGE : return -1;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables) {
+ SetCommonFieldVariables(descriptor, variables);
+ (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+ int fixed_size = FixedSize(descriptor->type());
+ if (fixed_size != -1) {
+ (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+ }
+ (*variables)["wire_format_field_type"] =
+ "::google::protobuf::internal::WireFormatLite::" + FieldDescriptorProto_Type_Name(
+ static_cast<FieldDescriptorProto_Type>(descriptor->type()));
+}
+
+} // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ SetPrimitiveVariables(descriptor, &variables_);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+void PrimitiveFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "$type$ $name$_;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $name$() const$deprecation$;\n"
+ "inline void set_$name$($type$ value)$deprecation$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$() const {\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " set_has_$name$();\n"
+ " $name$_ = value;\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " $type$, $wire_format_field_type$>(\n"
+ " input, &$name$_)));\n"
+ "set_has_$name$();\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormatLite::Write$declared_type$("
+ "$number$, this->$name$(), output);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "target = ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray("
+ "$number$, this->$name$(), target);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ int fixed_size = FixedSize(descriptor_->type());
+ if (fixed_size == -1) {
+ printer->Print(variables_,
+ "total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->$name$());\n");
+ } else {
+ printer->Print(variables_,
+ "total_size += $tag_size$ + $fixed_size$;\n");
+ }
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ SetPrimitiveVariables(descriptor, &variables_);
+
+ if (descriptor->options().packed()) {
+ variables_["packed_reader"] = "ReadPackedPrimitive";
+ variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline";
+ } else {
+ variables_["packed_reader"] = "ReadPackedPrimitiveNoInline";
+ variables_["repeated_reader"] = "ReadRepeatedPrimitive";
+ }
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+void RepeatedPrimitiveFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedField< $type$ > $name$_;\n");
+ if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
+ printer->Print(variables_,
+ "mutable int _$name$_cached_byte_size_;\n");
+ }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $name$(int index) const$deprecation$;\n"
+ "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
+ "inline void add_$name$($type$ value)$deprecation$;\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+ " $name$() const$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+ " mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$(int index) const {\n"
+ " return $name$_.Get(index);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+ " $name$_.Set(index, value);\n"
+ "}\n"
+ "inline void $classname$::add_$name$($type$ value) {\n"
+ " $name$_.Add(value);\n"
+ "}\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+ "$classname$::$name$() const {\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_((::google::protobuf::internal::WireFormatLite::$repeated_reader$<\n"
+ " $type$, $wire_format_field_type$>(\n"
+ " $tag_size$, $tag$, input, this->mutable_$name$())));\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_((::google::protobuf::internal::WireFormatLite::$packed_reader$<\n"
+ " $type$, $wire_format_field_type$>(\n"
+ " input, this->mutable_$name$())));\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " ::google::protobuf::internal::WireFormatLite::WriteTag("
+ "$number$, "
+ "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, "
+ "output);\n"
+ " output->WriteVarint32(_$name$_cached_byte_size_);\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoTag(\n"
+ " this->$name$(i), output);\n");
+ } else {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ " $number$, this->$name$(i), output);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " target);\n"
+ " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n"
+ " _$name$_cached_byte_size_, target);\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoTagToArray(this->$name$(i), target);\n");
+ } else {
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$ToArray($number$, this->$name$(i), target);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int data_size = 0;\n");
+ printer->Indent();
+ int fixed_size = FixedSize(descriptor_->type());
+ if (fixed_size == -1) {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " data_size += ::google::protobuf::internal::WireFormatLite::\n"
+ " $declared_type$Size(this->$name$(i));\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "data_size = $fixed_size$ * this->$name$_size();\n");
+ }
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (data_size > 0) {\n"
+ " total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
+ "}\n"
+ "_$name$_cached_byte_size_ = data_size;\n"
+ "total_size += data_size;\n");
+ } else {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
new file mode 100644
index 0000000..8fcd74a
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class PrimitiveFieldGenerator : public FieldGenerator {
+ public:
+ explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+ ~PrimitiveFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+};
+
+class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+ ~RepeatedPrimitiveFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc
new file mode 100644
index 0000000..c282568
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc
@@ -0,0 +1,334 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_service.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
+ const string& dllexport_decl)
+ : descriptor_(descriptor) {
+ vars_["classname"] = descriptor_->name();
+ vars_["full_name"] = descriptor_->full_name();
+ if (dllexport_decl.empty()) {
+ vars_["dllexport"] = "";
+ } else {
+ vars_["dllexport"] = dllexport_decl + " ";
+ }
+}
+
+ServiceGenerator::~ServiceGenerator() {}
+
+void ServiceGenerator::GenerateDeclarations(io::Printer* printer) {
+ // Forward-declare the stub type.
+ printer->Print(vars_,
+ "class $classname$_Stub;\n"
+ "\n");
+
+ GenerateInterface(printer);
+ GenerateStubDefinition(printer);
+}
+
+void ServiceGenerator::GenerateInterface(io::Printer* printer) {
+ printer->Print(vars_,
+ "class $dllexport$$classname$ : public ::google::protobuf::Service {\n"
+ " protected:\n"
+ " // This class should be treated as an abstract interface.\n"
+ " inline $classname$() {};\n"
+ " public:\n"
+ " virtual ~$classname$();\n");
+ printer->Indent();
+
+ printer->Print(vars_,
+ "\n"
+ "typedef $classname$_Stub Stub;\n"
+ "\n"
+ "static const ::google::protobuf::ServiceDescriptor* descriptor();\n"
+ "\n");
+
+ GenerateMethodSignatures(VIRTUAL, printer);
+
+ printer->Print(
+ "\n"
+ "// implements Service ----------------------------------------------\n"
+ "\n"
+ "const ::google::protobuf::ServiceDescriptor* GetDescriptor();\n"
+ "void CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
+ " ::google::protobuf::RpcController* controller,\n"
+ " const ::google::protobuf::Message* request,\n"
+ " ::google::protobuf::Message* response,\n"
+ " ::google::protobuf::Closure* done);\n"
+ "const ::google::protobuf::Message& GetRequestPrototype(\n"
+ " const ::google::protobuf::MethodDescriptor* method) const;\n"
+ "const ::google::protobuf::Message& GetResponsePrototype(\n"
+ " const ::google::protobuf::MethodDescriptor* method) const;\n");
+
+ printer->Outdent();
+ printer->Print(vars_,
+ "\n"
+ " private:\n"
+ " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
+ "};\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateStubDefinition(io::Printer* printer) {
+ printer->Print(vars_,
+ "class $dllexport$$classname$_Stub : public $classname$ {\n"
+ " public:\n");
+
+ printer->Indent();
+
+ printer->Print(vars_,
+ "$classname$_Stub(::google::protobuf::RpcChannel* channel);\n"
+ "$classname$_Stub(::google::protobuf::RpcChannel* channel,\n"
+ " ::google::protobuf::Service::ChannelOwnership ownership);\n"
+ "~$classname$_Stub();\n"
+ "\n"
+ "inline ::google::protobuf::RpcChannel* channel() { return channel_; }\n"
+ "\n"
+ "// implements $classname$ ------------------------------------------\n"
+ "\n");
+
+ GenerateMethodSignatures(NON_VIRTUAL, printer);
+
+ printer->Outdent();
+ printer->Print(vars_,
+ " private:\n"
+ " ::google::protobuf::RpcChannel* channel_;\n"
+ " bool owns_channel_;\n"
+ " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n"
+ "};\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateMethodSignatures(
+ VirtualOrNon virtual_or_non, io::Printer* printer) {
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ map<string, string> sub_vars;
+ sub_vars["name"] = method->name();
+ sub_vars["input_type"] = ClassName(method->input_type(), true);
+ sub_vars["output_type"] = ClassName(method->output_type(), true);
+ sub_vars["virtual"] = virtual_or_non == VIRTUAL ? "virtual " : "";
+
+ printer->Print(sub_vars,
+ "$virtual$void $name$(::google::protobuf::RpcController* controller,\n"
+ " const $input_type$* request,\n"
+ " $output_type$* response,\n"
+ " ::google::protobuf::Closure* done);\n");
+ }
+}
+
+// ===================================================================
+
+void ServiceGenerator::GenerateDescriptorInitializer(
+ io::Printer* printer, int index) {
+ map<string, string> vars;
+ vars["classname"] = descriptor_->name();
+ vars["index"] = SimpleItoa(index);
+
+ printer->Print(vars,
+ "$classname$_descriptor_ = file->service($index$);\n");
+}
+
+// ===================================================================
+
+void ServiceGenerator::GenerateImplementation(io::Printer* printer) {
+ printer->Print(vars_,
+ "$classname$::~$classname$() {}\n"
+ "\n"
+ "const ::google::protobuf::ServiceDescriptor* $classname$::descriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n"
+ "\n"
+ "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n"
+ "\n");
+
+ // Generate methods of the interface.
+ GenerateNotImplementedMethods(printer);
+ GenerateCallMethod(printer);
+ GenerateGetPrototype(REQUEST, printer);
+ GenerateGetPrototype(RESPONSE, printer);
+
+ // Generate stub implementation.
+ printer->Print(vars_,
+ "$classname$_Stub::$classname$_Stub(::google::protobuf::RpcChannel* channel)\n"
+ " : channel_(channel), owns_channel_(false) {}\n"
+ "$classname$_Stub::$classname$_Stub(\n"
+ " ::google::protobuf::RpcChannel* channel,\n"
+ " ::google::protobuf::Service::ChannelOwnership ownership)\n"
+ " : channel_(channel),\n"
+ " owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {}\n"
+ "$classname$_Stub::~$classname$_Stub() {\n"
+ " if (owns_channel_) delete channel_;\n"
+ "}\n"
+ "\n");
+
+ GenerateStubMethods(printer);
+}
+
+void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ map<string, string> sub_vars;
+ sub_vars["classname"] = descriptor_->name();
+ sub_vars["name"] = method->name();
+ sub_vars["index"] = SimpleItoa(i);
+ sub_vars["input_type"] = ClassName(method->input_type(), true);
+ sub_vars["output_type"] = ClassName(method->output_type(), true);
+
+ printer->Print(sub_vars,
+ "void $classname$::$name$(::google::protobuf::RpcController* controller,\n"
+ " const $input_type$*,\n"
+ " $output_type$*,\n"
+ " ::google::protobuf::Closure* done) {\n"
+ " controller->SetFailed(\"Method $name$() not implemented.\");\n"
+ " done->Run();\n"
+ "}\n"
+ "\n");
+ }
+}
+
+void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
+ printer->Print(vars_,
+ "void $classname$::CallMethod(const ::google::protobuf::MethodDescriptor* method,\n"
+ " ::google::protobuf::RpcController* controller,\n"
+ " const ::google::protobuf::Message* request,\n"
+ " ::google::protobuf::Message* response,\n"
+ " ::google::protobuf::Closure* done) {\n"
+ " GOOGLE_DCHECK_EQ(method->service(), $classname$_descriptor_);\n"
+ " switch(method->index()) {\n");
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ map<string, string> sub_vars;
+ sub_vars["name"] = method->name();
+ sub_vars["index"] = SimpleItoa(i);
+ sub_vars["input_type"] = ClassName(method->input_type(), true);
+ sub_vars["output_type"] = ClassName(method->output_type(), true);
+
+ // Note: down_cast does not work here because it only works on pointers,
+ // not references.
+ printer->Print(sub_vars,
+ " case $index$:\n"
+ " $name$(controller,\n"
+ " ::google::protobuf::down_cast<const $input_type$*>(request),\n"
+ " ::google::protobuf::down_cast< $output_type$*>(response),\n"
+ " done);\n"
+ " break;\n");
+ }
+
+ printer->Print(vars_,
+ " default:\n"
+ " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
+ " break;\n"
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
+ io::Printer* printer) {
+ if (which == REQUEST) {
+ printer->Print(vars_,
+ "const ::google::protobuf::Message& $classname$::GetRequestPrototype(\n");
+ } else {
+ printer->Print(vars_,
+ "const ::google::protobuf::Message& $classname$::GetResponsePrototype(\n");
+ }
+
+ printer->Print(vars_,
+ " const ::google::protobuf::MethodDescriptor* method) const {\n"
+ " GOOGLE_DCHECK_EQ(method->service(), descriptor());\n"
+ " switch(method->index()) {\n");
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ const Descriptor* type =
+ (which == REQUEST) ? method->input_type() : method->output_type();
+
+ map<string, string> sub_vars;
+ sub_vars["index"] = SimpleItoa(i);
+ sub_vars["type"] = ClassName(type, true);
+
+ printer->Print(sub_vars,
+ " case $index$:\n"
+ " return $type$::default_instance();\n");
+ }
+
+ printer->Print(vars_,
+ " default:\n"
+ " GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
+ " return *reinterpret_cast< ::google::protobuf::Message*>(NULL);\n"
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateStubMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ map<string, string> sub_vars;
+ sub_vars["classname"] = descriptor_->name();
+ sub_vars["name"] = method->name();
+ sub_vars["index"] = SimpleItoa(i);
+ sub_vars["input_type"] = ClassName(method->input_type(), true);
+ sub_vars["output_type"] = ClassName(method->output_type(), true);
+
+ printer->Print(sub_vars,
+ "void $classname$_Stub::$name$(::google::protobuf::RpcController* controller,\n"
+ " const $input_type$* request,\n"
+ " $output_type$* response,\n"
+ " ::google::protobuf::Closure* done) {\n"
+ " channel_->CallMethod(descriptor()->method($index$),\n"
+ " controller, request, response, done);\n"
+ "}\n");
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h
new file mode 100644
index 0000000..10e9dd3
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h
@@ -0,0 +1,118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class ServiceGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit ServiceGenerator(const ServiceDescriptor* descriptor,
+ const string& dllexport_decl);
+ ~ServiceGenerator();
+
+ // Header stuff.
+
+ // Generate the class definitions for the service's interface and the
+ // stub implementation.
+ void GenerateDeclarations(io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate code that initializes the global variable storing the service's
+ // descriptor.
+ void GenerateDescriptorInitializer(io::Printer* printer, int index);
+
+ // Generate implementations of everything declared by GenerateDeclarations().
+ void GenerateImplementation(io::Printer* printer);
+
+ private:
+ enum RequestOrResponse { REQUEST, RESPONSE };
+ enum VirtualOrNon { VIRTUAL, NON_VIRTUAL };
+
+ // Header stuff.
+
+ // Generate the service abstract interface.
+ void GenerateInterface(io::Printer* printer);
+
+ // Generate the stub class definition.
+ void GenerateStubDefinition(io::Printer* printer);
+
+ // Prints signatures for all methods in the
+ void GenerateMethodSignatures(VirtualOrNon virtual_or_non,
+ io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate the default implementations of the service methods, which
+ // produce a "not implemented" error.
+ void GenerateNotImplementedMethods(io::Printer* printer);
+
+ // Generate the CallMethod() method of the service.
+ void GenerateCallMethod(io::Printer* printer);
+
+ // Generate the Get{Request,Response}Prototype() methods.
+ void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
+
+ // Generate the stub's implementations of the service methods.
+ void GenerateStubMethods(io::Printer* printer);
+
+ const ServiceDescriptor* descriptor_;
+ map<string, string> vars_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc
new file mode 100644
index 0000000..3cec2b6
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -0,0 +1,454 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/cpp/cpp_string_field.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetStringVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables) {
+ SetCommonFieldVariables(descriptor, variables);
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_variable"] = descriptor->default_value_string().empty()
+ ? "::google::protobuf::internal::kEmptyString"
+ : "_default_" + FieldName(descriptor) + "_";
+ (*variables)["pointer_type"] =
+ descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
+}
+
+} // namespace
+
+// ===================================================================
+
+StringFieldGenerator::
+StringFieldGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ SetStringVariables(descriptor, &variables_);
+}
+
+StringFieldGenerator::~StringFieldGenerator() {}
+
+void StringFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "::std::string* $name$_;\n");
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_, "static const ::std::string $default_variable$;\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ // If we're using StringFieldGenerator for a field with a ctype, it's
+ // because that ctype isn't actually implemented. In particular, this is
+ // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
+ // We aren't releasing Cord because it has too many Google-specific
+ // dependencies and we aren't releasing StringPiece because it's hardly
+ // useful outside of Google and because it would get confusing to have
+ // multiple instances of the StringPiece class in different libraries (PCRE
+ // already includes it for their C++ bindings, which came from Google).
+ //
+ // In any case, we make all the accessors private while still actually
+ // using a string to represent the field internally. This way, we can
+ // guarantee that if we do ever implement the ctype, it won't break any
+ // existing users who might be -- for whatever reason -- already using .proto
+ // files that applied the ctype. The field can still be accessed via the
+ // reflection interface since the reflection interface is independent of
+ // the string's underlying representation.
+ if (descriptor_->options().ctype() != FieldOptions::STRING) {
+ printer->Outdent();
+ printer->Print(
+ " private:\n"
+ " // Hidden due to unknown ctype option.\n");
+ printer->Indent();
+ }
+
+ printer->Print(variables_,
+ "inline const ::std::string& $name$() const$deprecation$;\n"
+ "inline void set_$name$(const ::std::string& value)$deprecation$;\n"
+ "inline void set_$name$(const char* value)$deprecation$;\n"
+ "inline void set_$name$(const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n"
+ "inline ::std::string* mutable_$name$()$deprecation$;\n"
+ "inline ::std::string* release_$name$()$deprecation$;\n");
+
+ if (descriptor_->options().ctype() != FieldOptions::STRING) {
+ printer->Outdent();
+ printer->Print(" public:\n");
+ printer->Indent();
+ }
+}
+
+void StringFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const ::std::string& $classname$::$name$() const {\n"
+ " return *$name$_;\n"
+ "}\n"
+ "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n"
+ " $name$_ = new ::std::string;\n"
+ " }\n"
+ " $name$_->assign(value);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(const char* value) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n"
+ " $name$_ = new ::std::string;\n"
+ " }\n"
+ " $name$_->assign(value);\n"
+ "}\n"
+ "inline "
+ "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n"
+ " $name$_ = new ::std::string;\n"
+ " }\n"
+ " $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
+ "}\n"
+ "inline ::std::string* $classname$::mutable_$name$() {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n");
+ if (descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ " $name$_ = new ::std::string;\n");
+ } else {
+ printer->Print(variables_,
+ " $name$_ = new ::std::string($default_variable$);\n");
+ }
+ printer->Print(variables_,
+ " }\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::std::string* $classname$::release_$name$() {\n"
+ " clear_has_$name$();\n"
+ " if ($name$_ == &$default_variable$) {\n"
+ " return NULL;\n"
+ " } else {\n"
+ " ::std::string* temp = $name$_;\n"
+ " $name$_ = const_cast< ::std::string*>(&$default_variable$);\n"
+ " return temp;\n"
+ " }\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ "const ::std::string $classname$::$default_variable$($default$);\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ if (descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ "if ($name$_ != &$default_variable$) {\n"
+ " $name$_->clear();\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "if ($name$_ != &$default_variable$) {\n"
+ " $name$_->assign($default_variable$);\n"
+ "}\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void StringFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void StringFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = const_cast< ::std::string*>(&$default_variable$);\n");
+}
+
+void StringFieldGenerator::
+GenerateDestructorCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($name$_ != &$default_variable$) {\n"
+ " delete $name$_;\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+ " input, this->mutable_$name$()));\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::PARSE);\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ }
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ " $number$, this->$name$(), output);\n");
+}
+
+void StringFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ }
+ printer->Print(variables_,
+ "target =\n"
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n"
+ " $number$, this->$name$(), target);\n");
+}
+
+void StringFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->$name$());\n");
+}
+
+// ===================================================================
+
+RepeatedStringFieldGenerator::
+RepeatedStringFieldGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ SetStringVariables(descriptor, &variables_);
+}
+
+RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
+
+void RepeatedStringFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ // See comment above about unknown ctypes.
+ if (descriptor_->options().ctype() != FieldOptions::STRING) {
+ printer->Outdent();
+ printer->Print(
+ " private:\n"
+ " // Hidden due to unknown ctype option.\n");
+ printer->Indent();
+ }
+
+ printer->Print(variables_,
+ "inline const ::std::string& $name$(int index) const$deprecation$;\n"
+ "inline ::std::string* mutable_$name$(int index)$deprecation$;\n"
+ "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
+ "inline void set_$name$(int index, const char* value)$deprecation$;\n"
+ "inline "
+ "void set_$name$(int index, const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n"
+ "inline ::std::string* add_$name$()$deprecation$;\n"
+ "inline void add_$name$(const ::std::string& value)$deprecation$;\n"
+ "inline void add_$name$(const char* value)$deprecation$;\n"
+ "inline void add_$name$(const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n");
+
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
+ "$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
+ "$deprecation$;\n");
+
+ if (descriptor_->options().ctype() != FieldOptions::STRING) {
+ printer->Outdent();
+ printer->Print(" public:\n");
+ printer->Indent();
+ }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const ::std::string& $classname$::$name$(int index) const {\n"
+ " return $name$_.Get(index);\n"
+ "}\n"
+ "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
+ " return $name$_.Mutable(index);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
+ " $name$_.Mutable(index)->assign(value);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, const char* value) {\n"
+ " $name$_.Mutable(index)->assign(value);\n"
+ "}\n"
+ "inline void "
+ "$classname$::set_$name$"
+ "(int index, const $pointer_type$* value, size_t size) {\n"
+ " $name$_.Mutable(index)->assign(\n"
+ " reinterpret_cast<const char*>(value), size);\n"
+ "}\n"
+ "inline ::std::string* $classname$::add_$name$() {\n"
+ " return $name$_.Add();\n"
+ "}\n"
+ "inline void $classname$::add_$name$(const ::std::string& value) {\n"
+ " $name$_.Add()->assign(value);\n"
+ "}\n"
+ "inline void $classname$::add_$name$(const char* value) {\n"
+ " $name$_.Add()->assign(value);\n"
+ "}\n"
+ "inline void "
+ "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
+ " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
+ "}\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
+ "$classname$::$name$() const {\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
+ "$classname$::mutable_$name$() {\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+ " input, this->add_$name$()));\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$(this->$name$_size() - 1).data(),\n"
+ " this->$name$(this->$name$_size() - 1).length(),\n"
+ " ::google::protobuf::internal::WireFormat::PARSE);\n");
+ }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$(i).data(), this->$name$(i).length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ }
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ " $number$, this->$name$(i), output);\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
+ " this->$name$(i).data(), this->$name$(i).length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
+ }
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size();\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->$name$(i));\n"
+ "}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h
new file mode 100644
index 0000000..7f45107
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -0,0 +1,104 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class StringFieldGenerator : public FieldGenerator {
+ public:
+ explicit StringFieldGenerator(const FieldDescriptor* descriptor);
+ ~StringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateDestructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
+};
+
+class RepeatedStringFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor);
+ ~RepeatedStringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
new file mode 100644
index 0000000..54d830f
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -0,0 +1,113 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file tests that various identifiers work as field and type names even
+// though the same identifiers are used internally by the C++ code generator.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+package protobuf_unittest;
+
+// Test that fields can have names like "input" and "i" which are also used
+// internally by the code generator for local variables.
+message TestConflictingSymbolNames {
+ message BuildDescriptors {}
+ message TypeTraits {}
+
+ optional int32 input = 1;
+ optional int32 output = 2;
+ optional string length = 3;
+ repeated int32 i = 4;
+ repeated string new_element = 5 [ctype=STRING_PIECE];
+ optional int32 total_size = 6;
+ optional int32 tag = 7;
+
+ enum TestEnum { FOO = 1; }
+ message Data1 { repeated int32 data = 1; }
+ message Data2 { repeated TestEnum data = 1; }
+ message Data3 { repeated string data = 1; }
+ message Data4 { repeated Data4 data = 1; }
+ message Data5 { repeated string data = 1 [ctype=STRING_PIECE]; }
+ message Data6 { repeated string data = 1 [ctype=CORD]; }
+
+ optional int32 source = 8;
+ optional int32 value = 9;
+ optional int32 file = 10;
+ optional int32 from = 11;
+ optional int32 handle_uninterpreted = 12;
+ repeated int32 index = 13;
+ optional int32 controller = 14;
+ optional int32 already_here = 15;
+
+ optional uint32 uint32 = 16;
+ optional uint64 uint64 = 17;
+ optional string string = 18;
+ optional int32 memset = 19;
+ optional int32 int32 = 20;
+ optional int64 int64 = 21;
+
+ optional uint32 cached_size = 22;
+ optional uint32 extensions = 23;
+ optional uint32 bit = 24;
+ optional uint32 bits = 25;
+ optional uint32 offsets = 26;
+ optional uint32 reflection = 27;
+
+ message Cord {}
+ optional string some_cord = 28 [ctype=CORD];
+
+ message StringPiece {}
+ optional string some_string_piece = 29 [ctype=STRING_PIECE];
+
+ // Some keywords.
+ optional uint32 int = 30;
+ optional uint32 friend = 31;
+
+ // The generator used to #define a macro called "DO" inside the .cc file.
+ message DO {}
+ optional DO do = 32;
+
+ extensions 1000 to max;
+}
+
+message DummyMessage {}
+
+service TestConflictingMethodNames {
+ rpc Closure(DummyMessage) returns (DummyMessage);
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc
new file mode 100644
index 0000000..301a7ce
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -0,0 +1,1281 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// To test the code generator, we actually use it to generate code for
+// google/protobuf/unittest.proto, then test that. This means that we
+// are actually testing the parser and other parts of the system at the same
+// time, and that problems in the generator may show up as compile-time errors
+// rather than unittest failures, which may be surprising. However, testing
+// the output of the C++ generator directly would be very hard. We can't very
+// well just check it against golden files since those files would have to be
+// updated for any small change; such a test would be very brittle and probably
+// not very helpful. What we really want to test is that the code compiles
+// correctly and produces the interfaces we expect, which is why this test
+// is written this way.
+
+#include <vector>
+
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_optimize_for.pb.h>
+#include <google/protobuf/unittest_embed_optimize_for.pb.h>
+#include <google/protobuf/unittest_no_generic_services.pb.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace cpp_unittest {
+
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const string& filename, int line, int column,
+ const string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
+ filename, line, column, message);
+ }
+};
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+// Test that generated code has proper descriptors:
+// Parse a descriptor directly (using google::protobuf::compiler::Importer) and
+// compare it to the one that was produced by generated code.
+TEST(GeneratedDescriptorTest, IdenticalDescriptors) {
+ const FileDescriptor* generated_descriptor =
+ unittest::TestAllTypes::descriptor()->file();
+
+ // Set up the Importer.
+ MockErrorCollector error_collector;
+ DiskSourceTree source_tree;
+ source_tree.MapPath("", TestSourceDir());
+ Importer importer(&source_tree, &error_collector);
+
+ // Import (parse) unittest.proto.
+ const FileDescriptor* parsed_descriptor =
+ importer.Import("google/protobuf/unittest.proto");
+ EXPECT_EQ("", error_collector.text_);
+ ASSERT_TRUE(parsed_descriptor != NULL);
+
+ // Test that descriptors are generated correctly by converting them to
+ // FileDescriptorProtos and comparing.
+ FileDescriptorProto generated_decsriptor_proto, parsed_descriptor_proto;
+ generated_descriptor->CopyTo(&generated_decsriptor_proto);
+ parsed_descriptor->CopyTo(&parsed_descriptor_proto);
+
+ EXPECT_EQ(parsed_descriptor_proto.DebugString(),
+ generated_decsriptor_proto.DebugString());
+}
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+TEST(GeneratedMessageTest, Defaults) {
+ // Check that all default values are set correctly in the initial message.
+ unittest::TestAllTypes message;
+
+ TestUtil::ExpectClear(message);
+
+ // Messages should return pointers to default instances until first use.
+ // (This is not checked by ExpectClear() since it is not actually true after
+ // the fields have been set and then cleared.)
+ EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+ &message.optionalgroup());
+ EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.optional_nested_message());
+ EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
+ &message.optional_foreign_message());
+ EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+ &message.optional_import_message());
+}
+
+TEST(GeneratedMessageTest, FloatingPointDefaults) {
+ const unittest::TestExtremeDefaultValues& extreme_default =
+ unittest::TestExtremeDefaultValues::default_instance();
+
+ EXPECT_EQ(0.0f, extreme_default.zero_float());
+ EXPECT_EQ(1.0f, extreme_default.one_float());
+ EXPECT_EQ(1.5f, extreme_default.small_float());
+ EXPECT_EQ(-1.0f, extreme_default.negative_one_float());
+ EXPECT_EQ(-1.5f, extreme_default.negative_float());
+ EXPECT_EQ(2.0e8f, extreme_default.large_float());
+ EXPECT_EQ(-8e-28f, extreme_default.small_negative_float());
+ EXPECT_EQ(numeric_limits<double>::infinity(),
+ extreme_default.inf_double());
+ EXPECT_EQ(-numeric_limits<double>::infinity(),
+ extreme_default.neg_inf_double());
+ EXPECT_TRUE(extreme_default.nan_double() != extreme_default.nan_double());
+ EXPECT_EQ(numeric_limits<float>::infinity(),
+ extreme_default.inf_float());
+ EXPECT_EQ(-numeric_limits<float>::infinity(),
+ extreme_default.neg_inf_float());
+ EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float());
+}
+
+TEST(GeneratedMessageTest, Trigraph) {
+ const unittest::TestExtremeDefaultValues& extreme_default =
+ unittest::TestExtremeDefaultValues::default_instance();
+
+ EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph());
+}
+
+TEST(GeneratedMessageTest, Accessors) {
+ // Set every field to a unique value then go back and check all those
+ // values.
+ unittest::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+
+ TestUtil::ModifyRepeatedFields(&message);
+ TestUtil::ExpectRepeatedFieldsModified(message);
+}
+
+TEST(GeneratedMessageTest, MutableStringDefault) {
+ // mutable_foo() for a string should return a string initialized to its
+ // default value.
+ unittest::TestAllTypes message;
+
+ EXPECT_EQ("hello", *message.mutable_default_string());
+
+ // Note that the first time we call mutable_foo(), we get a newly-allocated
+ // string, but if we clear it and call it again, we get the same object again.
+ // We should verify that it has its default value in both cases.
+ message.set_default_string("blah");
+ message.Clear();
+
+ EXPECT_EQ("hello", *message.mutable_default_string());
+}
+
+TEST(GeneratedMessageTest, ReleaseString) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ unittest::TestAllTypes message;
+
+ EXPECT_EQ(NULL, message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_EQ("hello", message.default_string());
+
+ message.set_default_string("blah");
+ EXPECT_TRUE(message.has_default_string());
+ string* str = message.release_default_string();
+ EXPECT_FALSE(message.has_default_string());
+ ASSERT_TRUE(str != NULL);
+ EXPECT_EQ("blah", *str);
+ delete str;
+
+ EXPECT_EQ(NULL, message.release_default_string());
+ EXPECT_FALSE(message.has_default_string());
+ EXPECT_EQ("hello", message.default_string());
+}
+
+TEST(GeneratedMessageTest, ReleaseMessage) {
+ // Check that release_foo() starts out NULL, and gives us a value
+ // that we can delete after it's been set.
+ unittest::TestAllTypes message;
+
+ EXPECT_EQ(NULL, message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+
+ message.mutable_optional_nested_message()->set_bb(1);
+ unittest::TestAllTypes::NestedMessage* nest =
+ message.release_optional_nested_message();
+ EXPECT_FALSE(message.has_optional_nested_message());
+ ASSERT_TRUE(nest != NULL);
+ EXPECT_EQ(1, nest->bb());
+ delete nest;
+
+ EXPECT_EQ(NULL, message.release_optional_nested_message());
+ EXPECT_FALSE(message.has_optional_nested_message());
+}
+
+TEST(GeneratedMessageTest, Clear) {
+ // Set every field to a unique value, clear the message, then check that
+ // it is cleared.
+ unittest::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+ message.Clear();
+ TestUtil::ExpectClear(message);
+
+ // Unlike with the defaults test, we do NOT expect that requesting embedded
+ // messages will return a pointer to the default instance. Instead, they
+ // should return the objects that were created when mutable_blah() was
+ // called.
+ EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+ &message.optionalgroup());
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.optional_nested_message());
+ EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+ &message.optional_foreign_message());
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &message.optional_import_message());
+}
+
+TEST(GeneratedMessageTest, EmbeddedNullsInBytesCharStar) {
+ unittest::TestAllTypes message;
+
+ const char* value = "\0lalala\0\0";
+ message.set_optional_bytes(value, 9);
+ ASSERT_EQ(9, message.optional_bytes().size());
+ EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9));
+
+ message.add_repeated_bytes(value, 9);
+ ASSERT_EQ(9, message.repeated_bytes(0).size());
+ EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9));
+}
+
+TEST(GeneratedMessageTest, ClearOneField) {
+ // Set every field to a unique value, then clear one value and insure that
+ // only that one value is cleared.
+ unittest::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+ int64 original_value = message.optional_int64();
+
+ // Clear the field and make sure it shows up as cleared.
+ message.clear_optional_int64();
+ EXPECT_FALSE(message.has_optional_int64());
+ EXPECT_EQ(0, message.optional_int64());
+
+ // Other adjacent fields should not be cleared.
+ EXPECT_TRUE(message.has_optional_int32());
+ EXPECT_TRUE(message.has_optional_uint32());
+
+ // Make sure if we set it again, then all fields are set.
+ message.set_optional_int64(original_value);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageTest, StringCharStarLength) {
+ // Verify that we can use a char*,length to set one of the string fields.
+ unittest::TestAllTypes message;
+ message.set_optional_string("abcdef", 3);
+ EXPECT_EQ("abc", message.optional_string());
+
+ // Verify that we can use a char*,length to add to a repeated string field.
+ message.add_repeated_string("abcdef", 3);
+ EXPECT_EQ(1, message.repeated_string_size());
+ EXPECT_EQ("abc", message.repeated_string(0));
+
+ // Verify that we can use a char*,length to set a repeated string field.
+ message.set_repeated_string(0, "wxyz", 2);
+ EXPECT_EQ("wx", message.repeated_string(0));
+}
+
+
+TEST(GeneratedMessageTest, CopyFrom) {
+ unittest::TestAllTypes message1, message2;
+
+ TestUtil::SetAllFields(&message1);
+ message2.CopyFrom(message1);
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ // Copying from self should be a no-op.
+ message2.CopyFrom(message2);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+
+TEST(GeneratedMessageTest, SwapWithEmpty) {
+ unittest::TestAllTypes message1, message2;
+ TestUtil::SetAllFields(&message1);
+
+ TestUtil::ExpectAllFieldsSet(message1);
+ TestUtil::ExpectClear(message2);
+ message1.Swap(&message2);
+ TestUtil::ExpectAllFieldsSet(message2);
+ TestUtil::ExpectClear(message1);
+}
+
+TEST(GeneratedMessageTest, SwapWithSelf) {
+ unittest::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+ message.Swap(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageTest, SwapWithOther) {
+ unittest::TestAllTypes message1, message2;
+
+ message1.set_optional_int32(123);
+ message1.set_optional_string("abc");
+ message1.mutable_optional_nested_message()->set_bb(1);
+ message1.set_optional_nested_enum(unittest::TestAllTypes::FOO);
+ message1.add_repeated_int32(1);
+ message1.add_repeated_int32(2);
+ message1.add_repeated_string("a");
+ message1.add_repeated_string("b");
+ message1.add_repeated_nested_message()->set_bb(7);
+ message1.add_repeated_nested_message()->set_bb(8);
+ message1.add_repeated_nested_enum(unittest::TestAllTypes::FOO);
+ message1.add_repeated_nested_enum(unittest::TestAllTypes::BAR);
+
+ message2.set_optional_int32(456);
+ message2.set_optional_string("def");
+ message2.mutable_optional_nested_message()->set_bb(2);
+ message2.set_optional_nested_enum(unittest::TestAllTypes::BAR);
+ message2.add_repeated_int32(3);
+ message2.add_repeated_string("c");
+ message2.add_repeated_nested_message()->set_bb(9);
+ message2.add_repeated_nested_enum(unittest::TestAllTypes::BAZ);
+
+ message1.Swap(&message2);
+
+ EXPECT_EQ(456, message1.optional_int32());
+ EXPECT_EQ("def", message1.optional_string());
+ EXPECT_EQ(2, message1.optional_nested_message().bb());
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message1.optional_nested_enum());
+ ASSERT_EQ(1, message1.repeated_int32_size());
+ EXPECT_EQ(3, message1.repeated_int32(0));
+ ASSERT_EQ(1, message1.repeated_string_size());
+ EXPECT_EQ("c", message1.repeated_string(0));
+ ASSERT_EQ(1, message1.repeated_nested_message_size());
+ EXPECT_EQ(9, message1.repeated_nested_message(0).bb());
+ ASSERT_EQ(1, message1.repeated_nested_enum_size());
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, message1.repeated_nested_enum(0));
+
+ EXPECT_EQ(123, message2.optional_int32());
+ EXPECT_EQ("abc", message2.optional_string());
+ EXPECT_EQ(1, message2.optional_nested_message().bb());
+ EXPECT_EQ(unittest::TestAllTypes::FOO, message2.optional_nested_enum());
+ ASSERT_EQ(2, message2.repeated_int32_size());
+ EXPECT_EQ(1, message2.repeated_int32(0));
+ EXPECT_EQ(2, message2.repeated_int32(1));
+ ASSERT_EQ(2, message2.repeated_string_size());
+ EXPECT_EQ("a", message2.repeated_string(0));
+ EXPECT_EQ("b", message2.repeated_string(1));
+ ASSERT_EQ(2, message2.repeated_nested_message_size());
+ EXPECT_EQ(7, message2.repeated_nested_message(0).bb());
+ EXPECT_EQ(8, message2.repeated_nested_message(1).bb());
+ ASSERT_EQ(2, message2.repeated_nested_enum_size());
+ EXPECT_EQ(unittest::TestAllTypes::FOO, message2.repeated_nested_enum(0));
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message2.repeated_nested_enum(1));
+}
+
+TEST(GeneratedMessageTest, CopyConstructor) {
+ unittest::TestAllTypes message1;
+ TestUtil::SetAllFields(&message1);
+
+ unittest::TestAllTypes message2(message1);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageTest, CopyAssignmentOperator) {
+ unittest::TestAllTypes message1;
+ TestUtil::SetAllFields(&message1);
+
+ unittest::TestAllTypes message2;
+ message2 = message1;
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ // Make sure that self-assignment does something sane.
+ message2.operator=(message2);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageTest, UpcastCopyFrom) {
+ // Test the CopyFrom method that takes in the generic const Message&
+ // parameter.
+ unittest::TestAllTypes message1, message2;
+
+ TestUtil::SetAllFields(&message1);
+
+ const Message* source = implicit_cast<const Message*>(&message1);
+ message2.CopyFrom(*source);
+
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GeneratedMessageTest, DynamicMessageCopyFrom) {
+ // Test copying from a DynamicMessage, which must fall back to using
+ // reflection.
+ unittest::TestAllTypes message2;
+
+ // Construct a new version of the dynamic message via the factory.
+ DynamicMessageFactory factory;
+ scoped_ptr<Message> message1;
+ message1.reset(factory.GetPrototype(
+ unittest::TestAllTypes::descriptor())->New());
+
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+ reflection_tester.SetAllFieldsViaReflection(message1.get());
+
+ message2.CopyFrom(*message1);
+
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GeneratedMessageTest, NonEmptyMergeFrom) {
+ // Test merging with a non-empty message. Code is a modified form
+ // of that found in google/protobuf/reflection_ops_unittest.cc.
+ unittest::TestAllTypes message1, message2;
+
+ TestUtil::SetAllFields(&message1);
+
+ // This field will test merging into an empty spot.
+ message2.set_optional_int32(message1.optional_int32());
+ message1.clear_optional_int32();
+
+ // This tests overwriting.
+ message2.set_optional_string(message1.optional_string());
+ message1.set_optional_string("something else");
+
+ // This tests concatenating.
+ message2.add_repeated_int32(message1.repeated_int32(1));
+ int32 i = message1.repeated_int32(0);
+ message1.clear_repeated_int32();
+ message1.add_repeated_int32(i);
+
+ message1.MergeFrom(message2);
+
+ TestUtil::ExpectAllFieldsSet(message1);
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(GeneratedMessageTest, MergeFromSelf) {
+ unittest::TestAllTypes message;
+ EXPECT_DEATH(message.MergeFrom(message), "&from");
+ EXPECT_DEATH(message.MergeFrom(implicit_cast<const Message&>(message)),
+ "&from");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+// Test the generated SerializeWithCachedSizesToArray(),
+TEST(GeneratedMessageTest, SerializationToArray) {
+ unittest::TestAllTypes message1, message2;
+ string data;
+ TestUtil::SetAllFields(&message1);
+ int size = message1.ByteSize();
+ data.resize(size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(size, end - start);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(message2);
+
+}
+
+TEST(GeneratedMessageTest, PackedFieldsSerializationToArray) {
+ unittest::TestPackedTypes packed_message1, packed_message2;
+ string packed_data;
+ TestUtil::SetPackedFields(&packed_message1);
+ int packed_size = packed_message1.ByteSize();
+ packed_data.resize(packed_size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(&packed_data));
+ uint8* end = packed_message1.SerializeWithCachedSizesToArray(start);
+ EXPECT_EQ(packed_size, end - start);
+ EXPECT_TRUE(packed_message2.ParseFromString(packed_data));
+ TestUtil::ExpectPackedFieldsSet(packed_message2);
+}
+
+// Test the generated SerializeWithCachedSizes() by forcing the buffer to write
+// one byte at a time.
+TEST(GeneratedMessageTest, SerializationToStream) {
+ unittest::TestAllTypes message1, message2;
+ TestUtil::SetAllFields(&message1);
+ int size = message1.ByteSize();
+ string data;
+ data.resize(size);
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_TRUE(message2.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(message2);
+
+}
+
+TEST(GeneratedMessageTest, PackedFieldsSerializationToStream) {
+ unittest::TestPackedTypes message1, message2;
+ TestUtil::SetPackedFields(&message1);
+ int size = message1.ByteSize();
+ string data;
+ data.resize(size);
+ {
+ // Allow the output stream to buffer only one byte at a time.
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message1.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ }
+ EXPECT_TRUE(message2.ParseFromString(data));
+ TestUtil::ExpectPackedFieldsSet(message2);
+}
+
+
+TEST(GeneratedMessageTest, Required) {
+ // Test that IsInitialized() returns false if required fields are missing.
+ unittest::TestRequired message;
+
+ EXPECT_FALSE(message.IsInitialized());
+ message.set_a(1);
+ EXPECT_FALSE(message.IsInitialized());
+ message.set_b(2);
+ EXPECT_FALSE(message.IsInitialized());
+ message.set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(GeneratedMessageTest, RequiredForeign) {
+ // Test that IsInitialized() returns false if required fields in nested
+ // messages are missing.
+ unittest::TestRequiredForeign message;
+
+ EXPECT_TRUE(message.IsInitialized());
+
+ message.mutable_optional_message();
+ EXPECT_FALSE(message.IsInitialized());
+
+ message.mutable_optional_message()->set_a(1);
+ message.mutable_optional_message()->set_b(2);
+ message.mutable_optional_message()->set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+
+ message.add_repeated_message();
+ EXPECT_FALSE(message.IsInitialized());
+
+ message.mutable_repeated_message(0)->set_a(1);
+ message.mutable_repeated_message(0)->set_b(2);
+ message.mutable_repeated_message(0)->set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(GeneratedMessageTest, ForeignNested) {
+ // Test that TestAllTypes::NestedMessage can be embedded directly into
+ // another message.
+ unittest::TestForeignNested message;
+
+ // If this compiles and runs without crashing, it must work. We have
+ // nothing more to test.
+ unittest::TestAllTypes::NestedMessage* nested =
+ message.mutable_foreign_nested();
+ nested->set_bb(1);
+}
+
+TEST(GeneratedMessageTest, ReallyLargeTagNumber) {
+ // Test that really large tag numbers don't break anything.
+ unittest::TestReallyLargeTagNumber message1, message2;
+ string data;
+
+ // For the most part, if this compiles and runs then we're probably good.
+ // (The most likely cause for failure would be if something were attempting
+ // to allocate a lookup table of some sort using tag numbers as the index.)
+ // We'll try serializing just for fun.
+ message1.set_a(1234);
+ message1.set_bb(5678);
+ message1.SerializeToString(&data);
+ EXPECT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(1234, message2.a());
+ EXPECT_EQ(5678, message2.bb());
+}
+
+TEST(GeneratedMessageTest, MutualRecursion) {
+ // Test that mutually-recursive message types work.
+ unittest::TestMutualRecursionA message;
+ unittest::TestMutualRecursionA* nested = message.mutable_bb()->mutable_a();
+ unittest::TestMutualRecursionA* nested2 = nested->mutable_bb()->mutable_a();
+
+ // Again, if the above compiles and runs, that's all we really have to
+ // test, but just for run we'll check that the system didn't somehow come
+ // up with a pointer loop...
+ EXPECT_NE(&message, nested);
+ EXPECT_NE(&message, nested2);
+ EXPECT_NE(nested, nested2);
+}
+
+TEST(GeneratedMessageTest, CamelCaseFieldNames) {
+ // This test is mainly checking that the following compiles, which verifies
+ // that the field names were coerced to lower-case.
+ //
+ // Protocol buffers standard style is to use lowercase-with-underscores for
+ // field names. Some old proto1 .protos unfortunately used camel-case field
+ // names. In proto1, these names were forced to lower-case. So, we do the
+ // same thing in proto2.
+
+ unittest::TestCamelCaseFieldNames message;
+
+ message.set_primitivefield(2);
+ message.set_stringfield("foo");
+ message.set_enumfield(unittest::FOREIGN_FOO);
+ message.mutable_messagefield()->set_c(6);
+
+ message.add_repeatedprimitivefield(8);
+ message.add_repeatedstringfield("qux");
+ message.add_repeatedenumfield(unittest::FOREIGN_BAR);
+ message.add_repeatedmessagefield()->set_c(15);
+
+ EXPECT_EQ(2, message.primitivefield());
+ EXPECT_EQ("foo", message.stringfield());
+ EXPECT_EQ(unittest::FOREIGN_FOO, message.enumfield());
+ EXPECT_EQ(6, message.messagefield().c());
+
+ EXPECT_EQ(8, message.repeatedprimitivefield(0));
+ EXPECT_EQ("qux", message.repeatedstringfield(0));
+ EXPECT_EQ(unittest::FOREIGN_BAR, message.repeatedenumfield(0));
+ EXPECT_EQ(15, message.repeatedmessagefield(0).c());
+}
+
+TEST(GeneratedMessageTest, TestConflictingSymbolNames) {
+ // test_bad_identifiers.proto successfully compiled, then it works. The
+ // following is just a token usage to insure that the code is, in fact,
+ // being compiled and linked.
+
+ protobuf_unittest::TestConflictingSymbolNames message;
+ message.set_uint32(1);
+ EXPECT_EQ(3, message.ByteSize());
+
+ message.set_friend_(5);
+ EXPECT_EQ(5, message.friend_());
+}
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GeneratedMessageTest, TestOptimizedForSize) {
+ // We rely on the tests in reflection_ops_unittest and wire_format_unittest
+ // to really test that reflection-based methods work. Here we are mostly
+ // just making sure that TestOptimizedForSize actually builds and seems to
+ // function.
+
+ protobuf_unittest::TestOptimizedForSize message, message2;
+ message.set_i(1);
+ message.mutable_msg()->set_c(2);
+ message2.CopyFrom(message);
+ EXPECT_EQ(1, message2.i());
+ EXPECT_EQ(2, message2.msg().c());
+}
+
+TEST(GeneratedMessageTest, TestEmbedOptimizedForSize) {
+ // Verifies that something optimized for speed can contain something optimized
+ // for size.
+
+ protobuf_unittest::TestEmbedOptimizedForSize message, message2;
+ message.mutable_optional_message()->set_i(1);
+ message.add_repeated_message()->mutable_msg()->set_c(2);
+ string data;
+ message.SerializeToString(&data);
+ ASSERT_TRUE(message2.ParseFromString(data));
+ EXPECT_EQ(1, message2.optional_message().i());
+ EXPECT_EQ(2, message2.repeated_message(0).msg().c());
+}
+
+TEST(GeneratedMessageTest, TestSpaceUsed) {
+ unittest::TestAllTypes message1;
+ // sizeof provides a lower bound on SpaceUsed().
+ EXPECT_LE(sizeof(unittest::TestAllTypes), message1.SpaceUsed());
+ const int empty_message_size = message1.SpaceUsed();
+
+ // Setting primitive types shouldn't affect the space used.
+ message1.set_optional_int32(123);
+ message1.set_optional_int64(12345);
+ message1.set_optional_uint32(123);
+ message1.set_optional_uint64(12345);
+ EXPECT_EQ(empty_message_size, message1.SpaceUsed());
+
+ // On some STL implementations, setting the string to a small value should
+ // only increase SpaceUsed() by the size of a string object, though this is
+ // not true everywhere.
+ message1.set_optional_string("abc");
+ EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsed());
+
+ // Setting a string to a value larger than the string object itself should
+ // increase SpaceUsed(), because it cannot store the value internally.
+ message1.set_optional_string(string(sizeof(string) + 1, 'x'));
+ int min_expected_increase = message1.optional_string().capacity() +
+ sizeof(string);
+ EXPECT_LE(empty_message_size + min_expected_increase,
+ message1.SpaceUsed());
+
+ int previous_size = message1.SpaceUsed();
+ // Adding an optional message should increase the size by the size of the
+ // nested message type. NestedMessage is simple enough (1 int field) that it
+ // is equal to sizeof(NestedMessage)
+ message1.mutable_optional_nested_message();
+ ASSERT_EQ(sizeof(unittest::TestAllTypes::NestedMessage),
+ message1.optional_nested_message().SpaceUsed());
+ EXPECT_EQ(previous_size +
+ sizeof(unittest::TestAllTypes::NestedMessage),
+ message1.SpaceUsed());
+}
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+
+TEST(GeneratedMessageTest, FieldConstantValues) {
+ unittest::TestRequired message;
+ EXPECT_EQ(unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1);
+ EXPECT_EQ(unittest::TestAllTypes::kOptionalInt32FieldNumber, 1);
+ EXPECT_EQ(unittest::TestAllTypes::kOptionalgroupFieldNumber, 16);
+ EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedMessageFieldNumber, 18);
+ EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedEnumFieldNumber, 21);
+ EXPECT_EQ(unittest::TestAllTypes::kRepeatedInt32FieldNumber, 31);
+ EXPECT_EQ(unittest::TestAllTypes::kRepeatedgroupFieldNumber, 46);
+ EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedMessageFieldNumber, 48);
+ EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedEnumFieldNumber, 51);
+}
+
+TEST(GeneratedMessageTest, ExtensionConstantValues) {
+ EXPECT_EQ(unittest::TestRequired::kSingleFieldNumber, 1000);
+ EXPECT_EQ(unittest::TestRequired::kMultiFieldNumber, 1001);
+ EXPECT_EQ(unittest::kOptionalInt32ExtensionFieldNumber, 1);
+ EXPECT_EQ(unittest::kOptionalgroupExtensionFieldNumber, 16);
+ EXPECT_EQ(unittest::kOptionalNestedMessageExtensionFieldNumber, 18);
+ EXPECT_EQ(unittest::kOptionalNestedEnumExtensionFieldNumber, 21);
+ EXPECT_EQ(unittest::kRepeatedInt32ExtensionFieldNumber, 31);
+ EXPECT_EQ(unittest::kRepeatedgroupExtensionFieldNumber, 46);
+ EXPECT_EQ(unittest::kRepeatedNestedMessageExtensionFieldNumber, 48);
+ EXPECT_EQ(unittest::kRepeatedNestedEnumExtensionFieldNumber, 51);
+}
+
+// ===================================================================
+
+TEST(GeneratedEnumTest, EnumValuesAsSwitchCases) {
+ // Test that our nested enum values can be used as switch cases. This test
+ // doesn't actually do anything, the proof that it works is that it
+ // compiles.
+ int i =0;
+ unittest::TestAllTypes::NestedEnum a = unittest::TestAllTypes::BAR;
+ switch (a) {
+ case unittest::TestAllTypes::FOO:
+ i = 1;
+ break;
+ case unittest::TestAllTypes::BAR:
+ i = 2;
+ break;
+ case unittest::TestAllTypes::BAZ:
+ i = 3;
+ break;
+ // no default case: We want to make sure the compiler recognizes that
+ // all cases are covered. (GCC warns if you do not cover all cases of
+ // an enum in a switch.)
+ }
+
+ // Token check just for fun.
+ EXPECT_EQ(2, i);
+}
+
+TEST(GeneratedEnumTest, IsValidValue) {
+ // Test enum IsValidValue.
+ EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(1));
+ EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(2));
+ EXPECT_TRUE(unittest::TestAllTypes::NestedEnum_IsValid(3));
+
+ EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(0));
+ EXPECT_FALSE(unittest::TestAllTypes::NestedEnum_IsValid(4));
+
+ // Make sure it also works when there are dups.
+ EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(1));
+ EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(2));
+ EXPECT_TRUE(unittest::TestEnumWithDupValue_IsValid(3));
+
+ EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(0));
+ EXPECT_FALSE(unittest::TestEnumWithDupValue_IsValid(4));
+}
+
+TEST(GeneratedEnumTest, MinAndMax) {
+ EXPECT_EQ(unittest::TestAllTypes::FOO,
+ unittest::TestAllTypes::NestedEnum_MIN);
+ EXPECT_EQ(unittest::TestAllTypes::BAZ,
+ unittest::TestAllTypes::NestedEnum_MAX);
+ EXPECT_EQ(4, unittest::TestAllTypes::NestedEnum_ARRAYSIZE);
+
+ EXPECT_EQ(unittest::FOREIGN_FOO, unittest::ForeignEnum_MIN);
+ EXPECT_EQ(unittest::FOREIGN_BAZ, unittest::ForeignEnum_MAX);
+ EXPECT_EQ(7, unittest::ForeignEnum_ARRAYSIZE);
+
+ EXPECT_EQ(1, unittest::TestEnumWithDupValue_MIN);
+ EXPECT_EQ(3, unittest::TestEnumWithDupValue_MAX);
+ EXPECT_EQ(4, unittest::TestEnumWithDupValue_ARRAYSIZE);
+
+ EXPECT_EQ(unittest::SPARSE_E, unittest::TestSparseEnum_MIN);
+ EXPECT_EQ(unittest::SPARSE_C, unittest::TestSparseEnum_MAX);
+ EXPECT_EQ(12589235, unittest::TestSparseEnum_ARRAYSIZE);
+
+ // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE.
+ void* null_pointer = 0; // NULL may be integer-type, not pointer-type.
+ EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MIN);
+ EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MAX);
+ EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE);
+
+ EXPECT_NE(null_pointer, &unittest::ForeignEnum_MIN);
+ EXPECT_NE(null_pointer, &unittest::ForeignEnum_MAX);
+ EXPECT_NE(null_pointer, &unittest::ForeignEnum_ARRAYSIZE);
+
+ // Make sure we can use _MIN, _MAX and _ARRAYSIZE as switch cases.
+ switch (unittest::SPARSE_A) {
+ case unittest::TestSparseEnum_MIN:
+ case unittest::TestSparseEnum_MAX:
+ case unittest::TestSparseEnum_ARRAYSIZE:
+ break;
+ default:
+ break;
+ }
+}
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GeneratedEnumTest, Name) {
+ // "Names" in the presence of dup values are a bit arbitrary.
+ EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO1));
+ EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO2));
+
+ EXPECT_EQ("SPARSE_A", unittest::TestSparseEnum_Name(unittest::SPARSE_A));
+ EXPECT_EQ("SPARSE_B", unittest::TestSparseEnum_Name(unittest::SPARSE_B));
+ EXPECT_EQ("SPARSE_C", unittest::TestSparseEnum_Name(unittest::SPARSE_C));
+ EXPECT_EQ("SPARSE_D", unittest::TestSparseEnum_Name(unittest::SPARSE_D));
+ EXPECT_EQ("SPARSE_E", unittest::TestSparseEnum_Name(unittest::SPARSE_E));
+ EXPECT_EQ("SPARSE_F", unittest::TestSparseEnum_Name(unittest::SPARSE_F));
+ EXPECT_EQ("SPARSE_G", unittest::TestSparseEnum_Name(unittest::SPARSE_G));
+}
+
+TEST(GeneratedEnumTest, Parse) {
+ unittest::TestEnumWithDupValue dup_value = unittest::FOO1;
+ EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO1", &dup_value));
+ EXPECT_EQ(unittest::FOO1, dup_value);
+ EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO2", &dup_value));
+ EXPECT_EQ(unittest::FOO2, dup_value);
+ EXPECT_FALSE(unittest::TestEnumWithDupValue_Parse("FOO", &dup_value));
+}
+
+TEST(GeneratedEnumTest, GetEnumDescriptor) {
+ EXPECT_EQ(unittest::TestAllTypes::NestedEnum_descriptor(),
+ GetEnumDescriptor<unittest::TestAllTypes::NestedEnum>());
+ EXPECT_EQ(unittest::ForeignEnum_descriptor(),
+ GetEnumDescriptor<unittest::ForeignEnum>());
+ EXPECT_EQ(unittest::TestEnumWithDupValue_descriptor(),
+ GetEnumDescriptor<unittest::TestEnumWithDupValue>());
+ EXPECT_EQ(unittest::TestSparseEnum_descriptor(),
+ GetEnumDescriptor<unittest::TestSparseEnum>());
+}
+
+#endif // PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+// Support code for testing services.
+class GeneratedServiceTest : public testing::Test {
+ protected:
+ class MockTestService : public unittest::TestService {
+ public:
+ MockTestService()
+ : called_(false),
+ method_(""),
+ controller_(NULL),
+ request_(NULL),
+ response_(NULL),
+ done_(NULL) {}
+
+ ~MockTestService() {}
+
+ void Reset() { called_ = false; }
+
+ // implements TestService ----------------------------------------
+
+ void Foo(RpcController* controller,
+ const unittest::FooRequest* request,
+ unittest::FooResponse* response,
+ Closure* done) {
+ ASSERT_FALSE(called_);
+ called_ = true;
+ method_ = "Foo";
+ controller_ = controller;
+ request_ = request;
+ response_ = response;
+ done_ = done;
+ }
+
+ void Bar(RpcController* controller,
+ const unittest::BarRequest* request,
+ unittest::BarResponse* response,
+ Closure* done) {
+ ASSERT_FALSE(called_);
+ called_ = true;
+ method_ = "Bar";
+ controller_ = controller;
+ request_ = request;
+ response_ = response;
+ done_ = done;
+ }
+
+ // ---------------------------------------------------------------
+
+ bool called_;
+ string method_;
+ RpcController* controller_;
+ const Message* request_;
+ Message* response_;
+ Closure* done_;
+ };
+
+ class MockRpcChannel : public RpcChannel {
+ public:
+ MockRpcChannel()
+ : called_(false),
+ method_(NULL),
+ controller_(NULL),
+ request_(NULL),
+ response_(NULL),
+ done_(NULL),
+ destroyed_(NULL) {}
+
+ ~MockRpcChannel() {
+ if (destroyed_ != NULL) *destroyed_ = true;
+ }
+
+ void Reset() { called_ = false; }
+
+ // implements TestService ----------------------------------------
+
+ void CallMethod(const MethodDescriptor* method,
+ RpcController* controller,
+ const Message* request,
+ Message* response,
+ Closure* done) {
+ ASSERT_FALSE(called_);
+ called_ = true;
+ method_ = method;
+ controller_ = controller;
+ request_ = request;
+ response_ = response;
+ done_ = done;
+ }
+
+ // ---------------------------------------------------------------
+
+ bool called_;
+ const MethodDescriptor* method_;
+ RpcController* controller_;
+ const Message* request_;
+ Message* response_;
+ Closure* done_;
+ bool* destroyed_;
+ };
+
+ class MockController : public RpcController {
+ public:
+ void Reset() {
+ ADD_FAILURE() << "Reset() not expected during this test.";
+ }
+ bool Failed() const {
+ ADD_FAILURE() << "Failed() not expected during this test.";
+ return false;
+ }
+ string ErrorText() const {
+ ADD_FAILURE() << "ErrorText() not expected during this test.";
+ return "";
+ }
+ void StartCancel() {
+ ADD_FAILURE() << "StartCancel() not expected during this test.";
+ }
+ void SetFailed(const string& reason) {
+ ADD_FAILURE() << "SetFailed() not expected during this test.";
+ }
+ bool IsCanceled() const {
+ ADD_FAILURE() << "IsCanceled() not expected during this test.";
+ return false;
+ }
+ void NotifyOnCancel(Closure* callback) {
+ ADD_FAILURE() << "NotifyOnCancel() not expected during this test.";
+ }
+ };
+
+ GeneratedServiceTest()
+ : descriptor_(unittest::TestService::descriptor()),
+ foo_(descriptor_->FindMethodByName("Foo")),
+ bar_(descriptor_->FindMethodByName("Bar")),
+ stub_(&mock_channel_),
+ done_(NewPermanentCallback(&DoNothing)) {}
+
+ virtual void SetUp() {
+ ASSERT_TRUE(foo_ != NULL);
+ ASSERT_TRUE(bar_ != NULL);
+ }
+
+ const ServiceDescriptor* descriptor_;
+ const MethodDescriptor* foo_;
+ const MethodDescriptor* bar_;
+
+ MockTestService mock_service_;
+ MockController mock_controller_;
+
+ MockRpcChannel mock_channel_;
+ unittest::TestService::Stub stub_;
+
+ // Just so we don't have to re-define these with every test.
+ unittest::FooRequest foo_request_;
+ unittest::FooResponse foo_response_;
+ unittest::BarRequest bar_request_;
+ unittest::BarResponse bar_response_;
+ scoped_ptr<Closure> done_;
+};
+
+TEST_F(GeneratedServiceTest, GetDescriptor) {
+ // Test that GetDescriptor() works.
+
+ EXPECT_EQ(descriptor_, mock_service_.GetDescriptor());
+}
+
+TEST_F(GeneratedServiceTest, GetChannel) {
+ EXPECT_EQ(&mock_channel_, stub_.channel());
+}
+
+TEST_F(GeneratedServiceTest, OwnsChannel) {
+ MockRpcChannel* channel = new MockRpcChannel;
+ bool destroyed = false;
+ channel->destroyed_ = &destroyed;
+
+ {
+ unittest::TestService::Stub owning_stub(channel,
+ Service::STUB_OWNS_CHANNEL);
+ EXPECT_FALSE(destroyed);
+ }
+
+ EXPECT_TRUE(destroyed);
+}
+
+TEST_F(GeneratedServiceTest, CallMethod) {
+ // Test that CallMethod() works.
+
+ // Call Foo() via CallMethod().
+ mock_service_.CallMethod(foo_, &mock_controller_,
+ &foo_request_, &foo_response_, done_.get());
+
+ ASSERT_TRUE(mock_service_.called_);
+
+ EXPECT_EQ("Foo" , mock_service_.method_ );
+ EXPECT_EQ(&mock_controller_, mock_service_.controller_);
+ EXPECT_EQ(&foo_request_ , mock_service_.request_ );
+ EXPECT_EQ(&foo_response_ , mock_service_.response_ );
+ EXPECT_EQ(done_.get() , mock_service_.done_ );
+
+ // Try again, but call Bar() instead.
+ mock_service_.Reset();
+ mock_service_.CallMethod(bar_, &mock_controller_,
+ &bar_request_, &bar_response_, done_.get());
+
+ ASSERT_TRUE(mock_service_.called_);
+ EXPECT_EQ("Bar", mock_service_.method_);
+}
+
+TEST_F(GeneratedServiceTest, CallMethodTypeFailure) {
+ // Verify death if we call Foo() with Bar's message types.
+
+#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
+ EXPECT_DEBUG_DEATH(
+ mock_service_.CallMethod(foo_, &mock_controller_,
+ &foo_request_, &bar_response_, done_.get()),
+ "dynamic_cast");
+
+ mock_service_.Reset();
+ EXPECT_DEBUG_DEATH(
+ mock_service_.CallMethod(foo_, &mock_controller_,
+ &bar_request_, &foo_response_, done_.get()),
+ "dynamic_cast");
+#endif // GTEST_HAS_DEATH_TEST
+}
+
+TEST_F(GeneratedServiceTest, GetPrototypes) {
+ // Test Get{Request,Response}Prototype() methods.
+
+ EXPECT_EQ(&unittest::FooRequest::default_instance(),
+ &mock_service_.GetRequestPrototype(foo_));
+ EXPECT_EQ(&unittest::BarRequest::default_instance(),
+ &mock_service_.GetRequestPrototype(bar_));
+
+ EXPECT_EQ(&unittest::FooResponse::default_instance(),
+ &mock_service_.GetResponsePrototype(foo_));
+ EXPECT_EQ(&unittest::BarResponse::default_instance(),
+ &mock_service_.GetResponsePrototype(bar_));
+}
+
+TEST_F(GeneratedServiceTest, Stub) {
+ // Test that the stub class works.
+
+ // Call Foo() via the stub.
+ stub_.Foo(&mock_controller_, &foo_request_, &foo_response_, done_.get());
+
+ ASSERT_TRUE(mock_channel_.called_);
+
+ EXPECT_EQ(foo_ , mock_channel_.method_ );
+ EXPECT_EQ(&mock_controller_, mock_channel_.controller_);
+ EXPECT_EQ(&foo_request_ , mock_channel_.request_ );
+ EXPECT_EQ(&foo_response_ , mock_channel_.response_ );
+ EXPECT_EQ(done_.get() , mock_channel_.done_ );
+
+ // Call Bar() via the stub.
+ mock_channel_.Reset();
+ stub_.Bar(&mock_controller_, &bar_request_, &bar_response_, done_.get());
+
+ ASSERT_TRUE(mock_channel_.called_);
+ EXPECT_EQ(bar_, mock_channel_.method_);
+}
+
+TEST_F(GeneratedServiceTest, NotImplemented) {
+ // Test that failing to implement a method of a service causes it to fail
+ // with a "not implemented" error message.
+
+ // A service which doesn't implement any methods.
+ class UnimplementedService : public unittest::TestService {
+ public:
+ UnimplementedService() {}
+ };
+
+ UnimplementedService unimplemented_service;
+
+ // And a controller which expects to get a "not implemented" error.
+ class ExpectUnimplementedController : public MockController {
+ public:
+ ExpectUnimplementedController() : called_(false) {}
+
+ void SetFailed(const string& reason) {
+ EXPECT_FALSE(called_);
+ called_ = true;
+ EXPECT_EQ("Method Foo() not implemented.", reason);
+ }
+
+ bool called_;
+ };
+
+ ExpectUnimplementedController controller;
+
+ // Call Foo.
+ unimplemented_service.Foo(&controller, &foo_request_, &foo_response_,
+ done_.get());
+
+ EXPECT_TRUE(controller.called_);
+}
+
+} // namespace cpp_unittest
+} // namespace cpp
+} // namespace compiler
+
+namespace no_generic_services_test {
+ // Verify that no class called "TestService" was defined in
+ // unittest_no_generic_services.pb.h by defining a different type by the same
+ // name. If such a service was generated, this will not compile.
+ struct TestService {
+ int i;
+ };
+}
+
+namespace compiler {
+namespace cpp {
+namespace cpp_unittest {
+
+TEST_F(GeneratedServiceTest, NoGenericServices) {
+ // Verify that non-services in unittest_no_generic_services.proto were
+ // generated.
+ no_generic_services_test::TestMessage message;
+ message.set_a(1);
+ message.SetExtension(no_generic_services_test::test_extension, 123);
+ no_generic_services_test::TestEnum e = no_generic_services_test::FOO;
+ EXPECT_EQ(e, 1);
+
+ // Verify that a ServiceDescriptor is generated for the service even if the
+ // class itself is not.
+ const FileDescriptor* file =
+ no_generic_services_test::TestMessage::descriptor()->file();
+
+ ASSERT_EQ(1, file->service_count());
+ EXPECT_EQ("TestService", file->service(0)->name());
+ ASSERT_EQ(1, file->service(0)->method_count());
+ EXPECT_EQ("Foo", file->service(0)->method(0)->name());
+}
+
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+// This test must run last. It verifies that descriptors were or were not
+// initialized depending on whether PROTOBUF_TEST_NO_DESCRIPTORS was defined.
+// When this is defined, we skip all tests which are expected to trigger
+// descriptor initialization. This verifies that everything else still works
+// if descriptors are not initialized.
+TEST(DescriptorInitializationTest, Initialized) {
+#ifdef PROTOBUF_TEST_NO_DESCRIPTORS
+ bool should_have_descriptors = false;
+#else
+ bool should_have_descriptors = true;
+#endif
+
+ EXPECT_EQ(should_have_descriptors,
+ DescriptorPool::generated_pool()->InternalIsFileLoaded(
+ "google/protobuf/unittest.proto"));
+}
+
+} // namespace cpp_unittest
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/importer.cc b/src/third_party/protobuf/src/google/protobuf/compiler/importer.cc
new file mode 100644
index 0000000..422f759
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/importer.cc
@@ -0,0 +1,459 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <algorithm>
+
+#include <google/protobuf/compiler/importer.h>
+
+#include <google/protobuf/compiler/parser.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#ifdef _WIN32
+#ifndef F_OK
+#define F_OK 00 // not defined by MSVC for whatever reason
+#endif
+#include <ctype.h>
+#endif
+
+// Returns true if the text looks like a Windows-style absolute path, starting
+// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with
+// copy in command_line_interface.cc?
+static bool IsWindowsAbsolutePath(const string& text) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ return text.size() >= 3 && text[1] == ':' &&
+ isalpha(text[0]) &&
+ (text[2] == '/' || text[2] == '\\') &&
+ text.find_last_of(':') == 1;
+#else
+ return false;
+#endif
+}
+
+MultiFileErrorCollector::~MultiFileErrorCollector() {}
+
+// This class serves two purposes:
+// - It implements the ErrorCollector interface (used by Tokenizer and Parser)
+// in terms of MultiFileErrorCollector, using a particular filename.
+// - It lets us check if any errors have occurred.
+class SourceTreeDescriptorDatabase::SingleFileErrorCollector
+ : public io::ErrorCollector {
+ public:
+ SingleFileErrorCollector(const string& filename,
+ MultiFileErrorCollector* multi_file_error_collector)
+ : filename_(filename),
+ multi_file_error_collector_(multi_file_error_collector),
+ had_errors_(false) {}
+ ~SingleFileErrorCollector() {}
+
+ bool had_errors() { return had_errors_; }
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(int line, int column, const string& message) {
+ if (multi_file_error_collector_ != NULL) {
+ multi_file_error_collector_->AddError(filename_, line, column, message);
+ }
+ had_errors_ = true;
+ }
+
+ private:
+ string filename_;
+ MultiFileErrorCollector* multi_file_error_collector_;
+ bool had_errors_;
+};
+
+// ===================================================================
+
+SourceTreeDescriptorDatabase::SourceTreeDescriptorDatabase(
+ SourceTree* source_tree)
+ : source_tree_(source_tree),
+ error_collector_(NULL),
+ using_validation_error_collector_(false),
+ validation_error_collector_(this) {}
+
+SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {}
+
+bool SourceTreeDescriptorDatabase::FindFileByName(
+ const string& filename, FileDescriptorProto* output) {
+ scoped_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename));
+ if (input == NULL) {
+ if (error_collector_ != NULL) {
+ error_collector_->AddError(filename, -1, 0, "File not found.");
+ }
+ return false;
+ }
+
+ // Set up the tokenizer and parser.
+ SingleFileErrorCollector file_error_collector(filename, error_collector_);
+ io::Tokenizer tokenizer(input.get(), &file_error_collector);
+
+ Parser parser;
+ if (error_collector_ != NULL) {
+ parser.RecordErrorsTo(&file_error_collector);
+ }
+ if (using_validation_error_collector_) {
+ parser.RecordSourceLocationsTo(&source_locations_);
+ }
+
+ // Parse it.
+ output->set_name(filename);
+ return parser.Parse(&tokenizer, output) &&
+ !file_error_collector.had_errors();
+}
+
+bool SourceTreeDescriptorDatabase::FindFileContainingSymbol(
+ const string& symbol_name, FileDescriptorProto* output) {
+ return false;
+}
+
+bool SourceTreeDescriptorDatabase::FindFileContainingExtension(
+ const string& containing_type, int field_number,
+ FileDescriptorProto* output) {
+ return false;
+}
+
+// -------------------------------------------------------------------
+
+SourceTreeDescriptorDatabase::ValidationErrorCollector::
+ValidationErrorCollector(SourceTreeDescriptorDatabase* owner)
+ : owner_(owner) {}
+
+SourceTreeDescriptorDatabase::ValidationErrorCollector::
+~ValidationErrorCollector() {}
+
+void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError(
+ const string& filename,
+ const string& element_name,
+ const Message* descriptor,
+ ErrorLocation location,
+ const string& message) {
+ if (owner_->error_collector_ == NULL) return;
+
+ int line, column;
+ owner_->source_locations_.Find(descriptor, location, &line, &column);
+ owner_->error_collector_->AddError(filename, line, column, message);
+}
+
+// ===================================================================
+
+Importer::Importer(SourceTree* source_tree,
+ MultiFileErrorCollector* error_collector)
+ : database_(source_tree),
+ pool_(&database_, database_.GetValidationErrorCollector()) {
+ database_.RecordErrorsTo(error_collector);
+}
+
+Importer::~Importer() {}
+
+const FileDescriptor* Importer::Import(const string& filename) {
+ return pool_.FindFileByName(filename);
+}
+
+// ===================================================================
+
+SourceTree::~SourceTree() {}
+
+DiskSourceTree::DiskSourceTree() {}
+
+DiskSourceTree::~DiskSourceTree() {}
+
+static inline char LastChar(const string& str) {
+ return str[str.size() - 1];
+}
+
+// Given a path, returns an equivalent path with these changes:
+// - On Windows, any backslashes are replaced with forward slashes.
+// - Any instances of the directory "." are removed.
+// - Any consecutive '/'s are collapsed into a single slash.
+// Note that the resulting string may be empty.
+//
+// TODO(kenton): It would be nice to handle "..", e.g. so that we can figure
+// out that "foo/bar.proto" is inside "baz/../foo". However, if baz is a
+// symlink or doesn't exist, then things get complicated, and we can't
+// actually determine this without investigating the filesystem, probably
+// in non-portable ways. So, we punt.
+//
+// TODO(kenton): It would be nice to use realpath() here except that it
+// resolves symbolic links. This could cause problems if people place
+// symbolic links in their source tree. For example, if you executed:
+// protoc --proto_path=foo foo/bar/baz.proto
+// then if foo/bar is a symbolic link, foo/bar/baz.proto will canonicalize
+// to a path which does not appear to be under foo, and thus the compiler
+// will complain that baz.proto is not inside the --proto_path.
+static string CanonicalizePath(string path) {
+#ifdef _WIN32
+ // The Win32 API accepts forward slashes as a path delimiter even though
+ // backslashes are standard. Let's avoid confusion and use only forward
+ // slashes.
+ if (HasPrefixString(path, "\\\\")) {
+ // Avoid converting two leading backslashes.
+ path = "\\\\" + StringReplace(path.substr(2), "\\", "/", true);
+ } else {
+ path = StringReplace(path, "\\", "/", true);
+ }
+#endif
+
+ vector<string> parts;
+ vector<string> canonical_parts;
+ SplitStringUsing(path, "/", &parts); // Note: Removes empty parts.
+ for (int i = 0; i < parts.size(); i++) {
+ if (parts[i] == ".") {
+ // Ignore.
+ } else {
+ canonical_parts.push_back(parts[i]);
+ }
+ }
+ string result = JoinStrings(canonical_parts, "/");
+ if (!path.empty() && path[0] == '/') {
+ // Restore leading slash.
+ result = '/' + result;
+ }
+ if (!path.empty() && LastChar(path) == '/' &&
+ !result.empty() && LastChar(result) != '/') {
+ // Restore trailing slash.
+ result += '/';
+ }
+ return result;
+}
+
+static inline bool ContainsParentReference(const string& path) {
+ return path == ".." ||
+ HasPrefixString(path, "../") ||
+ HasSuffixString(path, "/..") ||
+ path.find("/../") != string::npos;
+}
+
+// Maps a file from an old location to a new one. Typically, old_prefix is
+// a virtual path and new_prefix is its corresponding disk path. Returns
+// false if the filename did not start with old_prefix, otherwise replaces
+// old_prefix with new_prefix and stores the result in *result. Examples:
+// string result;
+// assert(ApplyMapping("foo/bar", "", "baz", &result));
+// assert(result == "baz/foo/bar");
+//
+// assert(ApplyMapping("foo/bar", "foo", "baz", &result));
+// assert(result == "baz/bar");
+//
+// assert(ApplyMapping("foo", "foo", "bar", &result));
+// assert(result == "bar");
+//
+// assert(!ApplyMapping("foo/bar", "baz", "qux", &result));
+// assert(!ApplyMapping("foo/bar", "baz", "qux", &result));
+// assert(!ApplyMapping("foobar", "foo", "baz", &result));
+static bool ApplyMapping(const string& filename,
+ const string& old_prefix,
+ const string& new_prefix,
+ string* result) {
+ if (old_prefix.empty()) {
+ // old_prefix matches any relative path.
+ if (ContainsParentReference(filename)) {
+ // We do not allow the file name to use "..".
+ return false;
+ }
+ if (HasPrefixString(filename, "/") ||
+ IsWindowsAbsolutePath(filename)) {
+ // This is an absolute path, so it isn't matched by the empty string.
+ return false;
+ }
+ result->assign(new_prefix);
+ if (!result->empty()) result->push_back('/');
+ result->append(filename);
+ return true;
+ } else if (HasPrefixString(filename, old_prefix)) {
+ // old_prefix is a prefix of the filename. Is it the whole filename?
+ if (filename.size() == old_prefix.size()) {
+ // Yep, it's an exact match.
+ *result = new_prefix;
+ return true;
+ } else {
+ // Not an exact match. Is the next character a '/'? Otherwise,
+ // this isn't actually a match at all. E.g. the prefix "foo/bar"
+ // does not match the filename "foo/barbaz".
+ int after_prefix_start = -1;
+ if (filename[old_prefix.size()] == '/') {
+ after_prefix_start = old_prefix.size() + 1;
+ } else if (filename[old_prefix.size() - 1] == '/') {
+ // old_prefix is never empty, and canonicalized paths never have
+ // consecutive '/' characters.
+ after_prefix_start = old_prefix.size();
+ }
+ if (after_prefix_start != -1) {
+ // Yep. So the prefixes are directories and the filename is a file
+ // inside them.
+ string after_prefix = filename.substr(after_prefix_start);
+ if (ContainsParentReference(after_prefix)) {
+ // We do not allow the file name to use "..".
+ return false;
+ }
+ result->assign(new_prefix);
+ if (!result->empty()) result->push_back('/');
+ result->append(after_prefix);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void DiskSourceTree::MapPath(const string& virtual_path,
+ const string& disk_path) {
+ mappings_.push_back(Mapping(virtual_path, CanonicalizePath(disk_path)));
+}
+
+DiskSourceTree::DiskFileToVirtualFileResult
+DiskSourceTree::DiskFileToVirtualFile(
+ const string& disk_file,
+ string* virtual_file,
+ string* shadowing_disk_file) {
+ int mapping_index = -1;
+ string canonical_disk_file = CanonicalizePath(disk_file);
+
+ for (int i = 0; i < mappings_.size(); i++) {
+ // Apply the mapping in reverse.
+ if (ApplyMapping(canonical_disk_file, mappings_[i].disk_path,
+ mappings_[i].virtual_path, virtual_file)) {
+ // Success.
+ mapping_index = i;
+ break;
+ }
+ }
+
+ if (mapping_index == -1) {
+ return NO_MAPPING;
+ }
+
+ // Iterate through all mappings with higher precedence and verify that none
+ // of them map this file to some other existing file.
+ for (int i = 0; i < mapping_index; i++) {
+ if (ApplyMapping(*virtual_file, mappings_[i].virtual_path,
+ mappings_[i].disk_path, shadowing_disk_file)) {
+ if (access(shadowing_disk_file->c_str(), F_OK) >= 0) {
+ // File exists.
+ return SHADOWED;
+ }
+ }
+ }
+ shadowing_disk_file->clear();
+
+ // Verify that we can open the file. Note that this also has the side-effect
+ // of verifying that we are not canonicalizing away any non-existent
+ // directories.
+ scoped_ptr<io::ZeroCopyInputStream> stream(OpenDiskFile(disk_file));
+ if (stream == NULL) {
+ return CANNOT_OPEN;
+ }
+
+ return SUCCESS;
+}
+
+bool DiskSourceTree::VirtualFileToDiskFile(const string& virtual_file,
+ string* disk_file) {
+ scoped_ptr<io::ZeroCopyInputStream> stream(OpenVirtualFile(virtual_file,
+ disk_file));
+ return stream != NULL;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::Open(const string& filename) {
+ return OpenVirtualFile(filename, NULL);
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile(
+ const string& virtual_file,
+ string* disk_file) {
+ if (virtual_file != CanonicalizePath(virtual_file) ||
+ ContainsParentReference(virtual_file)) {
+ // We do not allow importing of paths containing things like ".." or
+ // consecutive slashes since the compiler expects files to be uniquely
+ // identified by file name.
+ return NULL;
+ }
+
+ for (int i = 0; i < mappings_.size(); i++) {
+ string temp_disk_file;
+ if (ApplyMapping(virtual_file, mappings_[i].virtual_path,
+ mappings_[i].disk_path, &temp_disk_file)) {
+ io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file);
+ if (stream != NULL) {
+ if (disk_file != NULL) {
+ *disk_file = temp_disk_file;
+ }
+ return stream;
+ }
+
+ if (errno == EACCES) {
+ // The file exists but is not readable.
+ // TODO(kenton): Find a way to report this more nicely.
+ GOOGLE_LOG(WARNING) << "Read access is denied for file: " << temp_disk_file;
+ return NULL;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile(
+ const string& filename) {
+ int file_descriptor;
+ do {
+ file_descriptor = open(filename.c_str(), O_RDONLY);
+ } while (file_descriptor < 0 && errno == EINTR);
+ if (file_descriptor >= 0) {
+ io::FileInputStream* result = new io::FileInputStream(file_descriptor);
+ result->SetCloseOnDelete(true);
+ return result;
+ } else {
+ return NULL;
+ }
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/importer.h b/src/third_party/protobuf/src/google/protobuf/compiler/importer.h
new file mode 100644
index 0000000..7a2efc2
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/importer.h
@@ -0,0 +1,303 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file is the public interface to the .proto file parser.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
+#define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
+
+#include <string>
+#include <vector>
+#include <set>
+#include <utility>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/compiler/parser.h>
+
+namespace google {
+namespace protobuf {
+
+namespace io { class ZeroCopyInputStream; }
+
+namespace compiler {
+
+// Defined in this file.
+class Importer;
+class MultiFileErrorCollector;
+class SourceTree;
+class DiskSourceTree;
+
+// TODO(kenton): Move all SourceTree stuff to a separate file?
+
+// An implementation of DescriptorDatabase which loads files from a SourceTree
+// and parses them.
+//
+// Note: This class is not thread-safe since it maintains a table of source
+// code locations for error reporting. However, when a DescriptorPool wraps
+// a DescriptorDatabase, it uses mutex locking to make sure only one method
+// of the database is called at a time, even if the DescriptorPool is used
+// from multiple threads. Therefore, there is only a problem if you create
+// multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase
+// and use them from multiple threads.
+//
+// Note: This class does not implement FindFileContainingSymbol() or
+// FindFileContainingExtension(); these will always return false.
+class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase {
+ public:
+ SourceTreeDescriptorDatabase(SourceTree* source_tree);
+ ~SourceTreeDescriptorDatabase();
+
+ // Instructs the SourceTreeDescriptorDatabase to report any parse errors
+ // to the given MultiFileErrorCollector. This should be called before
+ // parsing. error_collector must remain valid until either this method
+ // is called again or the SourceTreeDescriptorDatabase is destroyed.
+ void RecordErrorsTo(MultiFileErrorCollector* error_collector) {
+ error_collector_ = error_collector;
+ }
+
+ // Gets a DescriptorPool::ErrorCollector which records errors to the
+ // MultiFileErrorCollector specified with RecordErrorsTo(). This collector
+ // has the ability to determine exact line and column numbers of errors
+ // from the information given to it by the DescriptorPool.
+ DescriptorPool::ErrorCollector* GetValidationErrorCollector() {
+ using_validation_error_collector_ = true;
+ return &validation_error_collector_;
+ }
+
+ // implements DescriptorDatabase -----------------------------------
+ bool FindFileByName(const string& filename, FileDescriptorProto* output);
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output);
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output);
+
+ private:
+ class SingleFileErrorCollector;
+
+ SourceTree* source_tree_;
+ MultiFileErrorCollector* error_collector_;
+
+ class LIBPROTOBUF_EXPORT ValidationErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+ ValidationErrorCollector(SourceTreeDescriptorDatabase* owner);
+ ~ValidationErrorCollector();
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const string& filename,
+ const string& element_name,
+ const Message* descriptor,
+ ErrorLocation location,
+ const string& message);
+
+ private:
+ SourceTreeDescriptorDatabase* owner_;
+ };
+ friend class ValidationErrorCollector;
+
+ bool using_validation_error_collector_;
+ SourceLocationTable source_locations_;
+ ValidationErrorCollector validation_error_collector_;
+};
+
+// Simple interface for parsing .proto files. This wraps the process
+// of opening the file, parsing it with a Parser, recursively parsing all its
+// imports, and then cross-linking the results to produce a FileDescriptor.
+//
+// This is really just a thin wrapper around SourceTreeDescriptorDatabase.
+// You may find that SourceTreeDescriptorDatabase is more flexible.
+//
+// TODO(kenton): I feel like this class is not well-named.
+class LIBPROTOBUF_EXPORT Importer {
+ public:
+ Importer(SourceTree* source_tree,
+ MultiFileErrorCollector* error_collector);
+ ~Importer();
+
+ // Import the given file and build a FileDescriptor representing it. If
+ // the file is already in the DescriptorPool, the existing FileDescriptor
+ // will be returned. The FileDescriptor is property of the DescriptorPool,
+ // and will remain valid until it is destroyed. If any errors occur, they
+ // will be reported using the error collector and Import() will return NULL.
+ //
+ // A particular Importer object will only report errors for a particular
+ // file once. All future attempts to import the same file will return NULL
+ // without reporting any errors. The idea is that you might want to import
+ // a lot of files without seeing the same errors over and over again. If
+ // you want to see errors for the same files repeatedly, you can use a
+ // separate Importer object to import each one (but use the same
+ // DescriptorPool so that they can be cross-linked).
+ const FileDescriptor* Import(const string& filename);
+
+ // The DescriptorPool in which all imported FileDescriptors and their
+ // contents are stored.
+ inline const DescriptorPool* pool() const {
+ return &pool_;
+ }
+
+ private:
+ SourceTreeDescriptorDatabase database_;
+ DescriptorPool pool_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer);
+};
+
+// If the importer encounters problems while trying to import the proto files,
+// it reports them to a MultiFileErrorCollector.
+class LIBPROTOBUF_EXPORT MultiFileErrorCollector {
+ public:
+ inline MultiFileErrorCollector() {}
+ virtual ~MultiFileErrorCollector();
+
+ // Line and column numbers are zero-based. A line number of -1 indicates
+ // an error with the entire file (e.g. "not found").
+ virtual void AddError(const string& filename, int line, int column,
+ const string& message) = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector);
+};
+
+// Abstract interface which represents a directory tree containing proto files.
+// Used by the default implementation of Importer to resolve import statements
+// Most users will probably want to use the DiskSourceTree implementation,
+// below.
+class LIBPROTOBUF_EXPORT SourceTree {
+ public:
+ inline SourceTree() {}
+ virtual ~SourceTree();
+
+ // Open the given file and return a stream that reads it, or NULL if not
+ // found. The caller takes ownership of the returned object. The filename
+ // must be a path relative to the root of the source tree and must not
+ // contain "." or ".." components.
+ virtual io::ZeroCopyInputStream* Open(const string& filename) = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree);
+};
+
+// An implementation of SourceTree which loads files from locations on disk.
+// Multiple mappings can be set up to map locations in the DiskSourceTree to
+// locations in the physical filesystem.
+class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree {
+ public:
+ DiskSourceTree();
+ ~DiskSourceTree();
+
+ // Map a path on disk to a location in the SourceTree. The path may be
+ // either a file or a directory. If it is a directory, the entire tree
+ // under it will be mapped to the given virtual location. To map a directory
+ // to the root of the source tree, pass an empty string for virtual_path.
+ //
+ // If multiple mapped paths apply when opening a file, they will be searched
+ // in order. For example, if you do:
+ // MapPath("bar", "foo/bar");
+ // MapPath("", "baz");
+ // and then you do:
+ // Open("bar/qux");
+ // the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux,
+ // returning the first one that opens successfuly.
+ //
+ // disk_path may be an absolute path or relative to the current directory,
+ // just like a path you'd pass to open().
+ void MapPath(const string& virtual_path, const string& disk_path);
+
+ // Return type for DiskFileToVirtualFile().
+ enum DiskFileToVirtualFileResult {
+ SUCCESS,
+ SHADOWED,
+ CANNOT_OPEN,
+ NO_MAPPING
+ };
+
+ // Given a path to a file on disk, find a virtual path mapping to that
+ // file. The first mapping created with MapPath() whose disk_path contains
+ // the filename is used. However, that virtual path may not actually be
+ // usable to open the given file. Possible return values are:
+ // * SUCCESS: The mapping was found. *virtual_file is filled in so that
+ // calling Open(*virtual_file) will open the file named by disk_file.
+ // * SHADOWED: A mapping was found, but using Open() to open this virtual
+ // path will end up returning some different file. This is because some
+ // other mapping with a higher precedence also matches this virtual path
+ // and maps it to a different file that exists on disk. *virtual_file
+ // is filled in as it would be in the SUCCESS case. *shadowing_disk_file
+ // is filled in with the disk path of the file which would be opened if
+ // you were to call Open(*virtual_file).
+ // * CANNOT_OPEN: The mapping was found and was not shadowed, but the
+ // file specified cannot be opened. When this value is returned,
+ // errno will indicate the reason the file cannot be opened. *virtual_file
+ // will be set to the virtual path as in the SUCCESS case, even though
+ // it is not useful.
+ // * NO_MAPPING: Indicates that no mapping was found which contains this
+ // file.
+ DiskFileToVirtualFileResult
+ DiskFileToVirtualFile(const string& disk_file,
+ string* virtual_file,
+ string* shadowing_disk_file);
+
+ // Given a virtual path, find the path to the file on disk.
+ // Return true and update disk_file with the on-disk path if the file exists.
+ // Return false and leave disk_file untouched if the file doesn't exist.
+ bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file);
+
+ // implements SourceTree -------------------------------------------
+ io::ZeroCopyInputStream* Open(const string& filename);
+
+ private:
+ struct Mapping {
+ string virtual_path;
+ string disk_path;
+
+ inline Mapping(const string& virtual_path, const string& disk_path)
+ : virtual_path(virtual_path), disk_path(disk_path) {}
+ };
+ vector<Mapping> mappings_;
+
+ // Like Open(), but returns the on-disk path in disk_file if disk_file is
+ // non-NULL and the file could be successfully opened.
+ io::ZeroCopyInputStream* OpenVirtualFile(const string& virtual_file,
+ string* disk_file);
+
+ // Like Open() but given the actual on-disk path.
+ io::ZeroCopyInputStream* OpenDiskFile(const string& filename);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree);
+};
+
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc b/src/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc
new file mode 100644
index 0000000..56fad56
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc
@@ -0,0 +1,600 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+#define EXPECT_SUBSTRING(needle, haystack) \
+ EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack))
+
+class MockErrorCollector : public MultiFileErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const string& filename, int line, int column,
+ const string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
+ filename, line, column, message);
+ }
+};
+
+// -------------------------------------------------------------------
+
+// A dummy implementation of SourceTree backed by a simple map.
+class MockSourceTree : public SourceTree {
+ public:
+ MockSourceTree() {}
+ ~MockSourceTree() {}
+
+ void AddFile(const string& name, const char* contents) {
+ files_[name] = contents;
+ }
+
+ // implements SourceTree -------------------------------------------
+ io::ZeroCopyInputStream* Open(const string& filename) {
+ const char* contents = FindPtrOrNull(files_, filename);
+ if (contents == NULL) {
+ return NULL;
+ } else {
+ return new io::ArrayInputStream(contents, strlen(contents));
+ }
+ }
+
+ private:
+ hash_map<string, const char*> files_;
+};
+
+// ===================================================================
+
+class ImporterTest : public testing::Test {
+ protected:
+ ImporterTest()
+ : importer_(&source_tree_, &error_collector_) {}
+
+ void AddFile(const string& filename, const char* text) {
+ source_tree_.AddFile(filename, text);
+ }
+
+ // Return the collected error text
+ string error() const { return error_collector_.text_; }
+
+ MockErrorCollector error_collector_;
+ MockSourceTree source_tree_;
+ Importer importer_;
+};
+
+TEST_F(ImporterTest, Import) {
+ // Test normal importing.
+ AddFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+
+ const FileDescriptor* file = importer_.Import("foo.proto");
+ EXPECT_EQ("", error_collector_.text_);
+ ASSERT_TRUE(file != NULL);
+
+ ASSERT_EQ(1, file->message_type_count());
+ EXPECT_EQ("Foo", file->message_type(0)->name());
+
+ // Importing again should return same object.
+ EXPECT_EQ(file, importer_.Import("foo.proto"));
+}
+
+TEST_F(ImporterTest, ImportNested) {
+ // Test that importing a file which imports another file works.
+ AddFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n"
+ "message Foo {\n"
+ " optional Bar bar = 1;\n"
+ "}\n");
+ AddFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "message Bar {}\n");
+
+ // Note that both files are actually parsed by the first call to Import()
+ // here, since foo.proto imports bar.proto. The second call just returns
+ // the same ProtoFile for bar.proto which was constructed while importing
+ // foo.proto. We test that this is the case below by checking that bar
+ // is among foo's dependencies (by pointer).
+ const FileDescriptor* foo = importer_.Import("foo.proto");
+ const FileDescriptor* bar = importer_.Import("bar.proto");
+ EXPECT_EQ("", error_collector_.text_);
+ ASSERT_TRUE(foo != NULL);
+ ASSERT_TRUE(bar != NULL);
+
+ // Check that foo's dependency is the same object as bar.
+ ASSERT_EQ(1, foo->dependency_count());
+ EXPECT_EQ(bar, foo->dependency(0));
+
+ // Check that foo properly cross-links bar.
+ ASSERT_EQ(1, foo->message_type_count());
+ ASSERT_EQ(1, bar->message_type_count());
+ ASSERT_EQ(1, foo->message_type(0)->field_count());
+ ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE,
+ foo->message_type(0)->field(0)->type());
+ EXPECT_EQ(bar->message_type(0),
+ foo->message_type(0)->field(0)->message_type());
+}
+
+TEST_F(ImporterTest, FileNotFound) {
+ // Error: Parsing a file that doesn't exist.
+ EXPECT_TRUE(importer_.Import("foo.proto") == NULL);
+ EXPECT_EQ(
+ "foo.proto:-1:0: File not found.\n",
+ error_collector_.text_);
+}
+
+TEST_F(ImporterTest, ImportNotFound) {
+ // Error: Importing a file that doesn't exist.
+ AddFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "import \"bar.proto\";\n");
+
+ EXPECT_TRUE(importer_.Import("foo.proto") == NULL);
+ EXPECT_EQ(
+ "bar.proto:-1:0: File not found.\n"
+ "foo.proto:-1:0: Import \"bar.proto\" was not found or had errors.\n",
+ error_collector_.text_);
+}
+
+TEST_F(ImporterTest, RecursiveImport) {
+ // Error: Recursive import.
+ AddFile("recursive1.proto",
+ "syntax = \"proto2\";\n"
+ "import \"recursive2.proto\";\n");
+ AddFile("recursive2.proto",
+ "syntax = \"proto2\";\n"
+ "import \"recursive1.proto\";\n");
+
+ EXPECT_TRUE(importer_.Import("recursive1.proto") == NULL);
+ EXPECT_EQ(
+ "recursive1.proto:-1:0: File recursively imports itself: recursive1.proto "
+ "-> recursive2.proto -> recursive1.proto\n"
+ "recursive2.proto:-1:0: Import \"recursive1.proto\" was not found "
+ "or had errors.\n"
+ "recursive1.proto:-1:0: Import \"recursive2.proto\" was not found "
+ "or had errors.\n",
+ error_collector_.text_);
+}
+
+// TODO(sanjay): The MapField tests below more properly belong in
+// descriptor_unittest, but are more convenient to test here.
+TEST_F(ImporterTest, MapFieldValid) {
+ AddFile(
+ "map.proto",
+ "syntax = \"proto2\";\n"
+ "message Item {\n"
+ " required string key = 1;\n"
+ "}\n"
+ "message Map {\n"
+ " repeated Item items = 1 [experimental_map_key = \"key\"];\n"
+ "}\n"
+ );
+ const FileDescriptor* file = importer_.Import("map.proto");
+ ASSERT_TRUE(file != NULL) << error_collector_.text_;
+ EXPECT_EQ("", error_collector_.text_);
+
+ // Check that Map::items points to Item::key
+ const Descriptor* item_type = file->FindMessageTypeByName("Item");
+ ASSERT_TRUE(item_type != NULL);
+ const Descriptor* map_type = file->FindMessageTypeByName("Map");
+ ASSERT_TRUE(map_type != NULL);
+ const FieldDescriptor* key_field = item_type->FindFieldByName("key");
+ ASSERT_TRUE(key_field != NULL);
+ const FieldDescriptor* items_field = map_type->FindFieldByName("items");
+ ASSERT_TRUE(items_field != NULL);
+ EXPECT_EQ(items_field->experimental_map_key(), key_field);
+}
+
+TEST_F(ImporterTest, MapFieldNotRepeated) {
+ AddFile(
+ "map.proto",
+ "syntax = \"proto2\";\n"
+ "message Item {\n"
+ " required string key = 1;\n"
+ "}\n"
+ "message Map {\n"
+ " required Item items = 1 [experimental_map_key = \"key\"];\n"
+ "}\n"
+ );
+ EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+ EXPECT_SUBSTRING("only allowed for repeated fields", error());
+}
+
+TEST_F(ImporterTest, MapFieldNotMessageType) {
+ AddFile(
+ "map.proto",
+ "syntax = \"proto2\";\n"
+ "message Map {\n"
+ " repeated int32 items = 1 [experimental_map_key = \"key\"];\n"
+ "}\n"
+ );
+ EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+ EXPECT_SUBSTRING("only allowed for fields with a message type", error());
+}
+
+TEST_F(ImporterTest, MapFieldTypeNotFound) {
+ AddFile(
+ "map.proto",
+ "syntax = \"proto2\";\n"
+ "message Map {\n"
+ " repeated Unknown items = 1 [experimental_map_key = \"key\"];\n"
+ "}\n"
+ );
+ EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+ EXPECT_SUBSTRING("not defined", error());
+}
+
+TEST_F(ImporterTest, MapFieldKeyNotFound) {
+ AddFile(
+ "map.proto",
+ "syntax = \"proto2\";\n"
+ "message Item {\n"
+ " required string key = 1;\n"
+ "}\n"
+ "message Map {\n"
+ " repeated Item items = 1 [experimental_map_key = \"badkey\"];\n"
+ "}\n"
+ );
+ EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+ EXPECT_SUBSTRING("Could not find field", error());
+}
+
+TEST_F(ImporterTest, MapFieldKeyRepeated) {
+ AddFile(
+ "map.proto",
+ "syntax = \"proto2\";\n"
+ "message Item {\n"
+ " repeated string key = 1;\n"
+ "}\n"
+ "message Map {\n"
+ " repeated Item items = 1 [experimental_map_key = \"key\"];\n"
+ "}\n"
+ );
+ EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+ EXPECT_SUBSTRING("must not name a repeated field", error());
+}
+
+TEST_F(ImporterTest, MapFieldKeyNotScalar) {
+ AddFile(
+ "map.proto",
+ "syntax = \"proto2\";\n"
+ "message ItemKey { }\n"
+ "message Item {\n"
+ " required ItemKey key = 1;\n"
+ "}\n"
+ "message Map {\n"
+ " repeated Item items = 1 [experimental_map_key = \"key\"];\n"
+ "}\n"
+ );
+ EXPECT_TRUE(importer_.Import("map.proto") == NULL);
+ EXPECT_SUBSTRING("must name a scalar or string", error());
+}
+
+// ===================================================================
+
+class DiskSourceTreeTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_1");
+ dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2");
+
+ for (int i = 0; i < dirnames_.size(); i++) {
+ if (File::Exists(dirnames_[i])) {
+ File::DeleteRecursively(dirnames_[i], NULL, NULL);
+ }
+ GOOGLE_CHECK(File::CreateDir(dirnames_[i].c_str(), DEFAULT_FILE_MODE));
+ }
+ }
+
+ virtual void TearDown() {
+ for (int i = 0; i < dirnames_.size(); i++) {
+ File::DeleteRecursively(dirnames_[i], NULL, NULL);
+ }
+ }
+
+ void AddFile(const string& filename, const char* contents) {
+ File::WriteStringToFileOrDie(contents, filename);
+ }
+
+ void AddSubdir(const string& dirname) {
+ GOOGLE_CHECK(File::CreateDir(dirname.c_str(), DEFAULT_FILE_MODE));
+ }
+
+ void ExpectFileContents(const string& filename,
+ const char* expected_contents) {
+ scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
+
+ ASSERT_FALSE(input == NULL);
+
+ // Read all the data from the file.
+ string file_contents;
+ const void* data;
+ int size;
+ while (input->Next(&data, &size)) {
+ file_contents.append(reinterpret_cast<const char*>(data), size);
+ }
+
+ EXPECT_EQ(expected_contents, file_contents);
+ }
+
+ void ExpectFileNotFound(const string& filename) {
+ scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
+ EXPECT_TRUE(input == NULL);
+ }
+
+ DiskSourceTree source_tree_;
+
+ // Paths of two on-disk directories to use during the test.
+ vector<string> dirnames_;
+};
+
+TEST_F(DiskSourceTreeTest, MapRoot) {
+ // Test opening a file in a directory that is mapped to the root of the
+ // source tree.
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ source_tree_.MapPath("", dirnames_[0]);
+
+ ExpectFileContents("foo", "Hello World!");
+ ExpectFileNotFound("bar");
+}
+
+TEST_F(DiskSourceTreeTest, MapDirectory) {
+ // Test opening a file in a directory that is mapped to somewhere other
+ // than the root of the source tree.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ source_tree_.MapPath("baz", dirnames_[0]);
+
+ ExpectFileContents("baz/foo", "Hello World!");
+ ExpectFileNotFound("baz/bar");
+ ExpectFileNotFound("foo");
+ ExpectFileNotFound("bar");
+
+ // Non-canonical file names should not work.
+ ExpectFileNotFound("baz//foo");
+ ExpectFileNotFound("baz/../baz/foo");
+ ExpectFileNotFound("baz/./foo");
+ ExpectFileNotFound("baz/foo/");
+}
+
+TEST_F(DiskSourceTreeTest, NoParent) {
+ // Test that we cannot open files in a parent of a mapped directory.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ AddSubdir(dirnames_[0] + "/bar");
+ AddFile(dirnames_[0] + "/bar/baz", "Blah.");
+ source_tree_.MapPath("", dirnames_[0] + "/bar");
+
+ ExpectFileContents("baz", "Blah.");
+ ExpectFileNotFound("../foo");
+ ExpectFileNotFound("../bar/baz");
+}
+
+TEST_F(DiskSourceTreeTest, MapFile) {
+ // Test opening a file that is mapped directly into the source tree.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ source_tree_.MapPath("foo", dirnames_[0] + "/foo");
+
+ ExpectFileContents("foo", "Hello World!");
+ ExpectFileNotFound("bar");
+}
+
+TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) {
+ // Test mapping and searching multiple directories.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+ AddFile(dirnames_[1] + "/bar", "Goodbye World!");
+ source_tree_.MapPath("", dirnames_[0]);
+ source_tree_.MapPath("", dirnames_[1]);
+
+ ExpectFileContents("foo", "Hello World!");
+ ExpectFileContents("bar", "Goodbye World!");
+ ExpectFileNotFound("baz");
+}
+
+TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) {
+ // Test that directories are always searched in order, even when a latter
+ // directory is more-specific than a former one.
+
+ // Create the "bar" directory so we can put a file in it.
+ ASSERT_TRUE(File::CreateDir((dirnames_[0] + "/bar").c_str(),
+ DEFAULT_FILE_MODE));
+
+ // Add files and map paths.
+ AddFile(dirnames_[0] + "/bar/foo", "Hello World!");
+ AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+ source_tree_.MapPath("", dirnames_[0]);
+ source_tree_.MapPath("bar", dirnames_[1]);
+
+ // Check.
+ ExpectFileContents("bar/foo", "Hello World!");
+}
+
+TEST_F(DiskSourceTreeTest, DiskFileToVirtualFile) {
+ // Test DiskFileToVirtualFile.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+ source_tree_.MapPath("bar", dirnames_[0]);
+ source_tree_.MapPath("bar", dirnames_[1]);
+
+ string virtual_file;
+ string shadowing_disk_file;
+
+ EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+ source_tree_.DiskFileToVirtualFile(
+ "/foo", &virtual_file, &shadowing_disk_file));
+
+ EXPECT_EQ(DiskSourceTree::SHADOWED,
+ source_tree_.DiskFileToVirtualFile(
+ dirnames_[1] + "/foo", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("bar/foo", virtual_file);
+ EXPECT_EQ(dirnames_[0] + "/foo", shadowing_disk_file);
+
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile(
+ dirnames_[1] + "/baz", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("bar/baz", virtual_file);
+
+ EXPECT_EQ(DiskSourceTree::SUCCESS,
+ source_tree_.DiskFileToVirtualFile(
+ dirnames_[0] + "/foo", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("bar/foo", virtual_file);
+}
+
+TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) {
+ // Test handling of "..", ".", etc. in DiskFileToVirtualFile().
+
+ source_tree_.MapPath("dir1", "..");
+ source_tree_.MapPath("dir2", "../../foo");
+ source_tree_.MapPath("dir3", "./foo/bar/.");
+ source_tree_.MapPath("dir4", ".");
+ source_tree_.MapPath("", "/qux");
+ source_tree_.MapPath("dir5", "/quux/");
+
+ string virtual_file;
+ string shadowing_disk_file;
+
+ // "../.." should not be considered to be under "..".
+ EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+ source_tree_.DiskFileToVirtualFile(
+ "../../baz", &virtual_file, &shadowing_disk_file));
+
+ // "/foo" is not mapped (it should not be misintepreted as being under ".").
+ EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+ source_tree_.DiskFileToVirtualFile(
+ "/foo", &virtual_file, &shadowing_disk_file));
+
+#ifdef WIN32
+ // "C:\foo" is not mapped (it should not be misintepreted as being under ".").
+ EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+ source_tree_.DiskFileToVirtualFile(
+ "C:\\foo", &virtual_file, &shadowing_disk_file));
+#endif // WIN32
+
+ // But "../baz" should be.
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile(
+ "../baz", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("dir1/baz", virtual_file);
+
+ // "../../foo/baz" is under "../../foo".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile(
+ "../../foo/baz", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("dir2/baz", virtual_file);
+
+ // "foo/./bar/baz" is under "./foo/bar/.".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile(
+ "foo/bar/baz", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("dir3/baz", virtual_file);
+
+ // "bar" is under ".".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile(
+ "bar", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("dir4/bar", virtual_file);
+
+ // "/qux/baz" is under "/qux".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile(
+ "/qux/baz", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("baz", virtual_file);
+
+ // "/quux/bar" is under "/quux".
+ EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+ source_tree_.DiskFileToVirtualFile(
+ "/quux/bar", &virtual_file, &shadowing_disk_file));
+ EXPECT_EQ("dir5/bar", virtual_file);
+}
+
+TEST_F(DiskSourceTreeTest, VirtualFileToDiskFile) {
+ // Test VirtualFileToDiskFile.
+
+ AddFile(dirnames_[0] + "/foo", "Hello World!");
+ AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+ AddFile(dirnames_[1] + "/quux", "This file should not be hidden.");
+ source_tree_.MapPath("bar", dirnames_[0]);
+ source_tree_.MapPath("bar", dirnames_[1]);
+
+ // Existent files, shadowed and non-shadowed case.
+ string disk_file;
+ EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", &disk_file));
+ EXPECT_EQ(dirnames_[0] + "/foo", disk_file);
+ EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/quux", &disk_file));
+ EXPECT_EQ(dirnames_[1] + "/quux", disk_file);
+
+ // Nonexistent file in existent directory and vice versa.
+ string not_touched = "not touched";
+ EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("bar/baz", ¬_touched));
+ EXPECT_EQ("not touched", not_touched);
+ EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", ¬_touched));
+ EXPECT_EQ("not touched", not_touched);
+
+ // Accept NULL as output parameter.
+ EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", NULL));
+ EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", NULL));
+}
+
+} // namespace
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc
new file mode 100644
index 0000000..9d7bcab
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc
@@ -0,0 +1,243 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ const EnumValueDescriptor* value = descriptor_->value(i);
+ const EnumValueDescriptor* canonical_value =
+ descriptor_->FindValueByNumber(value->number());
+
+ if (value == canonical_value) {
+ canonical_values_.push_back(value);
+ } else {
+ Alias alias;
+ alias.value = value;
+ alias.canonical_value = canonical_value;
+ aliases_.push_back(alias);
+ }
+ }
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::Generate(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public enum $classname$\n"
+ " implements com.google.protobuf.ProtocolMessageEnum {\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public enum $classname$\n"
+ " implements com.google.protobuf.Internal.EnumLite {\n",
+ "classname", descriptor_->name());
+ }
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ map<string, string> vars;
+ vars["name"] = canonical_values_[i]->name();
+ vars["index"] = SimpleItoa(canonical_values_[i]->index());
+ vars["number"] = SimpleItoa(canonical_values_[i]->number());
+ printer->Print(vars,
+ "$name$($index$, $number$),\n");
+ }
+
+ printer->Print(
+ ";\n"
+ "\n");
+
+ // -----------------------------------------------------------------
+
+ for (int i = 0; i < aliases_.size(); i++) {
+ map<string, string> vars;
+ vars["classname"] = descriptor_->name();
+ vars["name"] = aliases_[i].value->name();
+ vars["canonical_name"] = aliases_[i].canonical_value->name();
+ printer->Print(vars,
+ "public static final $classname$ $name$ = $canonical_name$;\n");
+ }
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ map<string, string> vars;
+ vars["name"] = descriptor_->value(i)->name();
+ vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+ printer->Print(vars,
+ "public static final int $name$_VALUE = $number$;\n");
+ }
+ printer->Print("\n");
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "\n"
+ "public final int getNumber() { return value; }\n"
+ "\n"
+ "public static $classname$ valueOf(int value) {\n"
+ " switch (value) {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ printer->Print(
+ "case $number$: return $name$;\n",
+ "name", canonical_values_[i]->name(),
+ "number", SimpleItoa(canonical_values_[i]->number()));
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " default: return null;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+ " internalGetValueMap() {\n"
+ " return internalValueMap;\n"
+ "}\n"
+ "private static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+ " internalValueMap =\n"
+ " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
+ " public $classname$ findValueByNumber(int number) {\n"
+ " return $classname$.valueOf(number);\n"
+ " }\n"
+ " };\n"
+ "\n",
+ "classname", descriptor_->name());
+
+ // -----------------------------------------------------------------
+ // Reflection
+
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n"
+ " getValueDescriptor() {\n"
+ " return getDescriptor().getValues().get(index);\n"
+ "}\n"
+ "public final com.google.protobuf.Descriptors.EnumDescriptor\n"
+ " getDescriptorForType() {\n"
+ " return getDescriptor();\n"
+ "}\n"
+ "public static final com.google.protobuf.Descriptors.EnumDescriptor\n"
+ " getDescriptor() {\n");
+
+ // TODO(kenton): Cache statically? Note that we can't access descriptors
+ // at module init time because it wouldn't work with descriptor.proto, but
+ // we can cache the value the first time getDescriptor() is called.
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(
+ " return $file$.getDescriptor().getEnumTypes().get($index$);\n",
+ "file", ClassName(descriptor_->file()),
+ "index", SimpleItoa(descriptor_->index()));
+ } else {
+ printer->Print(
+ " return $parent$.getDescriptor().getEnumTypes().get($index$);\n",
+ "parent", ClassName(descriptor_->containing_type()),
+ "index", SimpleItoa(descriptor_->index()));
+ }
+
+ printer->Print(
+ "}\n"
+ "\n"
+ "private static final $classname$[] VALUES = {\n"
+ " ",
+ "classname", descriptor_->name());
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ printer->Print("$name$, ",
+ "name", descriptor_->value(i)->name());
+ }
+
+ printer->Print(
+ "\n"
+ "};\n"
+ "\n"
+ "public static $classname$ valueOf(\n"
+ " com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n"
+ " if (desc.getType() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"EnumValueDescriptor is not for this type.\");\n"
+ " }\n"
+ " return VALUES[desc.getIndex()];\n"
+ "}\n"
+ "\n",
+ "classname", descriptor_->name());
+
+ // index is only used for reflection; lite implementation does not need it
+ printer->Print("private final int index;\n");
+ }
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "private final int value;\n\n"
+ "private $classname$(int index, int value) {\n",
+ "classname", descriptor_->name());
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(" this.index = index;\n");
+ }
+ printer->Print(
+ " this.value = value;\n"
+ "}\n");
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(enum_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.h
new file mode 100644
index 0000000..05ece1f
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.h
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumGenerator {
+ public:
+ explicit EnumGenerator(const EnumDescriptor* descriptor);
+ ~EnumGenerator();
+
+ void Generate(io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+
+ // The proto language allows multiple enum constants to have the same numeric
+ // value. Java, however, does not allow multiple enum constants to be
+ // considered equivalent. We treat the first defined constant for any
+ // given numeric value as "canonical" and the rest as aliases of that
+ // canonical value.
+ vector<const EnumValueDescriptor*> canonical_values_;
+
+ struct Alias {
+ const EnumValueDescriptor* value;
+ const EnumValueDescriptor* canonical_value;
+ };
+ vector<Alias> aliases_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc
new file mode 100644
index 0000000..72caa10
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -0,0 +1,537 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_enum_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
+// repeat code between this and the other field types.
+void SetEnumVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ map<string, string>* variables) {
+ (*variables)["name"] =
+ UnderscoresToCamelCase(descriptor);
+ (*variables)["capitalized_name"] =
+ UnderscoresToCapitalizedCamelCase(descriptor);
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["type"] = ClassName(descriptor->enum_type());
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+ (*variables)["tag_size"] = SimpleItoa(
+ internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
+ (*variables)["on_changed"] =
+ HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex);
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::
+EnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, &variables_);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+int EnumFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int EnumFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void EnumFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n"
+ "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void EnumFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private $type$ $name$_;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private $type$ $name$_ = $default$;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n"
+ "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$;\n"
+ " $name$_ = $default$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for enums
+}
+
+void EnumFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void EnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ "$type$ value = $type$.valueOf(rawValue);\n");
+ if (HasUnknownFields(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "if (value == null) {\n"
+ " unknownFields.mergeVarintField($number$, rawValue);\n"
+ "} else {\n");
+ } else {
+ printer->Print(variables_,
+ "if (value != null) {\n");
+ }
+ printer->Print(variables_,
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " output.writeEnum($number$, $name$_.getNumber());\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeEnumSize($number$, $name$_.getNumber());\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result &&\n"
+ " (get$capitalized_name$() == other.get$capitalized_name$());\n");
+}
+
+void EnumFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + hashEnum(get$capitalized_name$());\n");
+}
+
+string EnumFieldGenerator::GetBoxedType() const {
+ return ClassName(descriptor_->enum_type());
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, &variables_);
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+int RepeatedEnumFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedEnumFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n"
+ "$deprecation$int get$capitalized_name$Count();\n"
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.util.List<$type$> $name$_;\n"
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+
+ if (descriptor_->options().packed() &&
+ HasGeneratedMethods(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "private int $name$MemoizedSerializedSize;\n");
+ }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ // One field is the list and the other field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ "private java.util.List<$type$> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n"
+
+ // Note: We return an unmodifiable list because otherwise the caller
+ // could hold on to the returned list and modify it after the message
+ // has been built, thus mutating the message which is supposed to be
+ // immutable.
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n"
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $type$> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " super.addAll(values, $name$_);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $name$_ = java.util.Collections.emptyList();\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for enums
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ printer->Print(variables_,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
+ printer->Print(variables_,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ // Read and store the enum
+ printer->Print(variables_,
+ "int rawValue = input.readEnum();\n"
+ "$type$ value = $type$.valueOf(rawValue);\n");
+ if (HasUnknownFields(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "if (value == null) {\n"
+ " unknownFields.mergeVarintField($number$, rawValue);\n"
+ "} else {\n");
+ } else {
+ printer->Print(variables_,
+ "if (value != null) {\n");
+ }
+ printer->Print(variables_,
+ " add$capitalized_name$(value);\n"
+ "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+ // Wrap GenerateParsingCode's contents with a while loop.
+
+ printer->Print(variables_,
+ "int length = input.readRawVarint32();\n"
+ "int oldLimit = input.pushLimit(length);\n"
+ "while(input.getBytesUntilLimit() > 0) {\n");
+ printer->Indent();
+
+ GenerateParsingCode(printer);
+
+ printer->Outdent();
+ printer->Print(variables_,
+ "}\n"
+ "input.popLimit(oldLimit);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (get$capitalized_name$List().size() > 0) {\n"
+ " output.writeRawVarint32($tag$);\n"
+ " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ "}\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeEnumNoTag($name$_.get(i).getNumber());\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeEnum($number$, $name$_.get(i).getNumber());\n"
+ "}\n");
+ }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .computeEnumSizeNoTag($name$_.get(i).getNumber());\n"
+ "}\n");
+ printer->Print(
+ "size += dataSize;\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$List().isEmpty()) {"
+ " size += $tag_size$;\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeRawVarint32Size(dataSize);\n"
+ "}");
+ } else {
+ printer->Print(variables_,
+ "size += $tag_size$ * $name$_.size();\n");
+ }
+
+ // cache the data size for packed fields.
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "$name$MemoizedSerializedSize = dataSize;\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + hashEnumList(get$capitalized_name$List());\n"
+ "}\n");
+}
+
+string RepeatedEnumFieldGenerator::GetBoxedType() const {
+ return ClassName(descriptor_->enum_type());
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h
new file mode 100644
index 0000000..0cad6be
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumFieldGenerator : public FieldGenerator {
+ public:
+ explicit EnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~EnumFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+};
+
+class RepeatedEnumFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~RepeatedEnumFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc
new file mode 100644
index 0000000..9b147c7
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc
@@ -0,0 +1,216 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+const char* TypeName(FieldDescriptor::Type field_type) {
+ switch (field_type) {
+ case FieldDescriptor::TYPE_INT32 : return "INT32";
+ case FieldDescriptor::TYPE_UINT32 : return "UINT32";
+ case FieldDescriptor::TYPE_SINT32 : return "SINT32";
+ case FieldDescriptor::TYPE_FIXED32 : return "FIXED32";
+ case FieldDescriptor::TYPE_SFIXED32: return "SFIXED32";
+ case FieldDescriptor::TYPE_INT64 : return "INT64";
+ case FieldDescriptor::TYPE_UINT64 : return "UINT64";
+ case FieldDescriptor::TYPE_SINT64 : return "SINT64";
+ case FieldDescriptor::TYPE_FIXED64 : return "FIXED64";
+ case FieldDescriptor::TYPE_SFIXED64: return "SFIXED64";
+ case FieldDescriptor::TYPE_FLOAT : return "FLOAT";
+ case FieldDescriptor::TYPE_DOUBLE : return "DOUBLE";
+ case FieldDescriptor::TYPE_BOOL : return "BOOL";
+ case FieldDescriptor::TYPE_STRING : return "STRING";
+ case FieldDescriptor::TYPE_BYTES : return "BYTES";
+ case FieldDescriptor::TYPE_ENUM : return "ENUM";
+ case FieldDescriptor::TYPE_GROUP : return "GROUP";
+ case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+}
+
+ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ if (descriptor_->extension_scope() != NULL) {
+ scope_ = ClassName(descriptor_->extension_scope());
+ } else {
+ scope_ = ClassName(descriptor_->file());
+ }
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+// Initializes the vars referenced in the generated code templates.
+void InitTemplateVars(const FieldDescriptor* descriptor,
+ const string& scope,
+ map<string, string>* vars_pointer) {
+ map<string, string> &vars = *vars_pointer;
+ vars["scope"] = scope;
+ vars["name"] = UnderscoresToCamelCase(descriptor);
+ vars["containing_type"] = ClassName(descriptor->containing_type());
+ vars["number"] = SimpleItoa(descriptor->number());
+ vars["constant_name"] = FieldConstantName(descriptor);
+ vars["index"] = SimpleItoa(descriptor->index());
+ vars["default"] =
+ descriptor->is_repeated() ? "" : DefaultValue(descriptor);
+ vars["type_constant"] = TypeName(GetType(descriptor));
+ vars["packed"] = descriptor->options().packed() ? "true" : "false";
+ vars["enum_map"] = "null";
+ vars["prototype"] = "null";
+
+ JavaType java_type = GetJavaType(descriptor);
+ string singular_type;
+ switch (java_type) {
+ case JAVATYPE_MESSAGE:
+ singular_type = ClassName(descriptor->message_type());
+ vars["prototype"] = singular_type + ".getDefaultInstance()";
+ break;
+ case JAVATYPE_ENUM:
+ singular_type = ClassName(descriptor->enum_type());
+ vars["enum_map"] = singular_type + ".internalGetValueMap()";
+ break;
+ default:
+ singular_type = BoxedPrimitiveTypeName(java_type);
+ break;
+ }
+ vars["type"] = descriptor->is_repeated() ?
+ "java.util.List<" + singular_type + ">" : singular_type;
+ vars["singular_type"] = singular_type;
+}
+
+void ExtensionGenerator::Generate(io::Printer* printer) {
+ map<string, string> vars;
+ InitTemplateVars(descriptor_, scope_, &vars);
+ printer->Print(vars,
+ "public static final int $constant_name$ = $number$;\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ // Non-lite extensions
+ if (descriptor_->extension_scope() == NULL) {
+ // Non-nested
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+ " .newFileScopedGeneratedExtension(\n"
+ " $singular_type$.class,\n"
+ " $prototype$);\n");
+ } else {
+ // Nested
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+ " .newMessageScopedGeneratedExtension(\n"
+ " $scope$.getDefaultInstance(),\n"
+ " $index$,\n"
+ " $singular_type$.class,\n"
+ " $prototype$);\n");
+ }
+ } else {
+ // Lite extensions
+ if (descriptor_->is_repeated()) {
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+ " .newRepeatedGeneratedExtension(\n"
+ " $containing_type$.getDefaultInstance(),\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+ " $packed$);\n");
+ } else {
+ printer->Print(
+ vars,
+ "public static final\n"
+ " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+ " $containing_type$,\n"
+ " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+ " .newSingularGeneratedExtension(\n"
+ " $containing_type$.getDefaultInstance(),\n"
+ " $default$,\n"
+ " $prototype$,\n"
+ " $enum_map$,\n"
+ " $number$,\n"
+ " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n");
+ }
+ }
+}
+
+void ExtensionGenerator::GenerateNonNestedInitializationCode(
+ io::Printer* printer) {
+ if (descriptor_->extension_scope() == NULL &&
+ HasDescriptorMethods(descriptor_->file())) {
+ // Only applies to non-nested, non-lite extensions.
+ printer->Print(
+ "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
+ "name", UnderscoresToCamelCase(descriptor_),
+ "index", SimpleItoa(descriptor_->index()));
+ }
+}
+
+void ExtensionGenerator::GenerateRegistrationCode(io::Printer* printer) {
+ printer->Print(
+ "registry.add($scope$.$name$);\n",
+ "scope", scope_,
+ "name", UnderscoresToCamelCase(descriptor_));
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h
new file mode 100644
index 0000000..009ed9f
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h
@@ -0,0 +1,77 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+ class FieldDescriptor; // descriptor.h
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Generates code for an extension, which may be within the scope of some
+// message or may be at file scope. This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ExtensionGenerator {
+ public:
+ explicit ExtensionGenerator(const FieldDescriptor* descriptor);
+ ~ExtensionGenerator();
+
+ void Generate(io::Printer* printer);
+ void GenerateNonNestedInitializationCode(io::Printer* printer);
+ void GenerateRegistrationCode(io::Printer* printer);
+
+ private:
+ const FieldDescriptor* descriptor_;
+ string scope_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc
new file mode 100644
index 0000000..c7d433c
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc
@@ -0,0 +1,137 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_primitive_field.h>
+#include <google/protobuf/compiler/java/java_enum_field.h>
+#include <google/protobuf/compiler/java/java_message_field.h>
+#include <google/protobuf/compiler/java/java_string_field.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+FieldGenerator::~FieldGenerator() {}
+
+void FieldGenerator::GenerateParsingCodeFromPacked(io::Printer* printer) const {
+ // Reaching here indicates a bug. Cases are:
+ // - This FieldGenerator should support packing, but this method should be
+ // overridden.
+ // - This FieldGenerator doesn't support packing, and this method should
+ // never have been called.
+ GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
+ << "called on field generator that does not support packing.";
+}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
+ : descriptor_(descriptor),
+ field_generators_(
+ new scoped_ptr<FieldGenerator>[descriptor->field_count()]),
+ extension_generators_(
+ new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) {
+
+ // Construct all the FieldGenerators and assign them bit indices for their
+ // bit fields.
+ int messageBitIndex = 0;
+ int builderBitIndex = 0;
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ FieldGenerator* generator = MakeGenerator(descriptor->field(i),
+ messageBitIndex, builderBitIndex);
+ field_generators_[i].reset(generator);
+ messageBitIndex += generator->GetNumBitsForMessage();
+ builderBitIndex += generator->GetNumBitsForBuilder();
+ }
+ for (int i = 0; i < descriptor->extension_count(); i++) {
+ FieldGenerator* generator = MakeGenerator(descriptor->extension(i),
+ messageBitIndex, builderBitIndex);
+ extension_generators_[i].reset(generator);
+ messageBitIndex += generator->GetNumBitsForMessage();
+ builderBitIndex += generator->GetNumBitsForBuilder();
+ }
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(
+ const FieldDescriptor* field, int messageBitIndex, int builderBitIndex) {
+ if (field->is_repeated()) {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ return new RepeatedMessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ case JAVATYPE_ENUM:
+ return new RepeatedEnumFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ case JAVATYPE_STRING:
+ return new RepeatedStringFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ default:
+ return new RepeatedPrimitiveFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ }
+ } else {
+ switch (GetJavaType(field)) {
+ case JAVATYPE_MESSAGE:
+ return new MessageFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ case JAVATYPE_ENUM:
+ return new EnumFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ case JAVATYPE_STRING:
+ return new StringFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ default:
+ return new PrimitiveFieldGenerator(
+ field, messageBitIndex, builderBitIndex);
+ }
+ }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+ const FieldDescriptor* field) const {
+ GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ return *field_generators_[field->index()];
+}
+
+const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
+ return *extension_generators_[index];
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h
new file mode 100644
index 0000000..6097f35
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h
@@ -0,0 +1,108 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class FieldGenerator {
+ public:
+ FieldGenerator() {}
+ virtual ~FieldGenerator();
+
+ virtual int GetNumBitsForMessage() const = 0;
+ virtual int GetNumBitsForBuilder() const = 0;
+ virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0;
+ virtual void GenerateMembers(io::Printer* printer) const = 0;
+ virtual void GenerateBuilderMembers(io::Printer* printer) const = 0;
+ virtual void GenerateInitializationCode(io::Printer* printer) const = 0;
+ virtual void GenerateBuilderClearCode(io::Printer* printer) const = 0;
+ virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+ virtual void GenerateBuildingCode(io::Printer* printer) const = 0;
+ virtual void GenerateParsingCode(io::Printer* printer) const = 0;
+ virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+ virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
+ virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
+ virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer)
+ const = 0;
+
+ virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
+ virtual void GenerateHashCode(io::Printer* printer) const = 0;
+
+ virtual string GetBoxedType() const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+ explicit FieldGeneratorMap(const Descriptor* descriptor);
+ ~FieldGeneratorMap();
+
+ const FieldGenerator& get(const FieldDescriptor* field) const;
+ const FieldGenerator& get_extension(int index) const;
+
+ private:
+ const Descriptor* descriptor_;
+ scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
+ scoped_array<scoped_ptr<FieldGenerator> > extension_generators_;
+
+ static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
+ int messageBitIndex, int builderBitIndex);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc
new file mode 100644
index 0000000..8968069
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc
@@ -0,0 +1,428 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_file.h>
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_service.h>
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_message.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+// Recursively searches the given message to see if it contains any extensions.
+bool UsesExtensions(const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+
+ // We conservatively assume that unknown fields are extensions.
+ if (reflection->GetUnknownFields(message).field_count() > 0) return true;
+
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message, &fields);
+
+ for (int i = 0; i < fields.size(); i++) {
+ if (fields[i]->is_extension()) return true;
+
+ if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) {
+ if (fields[i]->is_repeated()) {
+ int size = reflection->FieldSize(message, fields[i]);
+ for (int j = 0; j < size; j++) {
+ const Message& sub_message =
+ reflection->GetRepeatedMessage(message, fields[i], j);
+ if (UsesExtensions(sub_message)) return true;
+ }
+ } else {
+ const Message& sub_message = reflection->GetMessage(message, fields[i]);
+ if (UsesExtensions(sub_message)) return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+} // namespace
+
+FileGenerator::FileGenerator(const FileDescriptor* file)
+ : file_(file),
+ java_package_(FileJavaPackage(file)),
+ classname_(FileClassName(file)) {
+}
+
+FileGenerator::~FileGenerator() {}
+
+bool FileGenerator::Validate(string* error) {
+ // Check that no class name matches the file's class name. This is a common
+ // problem that leads to Java compile errors that can be hard to understand.
+ // It's especially bad when using the java_multiple_files, since we would
+ // end up overwriting the outer class with one of the inner ones.
+
+ bool found_conflict = false;
+ for (int i = 0; i < file_->enum_type_count() && !found_conflict; i++) {
+ if (file_->enum_type(i)->name() == classname_) {
+ found_conflict = true;
+ }
+ }
+ for (int i = 0; i < file_->message_type_count() && !found_conflict; i++) {
+ if (file_->message_type(i)->name() == classname_) {
+ found_conflict = true;
+ }
+ }
+ for (int i = 0; i < file_->service_count() && !found_conflict; i++) {
+ if (file_->service(i)->name() == classname_) {
+ found_conflict = true;
+ }
+ }
+
+ if (found_conflict) {
+ error->assign(file_->name());
+ error->append(
+ ": Cannot generate Java output because the file's outer class name, \"");
+ error->append(classname_);
+ error->append(
+ "\", matches the name of one of the types declared inside it. "
+ "Please either rename the type or use the java_outer_classname "
+ "option to specify a different outer class name for the .proto file.");
+ return false;
+ }
+
+ return true;
+}
+
+void FileGenerator::Generate(io::Printer* printer) {
+ // We don't import anything because we refer to all classes by their
+ // fully-qualified names in the generated source.
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", file_->name());
+ if (!java_package_.empty()) {
+ printer->Print(
+ "package $package$;\n"
+ "\n",
+ "package", java_package_);
+ }
+ printer->Print(
+ "public final class $classname$ {\n"
+ " private $classname$() {}\n",
+ "classname", classname_);
+ printer->Indent();
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "public static void registerAllExtensions(\n"
+ " com.google.protobuf.ExtensionRegistry$lite$ registry) {\n",
+ "lite", HasDescriptorMethods(file_) ? "" : "Lite");
+
+ printer->Indent();
+
+ for (int i = 0; i < file_->extension_count(); i++) {
+ ExtensionGenerator(file_->extension(i)).GenerateRegistrationCode(printer);
+ }
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ MessageGenerator(file_->message_type(i))
+ .GenerateExtensionRegistrationCode(printer);
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+
+ // -----------------------------------------------------------------
+
+ if (!file_->options().java_multiple_files()) {
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ EnumGenerator(file_->enum_type(i)).Generate(printer);
+ }
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ MessageGenerator messageGenerator(file_->message_type(i));
+ messageGenerator.GenerateInterface(printer);
+ messageGenerator.Generate(printer);
+ }
+ if (HasGenericServices(file_)) {
+ for (int i = 0; i < file_->service_count(); i++) {
+ ServiceGenerator(file_->service(i)).Generate(printer);
+ }
+ }
+ }
+
+ // Extensions must be generated in the outer class since they are values,
+ // not classes.
+ for (int i = 0; i < file_->extension_count(); i++) {
+ ExtensionGenerator(file_->extension(i)).Generate(printer);
+ }
+
+ // Static variables.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ MessageGenerator(file_->message_type(i)).GenerateStaticVariables(printer);
+ }
+
+ printer->Print("\n");
+
+ if (HasDescriptorMethods(file_)) {
+ GenerateEmbeddedDescriptor(printer);
+ } else {
+ printer->Print(
+ "static {\n");
+ printer->Indent();
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ MessageGenerator(file_->message_type(i))
+ .GenerateStaticVariableInitializers(printer);
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(outer_class_scope)\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) {
+ // Embed the descriptor. We simply serialize the entire FileDescriptorProto
+ // and embed it as a string literal, which is parsed and built into real
+ // descriptors at initialization time. We unfortunately have to put it in
+ // a string literal, not a byte array, because apparently using a literal
+ // byte array causes the Java compiler to generate *instructions* to
+ // initialize each and every byte of the array, e.g. as if you typed:
+ // b[0] = 123; b[1] = 456; b[2] = 789;
+ // This makes huge bytecode files and can easily hit the compiler's internal
+ // code size limits (error "code to large"). String literals are apparently
+ // embedded raw, which is what we want.
+ FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+
+ string file_data;
+ file_proto.SerializeToString(&file_data);
+
+ printer->Print(
+ "public static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " getDescriptor() {\n"
+ " return descriptor;\n"
+ "}\n"
+ "private static com.google.protobuf.Descriptors.FileDescriptor\n"
+ " descriptor;\n"
+ "static {\n"
+ " java.lang.String[] descriptorData = {\n");
+ printer->Indent();
+ printer->Indent();
+
+ // Only write 40 bytes per line.
+ static const int kBytesPerLine = 40;
+ for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+ if (i > 0) {
+ // Every 400 lines, start a new string literal, in order to avoid the
+ // 64k length limit.
+ if (i % 400 == 0) {
+ printer->Print(",\n");
+ } else {
+ printer->Print(" +\n");
+ }
+ }
+ printer->Print("\"$data$\"",
+ "data", CEscape(file_data.substr(i, kBytesPerLine)));
+ }
+
+ printer->Outdent();
+ printer->Print("\n};\n");
+
+ // -----------------------------------------------------------------
+ // Create the InternalDescriptorAssigner.
+
+ printer->Print(
+ "com.google.protobuf.Descriptors.FileDescriptor."
+ "InternalDescriptorAssigner assigner =\n"
+ " new com.google.protobuf.Descriptors.FileDescriptor."
+ "InternalDescriptorAssigner() {\n"
+ " public com.google.protobuf.ExtensionRegistry assignDescriptors(\n"
+ " com.google.protobuf.Descriptors.FileDescriptor root) {\n"
+ " descriptor = root;\n");
+
+ printer->Indent();
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ MessageGenerator(file_->message_type(i))
+ .GenerateStaticVariableInitializers(printer);
+ }
+ for (int i = 0; i < file_->extension_count(); i++) {
+ // TODO(kenton): Reuse ExtensionGenerator objects?
+ ExtensionGenerator(file_->extension(i))
+ .GenerateNonNestedInitializationCode(printer);
+ }
+
+ if (UsesExtensions(file_proto)) {
+ // Must construct an ExtensionRegistry containing all possible extensions
+ // and return it.
+ printer->Print(
+ "com.google.protobuf.ExtensionRegistry registry =\n"
+ " com.google.protobuf.ExtensionRegistry.newInstance();\n"
+ "registerAllExtensions(registry);\n");
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ if (ShouldIncludeDependency(file_->dependency(i))) {
+ printer->Print(
+ "$dependency$.registerAllExtensions(registry);\n",
+ "dependency", ClassName(file_->dependency(i)));
+ }
+ }
+ printer->Print(
+ "return registry;\n");
+ } else {
+ printer->Print(
+ "return null;\n");
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ " };\n");
+
+ // -----------------------------------------------------------------
+ // Invoke internalBuildGeneratedFileFrom() to build the file.
+
+ printer->Print(
+ "com.google.protobuf.Descriptors.FileDescriptor\n"
+ " .internalBuildGeneratedFileFrom(descriptorData,\n"
+ " new com.google.protobuf.Descriptors.FileDescriptor[] {\n");
+
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ if (ShouldIncludeDependency(file_->dependency(i))) {
+ printer->Print(
+ " $dependency$.getDescriptor(),\n",
+ "dependency", ClassName(file_->dependency(i)));
+ }
+ }
+
+ printer->Print(
+ " }, assigner);\n");
+
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+}
+
+template<typename GeneratorClass, typename DescriptorClass>
+static void GenerateSibling(const string& package_dir,
+ const string& java_package,
+ const DescriptorClass* descriptor,
+ GeneratorContext* context,
+ vector<string>* file_list,
+ const string& name_suffix,
+ void (GeneratorClass::*pfn)(io::Printer* printer)) {
+ string filename = package_dir + descriptor->name() + name_suffix + ".java";
+ file_list->push_back(filename);
+
+ scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ io::Printer printer(output.get(), '$');
+
+ printer.Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "\n");
+ if (!java_package.empty()) {
+ printer.Print(
+ "package $package$;\n"
+ "\n",
+ "package", java_package);
+ }
+
+ GeneratorClass generator(descriptor);
+ (generator.*pfn)(&printer);
+}
+
+void FileGenerator::GenerateSiblings(const string& package_dir,
+ GeneratorContext* context,
+ vector<string>* file_list) {
+ if (file_->options().java_multiple_files()) {
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ GenerateSibling<EnumGenerator>(package_dir, java_package_,
+ file_->enum_type(i),
+ context, file_list, "",
+ &EnumGenerator::Generate);
+ }
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ GenerateSibling<MessageGenerator>(package_dir, java_package_,
+ file_->message_type(i),
+ context, file_list, "OrBuilder",
+ &MessageGenerator::GenerateInterface);
+ GenerateSibling<MessageGenerator>(package_dir, java_package_,
+ file_->message_type(i),
+ context, file_list, "",
+ &MessageGenerator::Generate);
+ }
+ if (HasGenericServices(file_)) {
+ for (int i = 0; i < file_->service_count(); i++) {
+ GenerateSibling<ServiceGenerator>(package_dir, java_package_,
+ file_->service(i),
+ context, file_list, "",
+ &ServiceGenerator::Generate);
+ }
+ }
+ }
+}
+
+bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor) {
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h
new file mode 100644
index 0000000..5991146
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h
@@ -0,0 +1,101 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+ class FileDescriptor; // descriptor.h
+ namespace io {
+ class Printer; // printer.h
+ }
+ namespace compiler {
+ class GeneratorContext; // code_generator.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class FileGenerator {
+ public:
+ explicit FileGenerator(const FileDescriptor* file);
+ ~FileGenerator();
+
+ // Checks for problems that would otherwise lead to cryptic compile errors.
+ // Returns true if there are no problems, or writes an error description to
+ // the given string and returns false otherwise.
+ bool Validate(string* error);
+
+ void Generate(io::Printer* printer);
+
+ // If we aren't putting everything into one file, this will write all the
+ // files other than the outer file (i.e. one for each message, enum, and
+ // service type).
+ void GenerateSiblings(const string& package_dir,
+ GeneratorContext* generator_context,
+ vector<string>* file_list);
+
+ const string& java_package() { return java_package_; }
+ const string& classname() { return classname_; }
+
+
+ private:
+ // Returns whether the dependency should be included in the output file.
+ // Always returns true for opensource, but used internally at Google to help
+ // improve compatibility with version 1 of protocol buffers.
+ bool ShouldIncludeDependency(const FileDescriptor* descriptor);
+
+ const FileDescriptor* file_;
+ string java_package_;
+ string classname_;
+
+
+ void GenerateEmbeddedDescriptor(io::Printer* printer);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc
new file mode 100644
index 0000000..e6c79ab
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc
@@ -0,0 +1,128 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_generator.h>
+#include <google/protobuf/compiler/java/java_file.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+
+JavaGenerator::JavaGenerator() {}
+JavaGenerator::~JavaGenerator() {}
+
+bool JavaGenerator::Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+ // -----------------------------------------------------------------
+ // parse generator options
+
+ // Name a file where we will write a list of generated file names, one
+ // per line.
+ string output_list_file;
+
+
+ vector<pair<string, string> > options;
+ ParseGeneratorParameter(parameter, &options);
+
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "output_list_file") {
+ output_list_file = options[i].second;
+ } else {
+ *error = "Unknown generator option: " + options[i].first;
+ return false;
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+
+ if (file->options().optimize_for() == FileOptions::LITE_RUNTIME &&
+ file->options().java_generate_equals_and_hash()) {
+ *error = "The \"java_generate_equals_and_hash\" option is incompatible "
+ "with \"optimize_for = LITE_RUNTIME\". You must optimize for "
+ "SPEED or CODE_SIZE if you want to use this option.";
+ return false;
+ }
+
+ FileGenerator file_generator(file);
+ if (!file_generator.Validate(error)) {
+ return false;
+ }
+
+ string package_dir = JavaPackageToDir(file_generator.java_package());
+
+ vector<string> all_files;
+
+ string java_filename = package_dir;
+ java_filename += file_generator.classname();
+ java_filename += ".java";
+ all_files.push_back(java_filename);
+
+ // Generate main java file.
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(java_filename));
+ io::Printer printer(output.get(), '$');
+ file_generator.Generate(&printer);
+
+ // Generate sibling files.
+ file_generator.GenerateSiblings(package_dir, context, &all_files);
+
+ // Generate output list if requested.
+ if (!output_list_file.empty()) {
+ // Generate output list. This is just a simple text file placed in a
+ // deterministic location which lists the .java files being generated.
+ scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
+ context->Open(output_list_file));
+ io::Printer srclist_printer(srclist_raw_output.get(), '$');
+ for (int i = 0; i < all_files.size(); i++) {
+ srclist_printer.Print("$filename$\n", "filename", all_files[i]);
+ }
+ }
+
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h
new file mode 100644
index 0000000..888b8d8
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Generates Java code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
+
+#include <string>
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// CodeGenerator implementation which generates Java code. If you create your
+// own protocol compiler binary and you want it to support Java output, you
+// can do so by registering an instance of this CodeGenerator with the
+// CommandLineInterface in your main() function.
+class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator {
+ public:
+ JavaGenerator();
+ ~JavaGenerator();
+
+ // implements CodeGenerator ----------------------------------------
+ bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc
new file mode 100644
index 0000000..1b6f165
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc
@@ -0,0 +1,478 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <limits>
+#include <vector>
+
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+const char kThickSeparator[] =
+ "// ===================================================================\n";
+const char kThinSeparator[] =
+ "// -------------------------------------------------------------------\n";
+
+namespace {
+
+const char* kDefaultPackage = "";
+
+const string& FieldName(const FieldDescriptor* field) {
+ // Groups are hacky: The name of the field is just the lower-cased name
+ // of the group type. In Java, though, we would like to retain the original
+ // capitalization of the type name.
+ if (GetType(field) == FieldDescriptor::TYPE_GROUP) {
+ return field->message_type()->name();
+ } else {
+ return field->name();
+ }
+}
+
+string UnderscoresToCamelCaseImpl(const string& input, bool cap_next_letter) {
+ string result;
+ // Note: I distrust ctype.h due to locales.
+ for (int i = 0; i < input.size(); i++) {
+ if ('a' <= input[i] && input[i] <= 'z') {
+ if (cap_next_letter) {
+ result += input[i] + ('A' - 'a');
+ } else {
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('A' <= input[i] && input[i] <= 'Z') {
+ if (i == 0 && !cap_next_letter) {
+ // Force first letter to lower-case unless explicitly told to
+ // capitalize it.
+ result += input[i] + ('a' - 'A');
+ } else {
+ // Capital letters after the first are left as-is.
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('0' <= input[i] && input[i] <= '9') {
+ result += input[i];
+ cap_next_letter = true;
+ } else {
+ cap_next_letter = true;
+ }
+ }
+ return result;
+}
+
+} // namespace
+
+string UnderscoresToCamelCase(const FieldDescriptor* field) {
+ return UnderscoresToCamelCaseImpl(FieldName(field), false);
+}
+
+string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
+ return UnderscoresToCamelCaseImpl(FieldName(field), true);
+}
+
+string UnderscoresToCamelCase(const MethodDescriptor* method) {
+ return UnderscoresToCamelCaseImpl(method->name(), false);
+}
+
+string StripProto(const string& filename) {
+ if (HasSuffixString(filename, ".protodevel")) {
+ return StripSuffixString(filename, ".protodevel");
+ } else {
+ return StripSuffixString(filename, ".proto");
+ }
+}
+
+string FileClassName(const FileDescriptor* file) {
+ if (file->options().has_java_outer_classname()) {
+ return file->options().java_outer_classname();
+ } else {
+ string basename;
+ string::size_type last_slash = file->name().find_last_of('/');
+ if (last_slash == string::npos) {
+ basename = file->name();
+ } else {
+ basename = file->name().substr(last_slash + 1);
+ }
+ return UnderscoresToCamelCaseImpl(StripProto(basename), true);
+ }
+}
+
+string FileJavaPackage(const FileDescriptor* file) {
+ string result;
+
+ if (file->options().has_java_package()) {
+ result = file->options().java_package();
+ } else {
+ result = kDefaultPackage;
+ if (!file->package().empty()) {
+ if (!result.empty()) result += '.';
+ result += file->package();
+ }
+ }
+
+
+ return result;
+}
+
+string JavaPackageToDir(string package_name) {
+ string package_dir =
+ StringReplace(package_name, ".", "/", true);
+ if (!package_dir.empty()) package_dir += "/";
+ return package_dir;
+}
+
+string ToJavaName(const string& full_name, const FileDescriptor* file) {
+ string result;
+ if (file->options().java_multiple_files()) {
+ result = FileJavaPackage(file);
+ } else {
+ result = ClassName(file);
+ }
+ if (!result.empty()) {
+ result += '.';
+ }
+ if (file->package().empty()) {
+ result += full_name;
+ } else {
+ // Strip the proto package from full_name since we've replaced it with
+ // the Java package.
+ result += full_name.substr(file->package().size() + 1);
+ }
+ return result;
+}
+
+string ClassName(const FileDescriptor* descriptor) {
+ string result = FileJavaPackage(descriptor);
+ if (!result.empty()) result += '.';
+ result += FileClassName(descriptor);
+ return result;
+}
+
+string FieldConstantName(const FieldDescriptor *field) {
+ string name = field->name() + "_FIELD_NUMBER";
+ UpperString(&name);
+ return name;
+}
+
+FieldDescriptor::Type GetType(const FieldDescriptor* field) {
+ return field->type();
+}
+
+JavaType GetJavaType(const FieldDescriptor* field) {
+ switch (GetType(field)) {
+ case FieldDescriptor::TYPE_INT32:
+ case FieldDescriptor::TYPE_UINT32:
+ case FieldDescriptor::TYPE_SINT32:
+ case FieldDescriptor::TYPE_FIXED32:
+ case FieldDescriptor::TYPE_SFIXED32:
+ return JAVATYPE_INT;
+
+ case FieldDescriptor::TYPE_INT64:
+ case FieldDescriptor::TYPE_UINT64:
+ case FieldDescriptor::TYPE_SINT64:
+ case FieldDescriptor::TYPE_FIXED64:
+ case FieldDescriptor::TYPE_SFIXED64:
+ return JAVATYPE_LONG;
+
+ case FieldDescriptor::TYPE_FLOAT:
+ return JAVATYPE_FLOAT;
+
+ case FieldDescriptor::TYPE_DOUBLE:
+ return JAVATYPE_DOUBLE;
+
+ case FieldDescriptor::TYPE_BOOL:
+ return JAVATYPE_BOOLEAN;
+
+ case FieldDescriptor::TYPE_STRING:
+ return JAVATYPE_STRING;
+
+ case FieldDescriptor::TYPE_BYTES:
+ return JAVATYPE_BYTES;
+
+ case FieldDescriptor::TYPE_ENUM:
+ return JAVATYPE_ENUM;
+
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE:
+ return JAVATYPE_MESSAGE;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return JAVATYPE_INT;
+}
+
+const char* BoxedPrimitiveTypeName(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT : return "java.lang.Integer";
+ case JAVATYPE_LONG : return "java.lang.Long";
+ case JAVATYPE_FLOAT : return "java.lang.Float";
+ case JAVATYPE_DOUBLE : return "java.lang.Double";
+ case JAVATYPE_BOOLEAN: return "java.lang.Boolean";
+ case JAVATYPE_STRING : return "java.lang.String";
+ case JAVATYPE_BYTES : return "com.google.protobuf.ByteString";
+ case JAVATYPE_ENUM : return NULL;
+ case JAVATYPE_MESSAGE: return NULL;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+bool AllAscii(const string& text) {
+ for (int i = 0; i < text.size(); i++) {
+ if ((text[i] & 0x80) != 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+string DefaultValue(const FieldDescriptor* field) {
+ // Switch on CppType since we need to know which default_value_* method
+ // of FieldDescriptor to call.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return SimpleItoa(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ // Need to print as a signed int since Java has no unsigned.
+ return SimpleItoa(static_cast<int32>(field->default_value_uint32()));
+ case FieldDescriptor::CPPTYPE_INT64:
+ return SimpleItoa(field->default_value_int64()) + "L";
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return SimpleItoa(static_cast<int64>(field->default_value_uint64())) +
+ "L";
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field->default_value_double();
+ if (value == numeric_limits<double>::infinity()) {
+ return "Double.POSITIVE_INFINITY";
+ } else if (value == -numeric_limits<double>::infinity()) {
+ return "Double.NEGATIVE_INFINITY";
+ } else if (value != value) {
+ return "Double.NaN";
+ } else {
+ return SimpleDtoa(value) + "D";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = field->default_value_float();
+ if (value == numeric_limits<float>::infinity()) {
+ return "Float.POSITIVE_INFINITY";
+ } else if (value == -numeric_limits<float>::infinity()) {
+ return "Float.NEGATIVE_INFINITY";
+ } else if (value != value) {
+ return "Float.NaN";
+ } else {
+ return SimpleFtoa(value) + "F";
+ }
+ }
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
+ if (field->has_default_value()) {
+ // See comments in Internal.java for gory details.
+ return strings::Substitute(
+ "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
+ CEscape(field->default_value_string()));
+ } else {
+ return "com.google.protobuf.ByteString.EMPTY";
+ }
+ } else {
+ if (AllAscii(field->default_value_string())) {
+ // All chars are ASCII. In this case CEscape() works fine.
+ return "\"" + CEscape(field->default_value_string()) + "\"";
+ } else {
+ // See comments in Internal.java for gory details.
+ return strings::Substitute(
+ "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
+ CEscape(field->default_value_string()));
+ }
+ }
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return ClassName(field->enum_type()) + "." +
+ field->default_value_enum()->name();
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return ClassName(field->message_type()) + ".getDefaultInstance()";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
+ // Switch on CppType since we need to know which default_value_* method
+ // of FieldDescriptor to call.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return field->default_value_int32() == 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return field->default_value_uint32() == 0;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return field->default_value_int64() == 0L;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return field->default_value_uint64() == 0L;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return field->default_value_double() == 0.0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return field->default_value_float() == 0.0;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() == false;
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return false;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+const char* bit_masks[] = {
+ "0x00000001",
+ "0x00000002",
+ "0x00000004",
+ "0x00000008",
+ "0x00000010",
+ "0x00000020",
+ "0x00000040",
+ "0x00000080",
+
+ "0x00000100",
+ "0x00000200",
+ "0x00000400",
+ "0x00000800",
+ "0x00001000",
+ "0x00002000",
+ "0x00004000",
+ "0x00008000",
+
+ "0x00010000",
+ "0x00020000",
+ "0x00040000",
+ "0x00080000",
+ "0x00100000",
+ "0x00200000",
+ "0x00400000",
+ "0x00800000",
+
+ "0x01000000",
+ "0x02000000",
+ "0x04000000",
+ "0x08000000",
+ "0x10000000",
+ "0x20000000",
+ "0x40000000",
+ "0x80000000",
+};
+
+string GetBitFieldName(int index) {
+ string varName = "bitField";
+ varName += SimpleItoa(index);
+ varName += "_";
+ return varName;
+}
+
+string GetBitFieldNameForBit(int bitIndex) {
+ return GetBitFieldName(bitIndex / 32);
+}
+
+string GenerateGetBit(int bitIndex) {
+ string varName = GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = "((" + varName + " & " + mask + ") == " + mask + ")";
+ return result;
+}
+
+string GenerateSetBit(int bitIndex) {
+ string varName = GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = varName + " |= " + mask;
+ return result;
+}
+
+string GenerateClearBit(int bitIndex) {
+ string varName = GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = varName + " = (" + varName + " & ~" + mask + ")";
+ return result;
+}
+
+string GenerateGetBitFromLocal(int bitIndex) {
+ string varName = "from_" + GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = "((" + varName + " & " + mask + ") == " + mask + ")";
+ return result;
+}
+
+string GenerateSetBitToLocal(int bitIndex) {
+ string varName = "to_" + GetBitFieldNameForBit(bitIndex);
+ int bitInVarIndex = bitIndex % 32;
+
+ string mask = bit_masks[bitInVarIndex];
+ string result = varName + " |= " + mask;
+ return result;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h
new file mode 100644
index 0000000..88efd45
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h
@@ -0,0 +1,214 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
+
+#include <string>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// Commonly-used separator comments. Thick is a line of '=', thin is a line
+// of '-'.
+extern const char kThickSeparator[];
+extern const char kThinSeparator[];
+
+// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes
+// "fooBarBaz" or "FooBarBaz", respectively.
+string UnderscoresToCamelCase(const FieldDescriptor* field);
+string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field);
+
+// Similar, but for method names. (Typically, this merely has the effect
+// of lower-casing the first letter of the name.)
+string UnderscoresToCamelCase(const MethodDescriptor* method);
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+string StripProto(const string& filename);
+
+// Gets the unqualified class name for the file. Each .proto file becomes a
+// single Java class, with all its contents nested in that class.
+string FileClassName(const FileDescriptor* file);
+
+// Returns the file's Java package name.
+string FileJavaPackage(const FileDescriptor* file);
+
+// Returns output directory for the given package name.
+string JavaPackageToDir(string package_name);
+
+// Converts the given fully-qualified name in the proto namespace to its
+// fully-qualified name in the Java namespace, given that it is in the given
+// file.
+string ToJavaName(const string& full_name, const FileDescriptor* file);
+
+// These return the fully-qualified class name corresponding to the given
+// descriptor.
+inline string ClassName(const Descriptor* descriptor) {
+ return ToJavaName(descriptor->full_name(), descriptor->file());
+}
+inline string ClassName(const EnumDescriptor* descriptor) {
+ return ToJavaName(descriptor->full_name(), descriptor->file());
+}
+inline string ClassName(const ServiceDescriptor* descriptor) {
+ return ToJavaName(descriptor->full_name(), descriptor->file());
+}
+inline string ExtensionIdentifierName(const FieldDescriptor* descriptor) {
+ return ToJavaName(descriptor->full_name(), descriptor->file());
+}
+string ClassName(const FileDescriptor* descriptor);
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(const FieldDescriptor *field);
+
+// Returns the type of the FieldDescriptor.
+// This does nothing interesting for the open source release, but is used for
+// hacks that improve compatability with version 1 protocol buffers at Google.
+FieldDescriptor::Type GetType(const FieldDescriptor* field);
+
+enum JavaType {
+ JAVATYPE_INT,
+ JAVATYPE_LONG,
+ JAVATYPE_FLOAT,
+ JAVATYPE_DOUBLE,
+ JAVATYPE_BOOLEAN,
+ JAVATYPE_STRING,
+ JAVATYPE_BYTES,
+ JAVATYPE_ENUM,
+ JAVATYPE_MESSAGE
+};
+
+JavaType GetJavaType(const FieldDescriptor* field);
+
+// Get the fully-qualified class name for a boxed primitive type, e.g.
+// "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message
+// types.
+const char* BoxedPrimitiveTypeName(JavaType type);
+
+string DefaultValue(const FieldDescriptor* field);
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
+
+// Does this message class keep track of unknown fields?
+inline bool HasUnknownFields(const Descriptor* descriptor) {
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME ||
+ descriptor->file()->options().retain_unknown_fields();
+}
+
+// Does this message class have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+inline bool HasGeneratedMethods(const Descriptor* descriptor) {
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::CODE_SIZE;
+}
+
+// Does this message have specialized equals() and hashCode() methods?
+inline bool HasEqualsAndHashCode(const Descriptor* descriptor) {
+ return descriptor->file()->options().java_generate_equals_and_hash();
+}
+
+// Does this message class have descriptor and reflection methods?
+inline bool HasDescriptorMethods(const Descriptor* descriptor) {
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+inline bool HasDescriptorMethods(const EnumDescriptor* descriptor) {
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+inline bool HasDescriptorMethods(const FileDescriptor* descriptor) {
+ return descriptor->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+
+inline bool HasNestedBuilders(const Descriptor* descriptor) {
+ // The proto-lite version doesn't support nested builders.
+ return descriptor->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor *file) {
+ return file->service_count() > 0 &&
+ file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
+ file->options().java_generic_services();
+}
+
+
+// Methods for shared bitfields.
+
+// Gets the name of the shared bitfield for the given index.
+string GetBitFieldName(int index);
+
+// Gets the name of the shared bitfield for the given bit index.
+// Effectively, GetBitFieldName(bitIndex / 32)
+string GetBitFieldNameForBit(int bitIndex);
+
+// Generates the java code for the expression that returns the boolean value
+// of the bit of the shared bitfields for the given bit index.
+// Example: "((bitField1_ & 0x04) == 0x04)"
+string GenerateGetBit(int bitIndex);
+
+// Generates the java code for the expression that sets the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ | 0x04)"
+string GenerateSetBit(int bitIndex);
+
+// Generates the java code for the expression that clears the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ & ~0x04)"
+string GenerateClearBit(int bitIndex);
+
+// Does the same as GenerateGetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "((from_bitField1_ & 0x04) == 0x04)"
+string GenerateGetBitFromLocal(int bitIndex);
+
+// Does the same as GenerateSetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
+string GenerateSetBitToLocal(int bitIndex);
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc
new file mode 100644
index 0000000..4c087db
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc
@@ -0,0 +1,1287 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/compiler/java/java_message.h>
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
+ // Print the field's proto-syntax definition as a comment. We don't want to
+ // print group bodies so we cut off after the first line.
+ string def = field->DebugString();
+ printer->Print("// $def$\n",
+ "def", def.substr(0, def.find_first_of('\n')));
+}
+
+struct FieldOrderingByNumber {
+ inline bool operator()(const FieldDescriptor* a,
+ const FieldDescriptor* b) const {
+ return a->number() < b->number();
+ }
+};
+
+struct ExtensionRangeOrdering {
+ bool operator()(const Descriptor::ExtensionRange* a,
+ const Descriptor::ExtensionRange* b) const {
+ return a->start < b->start;
+ }
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
+ const FieldDescriptor** fields =
+ new const FieldDescriptor*[descriptor->field_count()];
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ fields[i] = descriptor->field(i);
+ }
+ sort(fields, fields + descriptor->field_count(),
+ FieldOrderingByNumber());
+ return fields;
+}
+
+// Get an identifier that uniquely identifies this type within the file.
+// This is used to declare static variables related to this type at the
+// outermost file scope.
+string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
+ return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
+}
+
+// Returns true if the message type has any required fields. If it doesn't,
+// we can optimize out calls to its isInitialized() method.
+//
+// already_seen is used to avoid checking the same type multiple times
+// (and also to protect against recursion).
+static bool HasRequiredFields(
+ const Descriptor* type,
+ hash_set<const Descriptor*>* already_seen) {
+ if (already_seen->count(type) > 0) {
+ // The type is already in cache. This means that either:
+ // a. The type has no required fields.
+ // b. We are in the midst of checking if the type has required fields,
+ // somewhere up the stack. In this case, we know that if the type
+ // has any required fields, they'll be found when we return to it,
+ // and the whole call to HasRequiredFields() will return true.
+ // Therefore, we don't have to check if this type has required fields
+ // here.
+ return false;
+ }
+ already_seen->insert(type);
+
+ // If the type has extensions, an extension with message type could contain
+ // required fields, so we have to be conservative and assume such an
+ // extension exists.
+ if (type->extension_range_count() > 0) return true;
+
+ for (int i = 0; i < type->field_count(); i++) {
+ const FieldDescriptor* field = type->field(i);
+ if (field->is_required()) {
+ return true;
+ }
+ if (GetJavaType(field) == JAVATYPE_MESSAGE) {
+ if (HasRequiredFields(field->message_type(), already_seen)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool HasRequiredFields(const Descriptor* type) {
+ hash_set<const Descriptor*> already_seen;
+ return HasRequiredFields(type, &already_seen);
+}
+
+} // namespace
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor)
+ : descriptor_(descriptor),
+ field_generators_(descriptor) {
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_)) {
+ // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
+ // used in the construction of descriptors, we have a tricky bootstrapping
+ // problem. To help control static initialization order, we make sure all
+ // descriptors and other static data that depends on them are members of
+ // the outermost class in the file. This way, they will be initialized in
+ // a deterministic order.
+
+ map<string, string> vars;
+ vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+ vars["index"] = SimpleItoa(descriptor_->index());
+ vars["classname"] = ClassName(descriptor_);
+ if (descriptor_->containing_type() != NULL) {
+ vars["parent"] = UniqueFileScopeIdentifier(
+ descriptor_->containing_type());
+ }
+ if (descriptor_->file()->options().java_multiple_files()) {
+ // We can only make these package-private since the classes that use them
+ // are in separate files.
+ vars["private"] = "";
+ } else {
+ vars["private"] = "private ";
+ }
+
+ // The descriptor for this type.
+ printer->Print(vars,
+ "$private$static com.google.protobuf.Descriptors.Descriptor\n"
+ " internal_$identifier$_descriptor;\n");
+
+ // And the FieldAccessorTable.
+ printer->Print(vars,
+ "$private$static\n"
+ " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ " internal_$identifier$_fieldAccessorTable;\n");
+ }
+
+ // Generate static members for all nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ MessageGenerator(descriptor_->nested_type(i))
+ .GenerateStaticVariables(printer);
+ }
+}
+
+void MessageGenerator::GenerateStaticVariableInitializers(
+ io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_)) {
+ map<string, string> vars;
+ vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+ vars["index"] = SimpleItoa(descriptor_->index());
+ vars["classname"] = ClassName(descriptor_);
+ if (descriptor_->containing_type() != NULL) {
+ vars["parent"] = UniqueFileScopeIdentifier(
+ descriptor_->containing_type());
+ }
+
+ // The descriptor for this type.
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(vars,
+ "internal_$identifier$_descriptor =\n"
+ " getDescriptor().getMessageTypes().get($index$);\n");
+ } else {
+ printer->Print(vars,
+ "internal_$identifier$_descriptor =\n"
+ " internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
+ }
+
+ // And the FieldAccessorTable.
+ printer->Print(vars,
+ "internal_$identifier$_fieldAccessorTable = new\n"
+ " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
+ " internal_$identifier$_descriptor,\n"
+ " new java.lang.String[] { ");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print(
+ "\"$field_name$\", ",
+ "field_name",
+ UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
+ }
+ printer->Print("},\n"
+ " $classname$.class,\n"
+ " $classname$.Builder.class);\n",
+ "classname", ClassName(descriptor_));
+ }
+
+ // Generate static member initializers for all nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ // TODO(kenton): Reuse MessageGenerator objects?
+ MessageGenerator(descriptor_->nested_type(i))
+ .GenerateStaticVariableInitializers(printer);
+ }
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateInterface(io::Printer* printer) {
+
+ if (descriptor_->extension_range_count() > 0) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public interface $classname$OrBuilder extends\n"
+ " com.google.protobuf.GeneratedMessage.\n"
+ " ExtendableMessageOrBuilder<$classname$> {\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public interface $classname$OrBuilder extends \n"
+ " com.google.protobuf.GeneratedMessageLite.\n"
+ " ExtendableMessageOrBuilder<$classname$> {\n",
+ "classname", descriptor_->name());
+ }
+ } else {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public interface $classname$OrBuilder\n"
+ " extends com.google.protobuf.MessageOrBuilder {\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public interface $classname$OrBuilder\n"
+ " extends com.google.protobuf.MessageLiteOrBuilder {\n",
+ "classname", descriptor_->name());
+ }
+ }
+
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ PrintFieldComment(printer, descriptor_->field(i));
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInterfaceMembers(printer);
+ }
+ printer->Outdent();
+
+ printer->Print("}\n");
+}
+
+// ===================================================================
+
+void MessageGenerator::Generate(io::Printer* printer) {
+ bool is_own_file =
+ descriptor_->containing_type() == NULL &&
+ descriptor_->file()->options().java_multiple_files();
+
+ if (descriptor_->extension_range_count() > 0) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public $static$ final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
+ " $classname$> implements $classname$OrBuilder {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public $static$ final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
+ " $classname$> implements $classname$OrBuilder {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ }
+ } else {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public $static$ final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessage\n"
+ " implements $classname$OrBuilder {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public $static$ final class $classname$ extends\n"
+ " com.google.protobuf.GeneratedMessageLite\n"
+ " implements $classname$OrBuilder {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ }
+ }
+ printer->Indent();
+ printer->Print(
+ "// Use $classname$.newBuilder() to construct.\n"
+ "private $classname$(Builder builder) {\n"
+ " super(builder);\n"
+ "}\n"
+ // Used when constructing the default instance, which cannot be initialized
+ // immediately because it may cyclically refer to other default instances.
+ "private $classname$(boolean noInit) {}\n"
+ "\n"
+ "private static final $classname$ defaultInstance;\n"
+ "public static $classname$ getDefaultInstance() {\n"
+ " return defaultInstance;\n"
+ "}\n"
+ "\n"
+ "public $classname$ getDefaultInstanceForType() {\n"
+ " return defaultInstance;\n"
+ "}\n"
+ "\n",
+ "classname", descriptor_->name());
+
+ GenerateDescriptorMethods(printer);
+
+ // Nested types
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ EnumGenerator(descriptor_->enum_type(i)).Generate(printer);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ MessageGenerator messageGenerator(descriptor_->nested_type(i));
+ messageGenerator.GenerateInterface(printer);
+ messageGenerator.Generate(printer);
+ }
+
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits += field_generators_.get(descriptor_->field(i))
+ .GetNumBitsForMessage();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+
+ // Fields
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ PrintFieldComment(printer, descriptor_->field(i));
+ printer->Print("public static final int $constant_name$ = $number$;\n",
+ "constant_name", FieldConstantName(descriptor_->field(i)),
+ "number", SimpleItoa(descriptor_->field(i)->number()));
+ field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
+ printer->Print("\n");
+ }
+
+ // Called by the constructor, except in the case of the default instance,
+ // in which case this is called by static init code later on.
+ printer->Print("private void initFields() {\n");
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateInitializationCode(printer);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+
+ if (HasGeneratedMethods(descriptor_)) {
+ GenerateIsInitialized(printer, MEMOIZE);
+ GenerateMessageSerializationMethods(printer);
+ }
+
+ if (HasEqualsAndHashCode(descriptor_)) {
+ GenerateEqualsAndHashCode(printer);
+ }
+
+ GenerateParseFromMethods(printer);
+ GenerateBuilder(printer);
+
+ // Carefully initialize the default instance in such a way that it doesn't
+ // conflict with other initialization.
+ printer->Print(
+ "\n"
+ "static {\n"
+ " defaultInstance = new $classname$(true);\n"
+ " defaultInstance.initFields();\n"
+ "}\n"
+ "\n"
+ "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "classname", descriptor_->name(),
+ "full_name", descriptor_->full_name());
+
+ // Extensions must be declared after the defaultInstance is initialized
+ // because the defaultInstance is used by the extension to lazily retrieve
+ // the outer class's FileDescriptor.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ExtensionGenerator(descriptor_->extension(i)).Generate(printer);
+ }
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+
+// ===================================================================
+
+void MessageGenerator::
+GenerateMessageSerializationMethods(io::Printer* printer) {
+ scoped_array<const FieldDescriptor*> sorted_fields(
+ SortFieldsByNumber(descriptor_));
+
+ vector<const Descriptor::ExtensionRange*> sorted_extensions;
+ for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+ sorted_extensions.push_back(descriptor_->extension_range(i));
+ }
+ sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeOrdering());
+
+ printer->Print(
+ "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
+ " throws java.io.IOException {\n");
+ printer->Indent();
+ // writeTo(CodedOutputStream output) might be invoked without
+ // getSerializedSize() ever being called, but we need the memoized
+ // sizes in case this message has packed fields. Rather than emit checks for
+ // each packed field, just call getSerializedSize() up front for all messages.
+ // In most cases, getSerializedSize() will have already been called anyway by
+ // one of the wrapper writeTo() methods, making this call cheap.
+ printer->Print(
+ "getSerializedSize();\n");
+
+ if (descriptor_->extension_range_count() > 0) {
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "com.google.protobuf.GeneratedMessage$lite$\n"
+ " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
+ " newMessageSetExtensionWriter();\n",
+ "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
+ "classname", ClassName(descriptor_));
+ } else {
+ printer->Print(
+ "com.google.protobuf.GeneratedMessage$lite$\n"
+ " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
+ " newExtensionWriter();\n",
+ "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
+ "classname", ClassName(descriptor_));
+ }
+ }
+
+ // Merge the fields and the extension ranges, both sorted by field number.
+ for (int i = 0, j = 0;
+ i < descriptor_->field_count() || j < sorted_extensions.size();
+ ) {
+ if (i == descriptor_->field_count()) {
+ GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+ } else if (j == sorted_extensions.size()) {
+ GenerateSerializeOneField(printer, sorted_fields[i++]);
+ } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
+ GenerateSerializeOneField(printer, sorted_fields[i++]);
+ } else {
+ GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
+ }
+ }
+
+ if (HasUnknownFields(descriptor_)) {
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "getUnknownFields().writeAsMessageSetTo(output);\n");
+ } else {
+ printer->Print(
+ "getUnknownFields().writeTo(output);\n");
+ }
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n"
+ "private int memoizedSerializedSize = -1;\n"
+ "public int getSerializedSize() {\n"
+ " int size = memoizedSerializedSize;\n"
+ " if (size != -1) return size;\n"
+ "\n"
+ " size = 0;\n");
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "size += extensionsSerializedSizeAsMessageSet();\n");
+ } else {
+ printer->Print(
+ "size += extensionsSerializedSize();\n");
+ }
+ }
+
+ if (HasUnknownFields(descriptor_)) {
+ if (descriptor_->options().message_set_wire_format()) {
+ printer->Print(
+ "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
+ } else {
+ printer->Print(
+ "size += getUnknownFields().getSerializedSize();\n");
+ }
+ }
+
+ printer->Outdent();
+ printer->Print(
+ " memoizedSerializedSize = size;\n"
+ " return size;\n"
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "private static final long serialVersionUID = 0L;\n"
+ "@java.lang.Override\n"
+ "protected java.lang.Object writeReplace()\n"
+ " throws java.io.ObjectStreamException {\n"
+ " return super.writeReplace();\n"
+ "}\n"
+ "\n");
+}
+
+void MessageGenerator::
+GenerateParseFromMethods(io::Printer* printer) {
+ // Note: These are separate from GenerateMessageSerializationMethods()
+ // because they need to be generated even for messages that are optimized
+ // for code size.
+ printer->Print(
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.ByteString data)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return newBuilder().mergeFrom(data).buildParsed();\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.ByteString data,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return newBuilder().mergeFrom(data, extensionRegistry)\n"
+ " .buildParsed();\n"
+ "}\n"
+ "public static $classname$ parseFrom(byte[] data)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return newBuilder().mergeFrom(data).buildParsed();\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " byte[] data,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " return newBuilder().mergeFrom(data, extensionRegistry)\n"
+ " .buildParsed();\n"
+ "}\n"
+ "public static $classname$ parseFrom(java.io.InputStream input)\n"
+ " throws java.io.IOException {\n"
+ " return newBuilder().mergeFrom(input).buildParsed();\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " java.io.InputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " return newBuilder().mergeFrom(input, extensionRegistry)\n"
+ " .buildParsed();\n"
+ "}\n"
+ "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
+ " throws java.io.IOException {\n"
+ " Builder builder = newBuilder();\n"
+ " if (builder.mergeDelimitedFrom(input)) {\n"
+ " return builder.buildParsed();\n"
+ " } else {\n"
+ " return null;\n"
+ " }\n"
+ "}\n"
+ "public static $classname$ parseDelimitedFrom(\n"
+ " java.io.InputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " Builder builder = newBuilder();\n"
+ " if (builder.mergeDelimitedFrom(input, extensionRegistry)) {\n"
+ " return builder.buildParsed();\n"
+ " } else {\n"
+ " return null;\n"
+ " }\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.CodedInputStream input)\n"
+ " throws java.io.IOException {\n"
+ " return newBuilder().mergeFrom(input).buildParsed();\n"
+ "}\n"
+ "public static $classname$ parseFrom(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n"
+ " return newBuilder().mergeFrom(input, extensionRegistry)\n"
+ " .buildParsed();\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+}
+
+void MessageGenerator::GenerateSerializeOneField(
+ io::Printer* printer, const FieldDescriptor* field) {
+ field_generators_.get(field).GenerateSerializationCode(printer);
+}
+
+void MessageGenerator::GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range) {
+ printer->Print(
+ "extensionWriter.writeUntil($end$, output);\n",
+ "end", SimpleItoa(range->end));
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateBuilder(io::Printer* printer) {
+ printer->Print(
+ "public static Builder newBuilder() { return Builder.create(); }\n"
+ "public Builder newBuilderForType() { return newBuilder(); }\n"
+ "public static Builder newBuilder($classname$ prototype) {\n"
+ " return newBuilder().mergeFrom(prototype);\n"
+ "}\n"
+ "public Builder toBuilder() { return newBuilder(this); }\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+
+ if (HasNestedBuilders(descriptor_)) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "protected Builder newBuilderForType(\n"
+ " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+ " Builder builder = new Builder(parent);\n"
+ " return builder;\n"
+ "}\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
+ " $classname$, Builder> implements $classname$OrBuilder {\n",
+ "classname", ClassName(descriptor_));
+ } else {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n"
+ " $classname$, Builder> implements $classname$OrBuilder {\n",
+ "classname", ClassName(descriptor_));
+ }
+ } else {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessage.Builder<Builder>\n"
+ " implements $classname$OrBuilder {\n",
+ "classname", ClassName(descriptor_));
+ } else {
+ printer->Print(
+ "public static final class Builder extends\n"
+ " com.google.protobuf.GeneratedMessageLite.Builder<\n"
+ " $classname$, Builder>\n"
+ " implements $classname$OrBuilder {\n",
+ "classname", ClassName(descriptor_));
+ }
+ }
+ printer->Indent();
+
+ GenerateDescriptorMethods(printer);
+ GenerateCommonBuilderMethods(printer);
+
+ if (HasGeneratedMethods(descriptor_)) {
+ GenerateIsInitialized(printer, DONT_MEMOIZE);
+ GenerateBuilderParsingMethods(printer);
+ }
+
+ // Integers for bit fields.
+ int totalBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ totalBits += field_generators_.get(descriptor_->field(i))
+ .GetNumBitsForBuilder();
+ }
+ int totalInts = (totalBits + 31) / 32;
+ for (int i = 0; i < totalInts; i++) {
+ printer->Print("private int $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ printer->Print("\n");
+ PrintFieldComment(printer, descriptor_->field(i));
+ field_generators_.get(descriptor_->field(i))
+ .GenerateBuilderMembers(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::GenerateDescriptorMethods(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public static final com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptor() {\n"
+ " return $fileclass$.internal_$identifier$_descriptor;\n"
+ "}\n"
+ "\n"
+ "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ " internalGetFieldAccessorTable() {\n"
+ " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
+ "}\n"
+ "\n",
+ "fileclass", ClassName(descriptor_->file()),
+ "identifier", UniqueFileScopeIdentifier(descriptor_));
+ }
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
+ printer->Print(
+ "// Construct using $classname$.newBuilder()\n"
+ "private Builder() {\n"
+ " maybeForceBuilderInitialization();\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "private Builder(BuilderParent parent) {\n"
+ " super(parent);\n"
+ " maybeForceBuilderInitialization();\n"
+ "}\n",
+ "classname", ClassName(descriptor_));
+ }
+
+
+ if (HasNestedBuilders(descriptor_)) {
+ printer->Print(
+ "private void maybeForceBuilderInitialization() {\n"
+ " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n");
+
+ printer->Indent();
+ printer->Indent();
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateFieldBuilderInitializationCode(printer);
+ }
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n");
+ } else {
+ printer->Print(
+ "private void maybeForceBuilderInitialization() {\n"
+ "}\n");
+ }
+
+ printer->Print(
+ "private static Builder create() {\n"
+ " return new Builder();\n"
+ "}\n"
+ "\n"
+ "public Builder clear() {\n"
+ " super.clear();\n",
+ "classname", ClassName(descriptor_));
+
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateBuilderClearCode(printer);
+ }
+
+ printer->Outdent();
+
+ printer->Print(
+ " return this;\n"
+ "}\n"
+ "\n"
+ "public Builder clone() {\n"
+ " return create().mergeFrom(buildPartial());\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public com.google.protobuf.Descriptors.Descriptor\n"
+ " getDescriptorForType() {\n"
+ " return $classname$.getDescriptor();\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+ }
+ printer->Print(
+ "public $classname$ getDefaultInstanceForType() {\n"
+ " return $classname$.getDefaultInstance();\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "public $classname$ build() {\n"
+ " $classname$ result = buildPartial();\n"
+ " if (!result.isInitialized()) {\n"
+ " throw newUninitializedMessageException(result);\n"
+ " }\n"
+ " return result;\n"
+ "}\n"
+ "\n"
+ "private $classname$ buildParsed()\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " $classname$ result = buildPartial();\n"
+ " if (!result.isInitialized()) {\n"
+ " throw newUninitializedMessageException(\n"
+ " result).asInvalidProtocolBufferException();\n"
+ " }\n"
+ " return result;\n"
+ "}\n"
+ "\n"
+ "public $classname$ buildPartial() {\n"
+ " $classname$ result = new $classname$(this);\n",
+ "classname", ClassName(descriptor_));
+
+ printer->Indent();
+
+ // Local vars for from and to bit fields to avoid accessing the builder and
+ // message over and over for these fields. Seems to provide a slight
+ // perforamance improvement in micro benchmark and this is also what proto1
+ // code does.
+ int totalBuilderBits = 0;
+ int totalMessageBits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldGenerator& field = field_generators_.get(descriptor_->field(i));
+ totalBuilderBits += field.GetNumBitsForBuilder();
+ totalMessageBits += field.GetNumBitsForMessage();
+ }
+ int totalBuilderInts = (totalBuilderBits + 31) / 32;
+ int totalMessageInts = (totalMessageBits + 31) / 32;
+ for (int i = 0; i < totalBuilderInts; i++) {
+ printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("int to_$bit_field_name$ = 0;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+
+ // Output generation code for each field.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
+ }
+
+ // Copy the bit field results to the generated message
+ for (int i = 0; i < totalMessageInts; i++) {
+ printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
+ "bit_field_name", GetBitFieldName(i));
+ }
+
+ printer->Outdent();
+
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ " onBuilt();\n");
+ }
+
+ printer->Print(
+ " return result;\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+
+ // -----------------------------------------------------------------
+
+ if (HasGeneratedMethods(descriptor_)) {
+ // MergeFrom(Message other) requires the ability to distinguish the other
+ // messages type by its descriptor.
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
+ " if (other instanceof $classname$) {\n"
+ " return mergeFrom(($classname$)other);\n"
+ " } else {\n"
+ " super.mergeFrom(other);\n"
+ " return this;\n"
+ " }\n"
+ "}\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+ }
+
+ printer->Print(
+ "public Builder mergeFrom($classname$ other) {\n"
+ // Optimization: If other is the default instance, we know none of its
+ // fields are set so we can skip the merge.
+ " if (other == $classname$.getDefaultInstance()) return this;\n",
+ "classname", ClassName(descriptor_));
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer);
+ }
+
+ printer->Outdent();
+
+ // if message type has extensions
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ " this.mergeExtensionFields(other);\n");
+ }
+
+ if (HasUnknownFields(descriptor_)) {
+ printer->Print(
+ " this.mergeUnknownFields(other.getUnknownFields());\n");
+ }
+
+ printer->Print(
+ " return this;\n"
+ "}\n"
+ "\n");
+ }
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
+ scoped_array<const FieldDescriptor*> sorted_fields(
+ SortFieldsByNumber(descriptor_));
+
+ printer->Print(
+ "public Builder mergeFrom(\n"
+ " com.google.protobuf.CodedInputStream input,\n"
+ " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+ " throws java.io.IOException {\n");
+ printer->Indent();
+
+ if (HasUnknownFields(descriptor_)) {
+ printer->Print(
+ "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
+ " com.google.protobuf.UnknownFieldSet.newBuilder(\n"
+ " this.getUnknownFields());\n");
+ }
+
+ printer->Print(
+ "while (true) {\n");
+ printer->Indent();
+
+ printer->Print(
+ "int tag = input.readTag();\n"
+ "switch (tag) {\n");
+ printer->Indent();
+
+ if (HasUnknownFields(descriptor_)) {
+ printer->Print(
+ "case 0:\n" // zero signals EOF / limit reached
+ " this.setUnknownFields(unknownFields.build());\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "default: {\n"
+ " if (!parseUnknownField(input, unknownFields,\n"
+ " extensionRegistry, tag)) {\n"
+ " this.setUnknownFields(unknownFields.build());\n"
+ " $on_changed$\n"
+ " return this;\n" // it's an endgroup tag
+ " }\n"
+ " break;\n"
+ "}\n",
+ "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : "");
+ } else {
+ printer->Print(
+ "case 0:\n" // zero signals EOF / limit reached
+ " $on_changed$\n"
+ " return this;\n"
+ "default: {\n"
+ " if (!parseUnknownField(input, extensionRegistry, tag)) {\n"
+ " $on_changed$\n"
+ " return this;\n" // it's an endgroup tag
+ " }\n"
+ " break;\n"
+ "}\n",
+ "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : "");
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = sorted_fields[i];
+ uint32 tag = WireFormatLite::MakeTag(field->number(),
+ WireFormat::WireTypeForFieldType(field->type()));
+
+ printer->Print(
+ "case $tag$: {\n",
+ "tag", SimpleItoa(tag));
+ printer->Indent();
+
+ field_generators_.get(field).GenerateParsingCode(printer);
+
+ printer->Outdent();
+ printer->Print(
+ " break;\n"
+ "}\n");
+
+ if (field->is_packable()) {
+ // To make packed = true wire compatible, we generate parsing code from a
+ // packed version of this field regardless of field->options().packed().
+ uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ printer->Print(
+ "case $tag$: {\n",
+ "tag", SimpleItoa(packed_tag));
+ printer->Indent();
+
+ field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
+
+ printer->Outdent();
+ printer->Print(
+ " break;\n"
+ "}\n");
+ }
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n" // switch (tag)
+ " }\n" // while (true)
+ "}\n"
+
+ "\n");
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateIsInitialized(
+ io::Printer* printer, UseMemoization useMemoization) {
+ bool memoization = useMemoization == MEMOIZE;
+ if (memoization) {
+ // Memoizes whether the protocol buffer is fully initialized (has all
+ // required fields). -1 means not yet computed. 0 means false and 1 means
+ // true.
+ printer->Print(
+ "private byte memoizedIsInitialized = -1;\n");
+ }
+ printer->Print(
+ "public final boolean isInitialized() {\n");
+ printer->Indent();
+
+ if (memoization) {
+ printer->Print(
+ "byte isInitialized = memoizedIsInitialized;\n"
+ "if (isInitialized != -1) return isInitialized == 1;\n"
+ "\n");
+ }
+
+ // Check that all required fields in this message are set.
+ // TODO(kenton): We can optimize this when we switch to putting all the
+ // "has" fields into a single bitfield.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (field->is_required()) {
+ printer->Print(
+ "if (!has$name$()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
+ "name", UnderscoresToCapitalizedCamelCase(field),
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ }
+ }
+
+ // Now check that all embedded messages are initialized.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (GetJavaType(field) == JAVATYPE_MESSAGE &&
+ HasRequiredFields(field->message_type())) {
+ switch (field->label()) {
+ case FieldDescriptor::LABEL_REQUIRED:
+ printer->Print(
+ "if (!get$name$().isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
+ "type", ClassName(field->message_type()),
+ "name", UnderscoresToCapitalizedCamelCase(field),
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ break;
+ case FieldDescriptor::LABEL_OPTIONAL:
+ printer->Print(
+ "if (has$name$()) {\n"
+ " if (!get$name$().isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "type", ClassName(field->message_type()),
+ "name", UnderscoresToCapitalizedCamelCase(field),
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ break;
+ case FieldDescriptor::LABEL_REPEATED:
+ printer->Print(
+ "for (int i = 0; i < get$name$Count(); i++) {\n"
+ " if (!get$name$(i).isInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ " }\n"
+ "}\n",
+ "type", ClassName(field->message_type()),
+ "name", UnderscoresToCapitalizedCamelCase(field),
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ break;
+ }
+ }
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "if (!extensionsAreInitialized()) {\n"
+ " $memoize$\n"
+ " return false;\n"
+ "}\n",
+ "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+ }
+
+ printer->Outdent();
+
+ if (memoization) {
+ printer->Print(
+ " memoizedIsInitialized = 1;\n");
+ }
+
+ printer->Print(
+ " return true;\n"
+ "}\n"
+ "\n");
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateEqualsAndHashCode(io::Printer* printer) {
+ printer->Print(
+ "@java.lang.Override\n"
+ "public boolean equals(final java.lang.Object obj) {\n");
+ printer->Indent();
+ printer->Print(
+ "if (obj == this) {\n"
+ " return true;\n"
+ "}\n"
+ "if (!(obj instanceof $classname$)) {\n"
+ " return super.equals(obj);\n"
+ "}\n"
+ "$classname$ other = ($classname$) obj;\n"
+ "\n",
+ "classname", ClassName(descriptor_));
+
+ printer->Print("boolean result = true;\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (!field->is_repeated()) {
+ printer->Print(
+ "result = result && (has$name$() == other.has$name$());\n"
+ "if (has$name$()) {\n",
+ "name", UnderscoresToCapitalizedCamelCase(field));
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ if (!field->is_repeated()) {
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ }
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "result = result &&\n"
+ " getUnknownFields().equals(other.getUnknownFields());\n");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "result = result &&\n"
+ " getExtensionFields().equals(other.getExtensionFields());\n");
+ }
+ }
+ printer->Print(
+ "return result;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "@java.lang.Override\n"
+ "public int hashCode() {\n");
+ printer->Indent();
+ printer->Print(
+ "int hash = 41;\n"
+ "hash = (19 * hash) + getDescriptorForType().hashCode();\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (!field->is_repeated()) {
+ printer->Print(
+ "if (has$name$()) {\n",
+ "name", UnderscoresToCapitalizedCamelCase(field));
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateHashCode(printer);
+ if (!field->is_repeated()) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+ if (HasDescriptorMethods(descriptor_)) {
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "hash = hashFields(hash, getExtensionFields());\n");
+ }
+ }
+ printer->Print(
+ "hash = (29 * hash) + getUnknownFields().hashCode();\n"
+ "return hash;\n");
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+}
+
+// ===================================================================
+
+void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ ExtensionGenerator(descriptor_->extension(i))
+ .GenerateRegistrationCode(printer);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ MessageGenerator(descriptor_->nested_type(i))
+ .GenerateExtensionRegistrationCode(printer);
+ }
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h
new file mode 100644
index 0000000..4c6fbbe
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h
@@ -0,0 +1,109 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class MessageGenerator {
+ public:
+ explicit MessageGenerator(const Descriptor* descriptor);
+ ~MessageGenerator();
+
+ // All static variables have to be declared at the top-level of the file
+ // so that we can control initialization order, which is important for
+ // DescriptorProto bootstrapping to work.
+ void GenerateStaticVariables(io::Printer* printer);
+
+ // Output code which initializes the static variables generated by
+ // GenerateStaticVariables().
+ void GenerateStaticVariableInitializers(io::Printer* printer);
+
+ // Generate the class itself.
+ void Generate(io::Printer* printer);
+
+ // Generates the base interface that both the class and its builder implement
+ void GenerateInterface(io::Printer* printer);
+
+ // Generate code to register all contained extensions with an
+ // ExtensionRegistry.
+ void GenerateExtensionRegistrationCode(io::Printer* printer);
+
+ private:
+ enum UseMemoization {
+ MEMOIZE,
+ DONT_MEMOIZE
+ };
+
+ void GenerateMessageSerializationMethods(io::Printer* printer);
+ void GenerateParseFromMethods(io::Printer* printer);
+ void GenerateSerializeOneField(io::Printer* printer,
+ const FieldDescriptor* field);
+ void GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range);
+
+ void GenerateBuilder(io::Printer* printer);
+ void GenerateCommonBuilderMethods(io::Printer* printer);
+ void GenerateDescriptorMethods(io::Printer* printer);
+ void GenerateBuilderParsingMethods(io::Printer* printer);
+ void GenerateIsInitialized(io::Printer* printer,
+ UseMemoization useMemoization);
+ void GenerateEqualsAndHashCode(io::Printer* printer);
+
+ const Descriptor* descriptor_;
+ FieldGeneratorMap field_generators_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc
new file mode 100644
index 0000000..251945a
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc
@@ -0,0 +1,884 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_message_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
+// repeat code between this and the other field types.
+void SetMessageVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ map<string, string>* variables) {
+ (*variables)["name"] =
+ UnderscoresToCamelCase(descriptor);
+ (*variables)["capitalized_name"] =
+ UnderscoresToCapitalizedCamelCase(descriptor);
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["type"] = ClassName(descriptor->message_type());
+ (*variables)["group_or_message"] =
+ (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ?
+ "Group" : "Message";
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
+ (*variables)["on_changed"] =
+ HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex);
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::
+MessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+int MessageFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int MessageFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void MessageFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ // TODO(jonp): In the future, consider having a method specific to the
+ // interface so that builders can choose dynamically to either return a
+ // message or a nested builder, so that asking for the interface doesn't
+ // cause a message to ever be built.
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n"
+ "$deprecation$$type$ get$capitalized_name$();\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
+ }
+}
+
+void MessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private $type$ $name$_;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " return $name$_;\n"
+ "}\n");
+ }
+}
+
+void MessageFieldGenerator::PrintNestedBuilderCondition(
+ io::Printer* printer,
+ const char* regular_case,
+ const char* nested_builder_case) const {
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+ printer->Indent();
+ printer->Print(variables_, regular_case);
+ printer->Outdent();
+ printer->Print("} else {\n");
+ printer->Indent();
+ printer->Print(variables_, nested_builder_case);
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ printer->Print(variables_, regular_case);
+ }
+}
+
+void MessageFieldGenerator::PrintNestedBuilderFunction(
+ io::Printer* printer,
+ const char* method_prototype,
+ const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const {
+ printer->Print(variables_, method_prototype);
+ printer->Print(" {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+ if (trailing_code != NULL) {
+ printer->Print(variables_, trailing_code);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
+ printer->Print(variables_,
+ // Used when the builder is null.
+ "private $type$ $name$_ = $type$.getDefaultInstance();\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // field of type "Field" called "Field".
+
+ // boolean hasField()
+ printer->Print(variables_,
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+
+ // Field getField()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public $type$ get$capitalized_name$()",
+
+ "return $name$_;\n",
+
+ "return $name$Builder_.getMessage();\n",
+
+ NULL);
+
+ // Field.Builder setField(Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "$name$_ = value;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(value);\n",
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder setField(Field.Builder builderForValue)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "$name$_ = builderForValue.build();\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(builderForValue.build());\n",
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder mergeField(Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+ "if ($get_has_field_bit_builder$ &&\n"
+ " $name$_ != $type$.getDefaultInstance()) {\n"
+ " $name$_ =\n"
+ " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+ "} else {\n"
+ " $name$_ = value;\n"
+ "}\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.mergeFrom(value);\n",
+
+ "$set_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ // Field.Builder clearField()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "$name$_ = $type$.getDefaultInstance();\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.clear();\n",
+
+ "$clear_has_field_bit_builder$;\n"
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
+ " $set_has_field_bit_builder$;\n"
+ " $on_changed$\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder();\n"
+ "}\n"
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilder();\n"
+ " } else {\n"
+ " return $name$_;\n"
+ " }\n"
+ "}\n"
+ "private com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> \n"
+ " get$capitalized_name$FieldBuilder() {\n"
+ " if ($name$Builder_ == null) {\n"
+ " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " $name$_,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
+}
+
+void MessageFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "get$capitalized_name$FieldBuilder();\n");
+}
+
+
+void MessageFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n");
+}
+
+void MessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ PrintNestedBuilderCondition(printer,
+ "$name$_ = $type$.getDefaultInstance();\n",
+
+ "$name$Builder_.clear();\n");
+ printer->Print(variables_, "$clear_has_field_bit_builder$;\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " merge$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n");
+
+ PrintNestedBuilderCondition(printer,
+ "result.$name$_ = $name$_;\n",
+
+ "result.$name$_ = $name$Builder_.build();\n");
+}
+
+void MessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$type$.Builder subBuilder = $type$.newBuilder();\n"
+ "if (has$capitalized_name$()) {\n"
+ " subBuilder.mergeFrom(get$capitalized_name$());\n"
+ "}\n");
+
+ if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+ printer->Print(variables_,
+ "input.readGroup($number$, subBuilder, extensionRegistry);\n");
+ } else {
+ printer->Print(variables_,
+ "input.readMessage(subBuilder, extensionRegistry);\n");
+ }
+
+ printer->Print(variables_,
+ "set$capitalized_name$(subBuilder.buildPartial());\n");
+}
+
+void MessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " output.write$group_or_message$($number$, $name$_);\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$group_or_message$Size($number$, $name$_);\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+}
+
+void MessageFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n"
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+string MessageFieldGenerator::GetBoxedType() const {
+ return ClassName(descriptor_->message_type());
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+int RepeatedMessageFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedMessageFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ // TODO(jonp): In the future, consider having methods specific to the
+ // interface so that builders can choose dynamically to either return a
+ // message or a nested builder, so that asking for the interface doesn't
+ // cause a message to ever be built.
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$type$> \n"
+ " get$capitalized_name$List();\n"
+ "$deprecation$$type$ get$capitalized_name$(int index);\n"
+ "$deprecation$int get$capitalized_name$Count();\n");
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList();\n"
+ "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index);\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.util.List<$type$> $name$_;\n"
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n"
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList() {\n"
+ " return $name$_;\n"
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n"
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+
+}
+
+void RepeatedMessageFieldGenerator::PrintNestedBuilderCondition(
+ io::Printer* printer,
+ const char* regular_case,
+ const char* nested_builder_case) const {
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+ printer->Indent();
+ printer->Print(variables_, regular_case);
+ printer->Outdent();
+ printer->Print("} else {\n");
+ printer->Indent();
+ printer->Print(variables_, nested_builder_case);
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ printer->Print(variables_, regular_case);
+ }
+}
+
+void RepeatedMessageFieldGenerator::PrintNestedBuilderFunction(
+ io::Printer* printer,
+ const char* method_prototype,
+ const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const {
+ printer->Print(variables_, method_prototype);
+ printer->Print(" {\n");
+ printer->Indent();
+ PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+ if (trailing_code != NULL) {
+ printer->Print(variables_, trailing_code);
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // When using nested-builders, the code initially works just like the
+ // non-nested builder case. It only creates a nested builder lazily on
+ // demand and then forever delegates to it after creation.
+
+ printer->Print(variables_,
+ // Used when the builder is null.
+ // One field is the list and the other field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ "private java.util.List<$type$> $name$_ =\n"
+ " java.util.Collections.emptyList();\n"
+
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n"
+ "\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ // If this builder is non-null, it is used and the other fields are
+ // ignored.
+ "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
+ "\n");
+ }
+
+ // The comments above the methods below are based on a hypothetical
+ // repeated field of type "Field" called "RepeatedField".
+
+ // List<Field> getRepeatedFieldList()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
+
+ "return java.util.Collections.unmodifiableList($name$_);\n",
+ "return $name$Builder_.getMessageList();\n",
+
+ NULL);
+
+ // int getRepeatedFieldCount()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public int get$capitalized_name$Count()",
+
+ "return $name$_.size();\n",
+ "return $name$Builder_.getCount();\n",
+
+ NULL);
+
+ // Field getRepeatedField(int index)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public $type$ get$capitalized_name$(int index)",
+
+ "return $name$_.get(index);\n",
+
+ "return $name$Builder_.getMessage(index);\n",
+
+ NULL);
+
+ // Builder setRepeatedField(int index, Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value)",
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, value);\n"
+ "$on_changed$\n",
+ "$name$Builder_.setMessage(index, value);\n",
+ "return this;\n");
+
+ // Builder setRepeatedField(int index, Field.Builder builderForValue)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.set(index, builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.setMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$($type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(value);\n"
+
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field value)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " int index, $type$ value)",
+
+ "if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ "}\n"
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, value);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, value);\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(Field.Builder builderForValue)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addRepeatedField(int index, Field.Builder builderForValue)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " int index, $type$.Builder builderForValue)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(index, builderForValue.build());\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addMessage(index, builderForValue.build());\n",
+
+ "return this;\n");
+
+ // Builder addAllRepeatedField(Iterable<Field> values)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $type$> values)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "super.addAll(values, $name$_);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.addAllMessages(values);\n",
+
+ "return this;\n");
+
+ // Builder clearAllRepeatedField()
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder clear$capitalized_name$()",
+
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.clear();\n",
+
+ "return this;\n");
+
+ // Builder removeRepeatedField(int index)
+ PrintNestedBuilderFunction(printer,
+ "$deprecation$public Builder remove$capitalized_name$(int index)",
+
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.remove(index);\n"
+ "$on_changed$\n",
+
+ "$name$Builder_.remove(index);\n",
+
+ "return this;\n");
+
+ if (HasNestedBuilders(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
+ "}\n"
+
+ "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+ " int index) {\n"
+ " if ($name$Builder_ == null) {\n"
+ " return $name$_.get(index);"
+ " } else {\n"
+ " return $name$Builder_.getMessageOrBuilder(index);\n"
+ " }\n"
+ "}\n"
+
+ "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+ " get$capitalized_name$OrBuilderList() {\n"
+ " if ($name$Builder_ != null) {\n"
+ " return $name$Builder_.getMessageOrBuilderList();\n"
+ " } else {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ " }\n"
+ "}\n"
+
+ "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " $type$.getDefaultInstance());\n"
+ "}\n"
+ "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n"
+ " int index) {\n"
+ " return get$capitalized_name$FieldBuilder().addBuilder(\n"
+ " index, $type$.getDefaultInstance());\n"
+ "}\n"
+ "$deprecation$public java.util.List<$type$.Builder> \n"
+ " get$capitalized_name$BuilderList() {\n"
+ " return get$capitalized_name$FieldBuilder().getBuilderList();\n"
+ "}\n"
+ "private com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder> \n"
+ " get$capitalized_name$FieldBuilder() {\n"
+ " if ($name$Builder_ == null) {\n"
+ " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n"
+ " $type$, $type$.Builder, $type$OrBuilder>(\n"
+ " $name$_,\n"
+ " $get_mutable_bit_builder$,\n"
+ " getParentForChildren(),\n"
+ " isClean());\n"
+ " $name$_ = null;\n"
+ " }\n"
+ " return $name$Builder_;\n"
+ "}\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "get$capitalized_name$FieldBuilder();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ PrintNestedBuilderCondition(printer,
+ "$name$_ = java.util.Collections.emptyList();\n"
+ "$clear_mutable_bit_builder$;\n",
+
+ "$name$Builder_.clear();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ // The code below does two optimizations (non-nested builder case):
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ PrintNestedBuilderCondition(printer,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n",
+
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$Builder_.isEmpty()) {\n"
+ " $name$Builder_.dispose();\n"
+ " $name$Builder_ = null;\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $name$Builder_ = \n"
+ " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n"
+ " get$capitalized_name$FieldBuilder() : null;\n"
+ " } else {\n"
+ " $name$Builder_.addAllMessages(other.$name$_);\n"
+ " }\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ // The code below (non-nested builder case) ensures that the result has an
+ // immutable list. If our list is immutable, we can just reuse it. If not,
+ // we make it immutable.
+ PrintNestedBuilderCondition(printer,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n",
+
+ "result.$name$_ = $name$Builder_.build();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$type$.Builder subBuilder = $type$.newBuilder();\n");
+
+ if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+ printer->Print(variables_,
+ "input.readGroup($number$, subBuilder, extensionRegistry);\n");
+ } else {
+ printer->Print(variables_,
+ "input.readMessage(subBuilder, extensionRegistry);\n");
+ }
+
+ printer->Print(variables_,
+ "add$capitalized_name$(subBuilder.buildPartial());\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$group_or_message$($number$, $name$_.get(i));\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+string RepeatedMessageFieldGenerator::GetBoxedType() const {
+ return ClassName(descriptor_->message_type());
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h
new file mode 100644
index 0000000..2efbcd9
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h
@@ -0,0 +1,134 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class MessageFieldGenerator : public FieldGenerator {
+ public:
+ explicit MessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~MessageFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+
+ void PrintNestedBuilderCondition(io::Printer* printer,
+ const char* regular_case, const char* nested_builder_case) const;
+ void PrintNestedBuilderFunction(io::Printer* printer,
+ const char* method_prototype, const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const;
+};
+
+class RepeatedMessageFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~RepeatedMessageFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+
+ void PrintNestedBuilderCondition(io::Printer* printer,
+ const char* regular_case, const char* nested_builder_case) const;
+ void PrintNestedBuilderFunction(io::Printer* printer,
+ const char* method_prototype, const char* regular_case,
+ const char* nested_builder_case,
+ const char* trailing_code) const;
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc
new file mode 100644
index 0000000..ccc94c9
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// TODO(kenton): Share code with the versions of this test in other languages?
+// It seemed like parameterizing it would add more complexity than it is
+// worth.
+
+#include <google/protobuf/compiler/java/java_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/printer.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+ TestGenerator() {}
+ ~TestGenerator() {}
+
+ virtual bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+ string filename = "Test.java";
+ TryInsert(filename, "outer_class_scope", context);
+ TryInsert(filename, "class_scope:foo.Bar", context);
+ TryInsert(filename, "class_scope:foo.Bar.Baz", context);
+ TryInsert(filename, "builder_scope:foo.Bar", context);
+ TryInsert(filename, "builder_scope:foo.Bar.Baz", context);
+ TryInsert(filename, "enum_scope:foo.Qux", context);
+ return true;
+ }
+
+ void TryInsert(const string& filename, const string& insertion_point,
+ GeneratorContext* context) const {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(filename, insertion_point));
+ io::Printer printer(output.get(), '$');
+ printer.Print("// inserted $name$\n", "name", insertion_point);
+ }
+};
+
+// This test verifies that all the expected insertion points exist. It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(JavaPluginTest, PluginTest) {
+ File::WriteStringToFileOrDie(
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "option java_package = \"\";\n"
+ "option java_outer_classname = \"Test\";\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ "}\n"
+ "enum Qux { BLAH = 1; }\n",
+ TestTempDir() + "/test.proto");
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ JavaGenerator java_generator;
+ TestGenerator test_generator;
+ cli.RegisterGenerator("--java_out", &java_generator, "");
+ cli.RegisterGenerator("--test_out", &test_generator, "");
+
+ string proto_path = "-I" + TestTempDir();
+ string java_out = "--java_out=" + TestTempDir();
+ string test_out = "--test_out=" + TestTempDir();
+
+ const char* argv[] = {
+ "protoc",
+ proto_path.c_str(),
+ java_out.c_str(),
+ test_out.c_str(),
+ "test.proto"
+ };
+
+ EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+} // namespace
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc
new file mode 100644
index 0000000..712e047
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -0,0 +1,719 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_primitive_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+const char* PrimitiveTypeName(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT : return "int";
+ case JAVATYPE_LONG : return "long";
+ case JAVATYPE_FLOAT : return "float";
+ case JAVATYPE_DOUBLE : return "double";
+ case JAVATYPE_BOOLEAN: return "boolean";
+ case JAVATYPE_STRING : return "java.lang.String";
+ case JAVATYPE_BYTES : return "com.google.protobuf.ByteString";
+ case JAVATYPE_ENUM : return NULL;
+ case JAVATYPE_MESSAGE: return NULL;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+bool IsReferenceType(JavaType type) {
+ switch (type) {
+ case JAVATYPE_INT : return false;
+ case JAVATYPE_LONG : return false;
+ case JAVATYPE_FLOAT : return false;
+ case JAVATYPE_DOUBLE : return false;
+ case JAVATYPE_BOOLEAN: return false;
+ case JAVATYPE_STRING : return true;
+ case JAVATYPE_BYTES : return true;
+ case JAVATYPE_ENUM : return true;
+ case JAVATYPE_MESSAGE: return true;
+
+ // No default because we want the compiler to complain if any new
+ // JavaTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+const char* GetCapitalizedType(const FieldDescriptor* field) {
+ switch (GetType(field)) {
+ case FieldDescriptor::TYPE_INT32 : return "Int32" ;
+ case FieldDescriptor::TYPE_UINT32 : return "UInt32" ;
+ case FieldDescriptor::TYPE_SINT32 : return "SInt32" ;
+ case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ;
+ case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
+ case FieldDescriptor::TYPE_INT64 : return "Int64" ;
+ case FieldDescriptor::TYPE_UINT64 : return "UInt64" ;
+ case FieldDescriptor::TYPE_SINT64 : return "SInt64" ;
+ case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ;
+ case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
+ case FieldDescriptor::TYPE_FLOAT : return "Float" ;
+ case FieldDescriptor::TYPE_DOUBLE : return "Double" ;
+ case FieldDescriptor::TYPE_BOOL : return "Bool" ;
+ case FieldDescriptor::TYPE_STRING : return "String" ;
+ case FieldDescriptor::TYPE_BYTES : return "Bytes" ;
+ case FieldDescriptor::TYPE_ENUM : return "Enum" ;
+ case FieldDescriptor::TYPE_GROUP : return "Group" ;
+ case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32 : return -1;
+ case FieldDescriptor::TYPE_INT64 : return -1;
+ case FieldDescriptor::TYPE_UINT32 : return -1;
+ case FieldDescriptor::TYPE_UINT64 : return -1;
+ case FieldDescriptor::TYPE_SINT32 : return -1;
+ case FieldDescriptor::TYPE_SINT64 : return -1;
+ case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
+ case FieldDescriptor::TYPE_ENUM : return -1;
+
+ case FieldDescriptor::TYPE_STRING : return -1;
+ case FieldDescriptor::TYPE_BYTES : return -1;
+ case FieldDescriptor::TYPE_GROUP : return -1;
+ case FieldDescriptor::TYPE_MESSAGE : return -1;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ map<string, string>* variables) {
+ (*variables)["name"] =
+ UnderscoresToCamelCase(descriptor);
+ (*variables)["capitalized_name"] =
+ UnderscoresToCapitalizedCamelCase(descriptor);
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
+ (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+ (*variables)["field_type"] = (*variables)["type"];
+ (*variables)["field_list_type"] = "java.util.List<" +
+ (*variables)["boxed_type"] + ">";
+ (*variables)["empty_list"] = "java.util.Collections.emptyList()";
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
+ "" : ("= " + DefaultValue(descriptor));
+ (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
+ (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+ (*variables)["tag_size"] = SimpleItoa(
+ WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ if (IsReferenceType(GetJavaType(descriptor))) {
+ (*variables)["null_check"] =
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n";
+ } else {
+ (*variables)["null_check"] = "";
+ }
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
+ int fixed_size = FixedSize(GetType(descriptor));
+ if (fixed_size != -1) {
+ (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+ }
+ (*variables)["on_changed"] =
+ HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex);
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+int PrimitiveFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int PrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void PrimitiveFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n"
+ "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private $field_type$ $name$_;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private $field_type$ $name$_ $default_init$;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public $type$ get$capitalized_name$() {\n"
+ " return $name$_;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
+ "$null_check$"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$;\n");
+ JavaType type = GetJavaType(descriptor_);
+ if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
+ // The default value is not a simple literal so we want to avoid executing
+ // it multiple times. Instead, get the default out of the default instance.
+ printer->Print(variables_,
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ } else {
+ printer->Print(variables_,
+ " $name$_ = $default$;\n");
+ }
+ printer->Print(variables_,
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void PrimitiveFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$set_has_field_bit_builder$;\n"
+ "$name$_ = input.read$capitalized_type$();\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " output.write$capitalized_type$($number$, $name$_);\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .compute$capitalized_type$Size($number$, $name$_);\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ switch (GetJavaType(descriptor_)) {
+ case JAVATYPE_INT:
+ case JAVATYPE_LONG:
+ case JAVATYPE_BOOLEAN:
+ printer->Print(variables_,
+ "result = result && (get$capitalized_name$()\n"
+ " == other.get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_FLOAT:
+ printer->Print(variables_,
+ "result = result && (Float.floatToIntBits(get$capitalized_name$())"
+ " == Float.floatToIntBits(other.get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_DOUBLE:
+ printer->Print(variables_,
+ "result = result && (Double.doubleToLongBits(get$capitalized_name$())"
+ " == Double.doubleToLongBits(other.get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_STRING:
+ case JAVATYPE_BYTES:
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_ENUM:
+ case JAVATYPE_MESSAGE:
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+}
+
+void PrimitiveFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n");
+ switch (GetJavaType(descriptor_)) {
+ case JAVATYPE_INT:
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$();\n");
+ break;
+
+ case JAVATYPE_LONG:
+ printer->Print(variables_,
+ "hash = (53 * hash) + hashLong(get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_BOOLEAN:
+ printer->Print(variables_,
+ "hash = (53 * hash) + hashBoolean(get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_FLOAT:
+ printer->Print(variables_,
+ "hash = (53 * hash) + Float.floatToIntBits(\n"
+ " get$capitalized_name$());\n");
+ break;
+
+ case JAVATYPE_DOUBLE:
+ printer->Print(variables_,
+ "hash = (53 * hash) + hashLong(\n"
+ " Double.doubleToLongBits(get$capitalized_name$()));\n");
+ break;
+
+ case JAVATYPE_STRING:
+ case JAVATYPE_BYTES:
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+ break;
+
+ case JAVATYPE_ENUM:
+ case JAVATYPE_MESSAGE:
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+}
+
+string PrimitiveFieldGenerator::GetBoxedType() const {
+ return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+int RepeatedPrimitiveFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedPrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n"
+ "$deprecation$int get$capitalized_name$Count();\n"
+ "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private $field_list_type$ $name$_;\n"
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " get$capitalized_name$List() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+
+ if (descriptor_->options().packed() &&
+ HasGeneratedMethods(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "private int $name$MemoizedSerializedSize = -1;\n");
+ }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // One field is the list and the bit field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ printer->Print(variables_,
+ "private $field_list_type$ $name$_ = $empty_list$;\n");
+
+ printer->Print(variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
+ // Note: We return an unmodifiable list because otherwise the caller
+ // could hold on to the returned list and modify it after the message
+ // has been built, thus mutating the message which is supposed to be
+ // immutable.
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<$boxed_type$>\n"
+ " get$capitalized_name$List() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n"
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, $type$ value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<? extends $boxed_type$> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " super.addAll(values, $name$_);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $name$_ = $empty_list$;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $empty_list$;\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ printer->Print(variables_,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
+ printer->Print(variables_,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(input.read$capitalized_type$());\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+ printer->Print(variables_,
+ "int length = input.readRawVarint32();\n"
+ "int limit = input.pushLimit(length);\n"
+ "while (input.getBytesUntilLimit() > 0) {\n"
+ " add$capitalized_name$(input.read$capitalized_type$());\n"
+ "}\n"
+ "input.popLimit(limit);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (get$capitalized_name$List().size() > 0) {\n"
+ " output.writeRawVarint32($tag$);\n"
+ " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ "}\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$($number$, $name$_.get(i));\n"
+ "}\n");
+ }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ if (FixedSize(GetType(descriptor_)) == -1) {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ printer->Print(
+ "size += dataSize;\n");
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$List().isEmpty()) {\n"
+ " size += $tag_size$;\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeInt32SizeNoTag(dataSize);\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ // cache the data size for packed fields.
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "$name$MemoizedSerializedSize = dataSize;\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
+ return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h
new file mode 100644
index 0000000..7900fac
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class PrimitiveFieldGenerator : public FieldGenerator {
+ public:
+ explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~PrimitiveFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+};
+
+class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~RepeatedPrimitiveFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc
new file mode 100644
index 0000000..1ae4f46
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc
@@ -0,0 +1,444 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_service.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor)
+ : descriptor_(descriptor) {}
+
+ServiceGenerator::~ServiceGenerator() {}
+
+void ServiceGenerator::Generate(io::Printer* printer) {
+ bool is_own_file = descriptor_->file()->options().java_multiple_files();
+ printer->Print(
+ "public $static$ abstract class $classname$\n"
+ " implements com.google.protobuf.Service {\n",
+ "static", is_own_file ? "" : "static",
+ "classname", descriptor_->name());
+ printer->Indent();
+
+ printer->Print(
+ "protected $classname$() {}\n\n",
+ "classname", descriptor_->name());
+
+ GenerateInterface(printer);
+
+ GenerateNewReflectiveServiceMethod(printer);
+ GenerateNewReflectiveBlockingServiceMethod(printer);
+
+ GenerateAbstractMethods(printer);
+
+ // Generate getDescriptor() and getDescriptorForType().
+ printer->Print(
+ "public static final\n"
+ " com.google.protobuf.Descriptors.ServiceDescriptor\n"
+ " getDescriptor() {\n"
+ " return $file$.getDescriptor().getServices().get($index$);\n"
+ "}\n",
+ "file", ClassName(descriptor_->file()),
+ "index", SimpleItoa(descriptor_->index()));
+ GenerateGetDescriptorForType(printer);
+
+ // Generate more stuff.
+ GenerateCallMethod(printer);
+ GenerateGetPrototype(REQUEST, printer);
+ GenerateGetPrototype(RESPONSE, printer);
+ GenerateStub(printer);
+ GenerateBlockingStub(printer);
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ServiceGenerator::GenerateGetDescriptorForType(io::Printer* printer) {
+ printer->Print(
+ "public final com.google.protobuf.Descriptors.ServiceDescriptor\n"
+ " getDescriptorForType() {\n"
+ " return getDescriptor();\n"
+ "}\n");
+}
+
+void ServiceGenerator::GenerateInterface(io::Printer* printer) {
+ printer->Print("public interface Interface {\n");
+ printer->Indent();
+ GenerateAbstractMethods(printer);
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ServiceGenerator::GenerateNewReflectiveServiceMethod(
+ io::Printer* printer) {
+ printer->Print(
+ "public static com.google.protobuf.Service newReflectiveService(\n"
+ " final Interface impl) {\n"
+ " return new $classname$() {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ printer->Print("@java.lang.Override\n");
+ GenerateMethodSignature(printer, method, IS_CONCRETE);
+ printer->Print(
+ " {\n"
+ " impl.$method$(controller, request, done);\n"
+ "}\n\n",
+ "method", UnderscoresToCamelCase(method));
+ }
+
+ printer->Outdent();
+ printer->Print("};\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ServiceGenerator::GenerateNewReflectiveBlockingServiceMethod(
+ io::Printer* printer) {
+ printer->Print(
+ "public static com.google.protobuf.BlockingService\n"
+ " newReflectiveBlockingService(final BlockingInterface impl) {\n"
+ " return new com.google.protobuf.BlockingService() {\n");
+ printer->Indent();
+ printer->Indent();
+
+ GenerateGetDescriptorForType(printer);
+
+ GenerateCallBlockingMethod(printer);
+ GenerateGetPrototype(REQUEST, printer);
+ GenerateGetPrototype(RESPONSE, printer);
+
+ printer->Outdent();
+ printer->Print("};\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void ServiceGenerator::GenerateAbstractMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ GenerateMethodSignature(printer, method, IS_ABSTRACT);
+ printer->Print(";\n\n");
+ }
+}
+
+void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
+ printer->Print(
+ "\n"
+ "public final void callMethod(\n"
+ " com.google.protobuf.Descriptors.MethodDescriptor method,\n"
+ " com.google.protobuf.RpcController controller,\n"
+ " com.google.protobuf.Message request,\n"
+ " com.google.protobuf.RpcCallback<\n"
+ " com.google.protobuf.Message> done) {\n"
+ " if (method.getService() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Service.callMethod() given method descriptor for wrong \" +\n"
+ " \"service type.\");\n"
+ " }\n"
+ " switch(method.getIndex()) {\n");
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ map<string, string> vars;
+ vars["index"] = SimpleItoa(i);
+ vars["method"] = UnderscoresToCamelCase(method);
+ vars["input"] = ClassName(method->input_type());
+ vars["output"] = ClassName(method->output_type());
+ printer->Print(vars,
+ "case $index$:\n"
+ " this.$method$(controller, ($input$)request,\n"
+ " com.google.protobuf.RpcUtil.<$output$>specializeCallback(\n"
+ " done));\n"
+ " return;\n");
+ }
+
+ printer->Print(
+ "default:\n"
+ " throw new java.lang.AssertionError(\"Can't get here.\");\n");
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateCallBlockingMethod(io::Printer* printer) {
+ printer->Print(
+ "\n"
+ "public final com.google.protobuf.Message callBlockingMethod(\n"
+ " com.google.protobuf.Descriptors.MethodDescriptor method,\n"
+ " com.google.protobuf.RpcController controller,\n"
+ " com.google.protobuf.Message request)\n"
+ " throws com.google.protobuf.ServiceException {\n"
+ " if (method.getService() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Service.callBlockingMethod() given method descriptor for \" +\n"
+ " \"wrong service type.\");\n"
+ " }\n"
+ " switch(method.getIndex()) {\n");
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ map<string, string> vars;
+ vars["index"] = SimpleItoa(i);
+ vars["method"] = UnderscoresToCamelCase(method);
+ vars["input"] = ClassName(method->input_type());
+ vars["output"] = ClassName(method->output_type());
+ printer->Print(vars,
+ "case $index$:\n"
+ " return impl.$method$(controller, ($input$)request);\n");
+ }
+
+ printer->Print(
+ "default:\n"
+ " throw new java.lang.AssertionError(\"Can't get here.\");\n");
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
+ io::Printer* printer) {
+ /*
+ * TODO(cpovirk): The exception message says "Service.foo" when it may be
+ * "BlockingService.foo." Consider fixing.
+ */
+ printer->Print(
+ "public final com.google.protobuf.Message\n"
+ " get$request_or_response$Prototype(\n"
+ " com.google.protobuf.Descriptors.MethodDescriptor method) {\n"
+ " if (method.getService() != getDescriptor()) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Service.get$request_or_response$Prototype() given method \" +\n"
+ " \"descriptor for wrong service type.\");\n"
+ " }\n"
+ " switch(method.getIndex()) {\n",
+ "request_or_response", (which == REQUEST) ? "Request" : "Response");
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ map<string, string> vars;
+ vars["index"] = SimpleItoa(i);
+ vars["type"] = ClassName(
+ (which == REQUEST) ? method->input_type() : method->output_type());
+ printer->Print(vars,
+ "case $index$:\n"
+ " return $type$.getDefaultInstance();\n");
+ }
+
+ printer->Print(
+ "default:\n"
+ " throw new java.lang.AssertionError(\"Can't get here.\");\n");
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateStub(io::Printer* printer) {
+ printer->Print(
+ "public static Stub newStub(\n"
+ " com.google.protobuf.RpcChannel channel) {\n"
+ " return new Stub(channel);\n"
+ "}\n"
+ "\n"
+ "public static final class Stub extends $classname$ implements Interface {"
+ "\n",
+ "classname", ClassName(descriptor_));
+ printer->Indent();
+
+ printer->Print(
+ "private Stub(com.google.protobuf.RpcChannel channel) {\n"
+ " this.channel = channel;\n"
+ "}\n"
+ "\n"
+ "private final com.google.protobuf.RpcChannel channel;\n"
+ "\n"
+ "public com.google.protobuf.RpcChannel getChannel() {\n"
+ " return channel;\n"
+ "}\n");
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ printer->Print("\n");
+ GenerateMethodSignature(printer, method, IS_CONCRETE);
+ printer->Print(" {\n");
+ printer->Indent();
+
+ map<string, string> vars;
+ vars["index"] = SimpleItoa(i);
+ vars["output"] = ClassName(method->output_type());
+ printer->Print(vars,
+ "channel.callMethod(\n"
+ " getDescriptor().getMethods().get($index$),\n"
+ " controller,\n"
+ " request,\n"
+ " $output$.getDefaultInstance(),\n"
+ " com.google.protobuf.RpcUtil.generalizeCallback(\n"
+ " done,\n"
+ " $output$.class,\n"
+ " $output$.getDefaultInstance()));\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+}
+
+void ServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
+ printer->Print(
+ "public static BlockingInterface newBlockingStub(\n"
+ " com.google.protobuf.BlockingRpcChannel channel) {\n"
+ " return new BlockingStub(channel);\n"
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "public interface BlockingInterface {");
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ GenerateBlockingMethodSignature(printer, method);
+ printer->Print(";\n");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ printer->Print(
+ "private static final class BlockingStub implements BlockingInterface {\n");
+ printer->Indent();
+
+ printer->Print(
+ "private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {\n"
+ " this.channel = channel;\n"
+ "}\n"
+ "\n"
+ "private final com.google.protobuf.BlockingRpcChannel channel;\n");
+
+ for (int i = 0; i < descriptor_->method_count(); i++) {
+ const MethodDescriptor* method = descriptor_->method(i);
+ GenerateBlockingMethodSignature(printer, method);
+ printer->Print(" {\n");
+ printer->Indent();
+
+ map<string, string> vars;
+ vars["index"] = SimpleItoa(i);
+ vars["output"] = ClassName(method->output_type());
+ printer->Print(vars,
+ "return ($output$) channel.callBlockingMethod(\n"
+ " getDescriptor().getMethods().get($index$),\n"
+ " controller,\n"
+ " request,\n"
+ " $output$.getDefaultInstance());\n");
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void ServiceGenerator::GenerateMethodSignature(io::Printer* printer,
+ const MethodDescriptor* method,
+ IsAbstract is_abstract) {
+ map<string, string> vars;
+ vars["name"] = UnderscoresToCamelCase(method);
+ vars["input"] = ClassName(method->input_type());
+ vars["output"] = ClassName(method->output_type());
+ vars["abstract"] = (is_abstract == IS_ABSTRACT) ? "abstract" : "";
+ printer->Print(vars,
+ "public $abstract$ void $name$(\n"
+ " com.google.protobuf.RpcController controller,\n"
+ " $input$ request,\n"
+ " com.google.protobuf.RpcCallback<$output$> done)");
+}
+
+void ServiceGenerator::GenerateBlockingMethodSignature(
+ io::Printer* printer,
+ const MethodDescriptor* method) {
+ map<string, string> vars;
+ vars["method"] = UnderscoresToCamelCase(method);
+ vars["input"] = ClassName(method->input_type());
+ vars["output"] = ClassName(method->output_type());
+ printer->Print(vars,
+ "\n"
+ "public $output$ $method$(\n"
+ " com.google.protobuf.RpcController controller,\n"
+ " $input$ request)\n"
+ " throws com.google.protobuf.ServiceException");
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_service.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_service.h
new file mode 100644
index 0000000..e07eebf
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_service.h
@@ -0,0 +1,113 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__
+
+#include <map>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ServiceGenerator {
+ public:
+ explicit ServiceGenerator(const ServiceDescriptor* descriptor);
+ ~ServiceGenerator();
+
+ void Generate(io::Printer* printer);
+
+ private:
+
+ // Generate the getDescriptorForType() method.
+ void GenerateGetDescriptorForType(io::Printer* printer);
+
+ // Generate a Java interface for the service.
+ void GenerateInterface(io::Printer* printer);
+
+ // Generate newReflectiveService() method.
+ void GenerateNewReflectiveServiceMethod(io::Printer* printer);
+
+ // Generate newReflectiveBlockingService() method.
+ void GenerateNewReflectiveBlockingServiceMethod(io::Printer* printer);
+
+ // Generate abstract method declarations for all methods.
+ void GenerateAbstractMethods(io::Printer* printer);
+
+ // Generate the implementation of Service.callMethod().
+ void GenerateCallMethod(io::Printer* printer);
+
+ // Generate the implementation of BlockingService.callBlockingMethod().
+ void GenerateCallBlockingMethod(io::Printer* printer);
+
+ // Generate the implementations of Service.get{Request,Response}Prototype().
+ enum RequestOrResponse { REQUEST, RESPONSE };
+ void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
+
+ // Generate a stub implementation of the service.
+ void GenerateStub(io::Printer* printer);
+
+ // Generate a method signature, possibly abstract, without body or trailing
+ // semicolon.
+ enum IsAbstract { IS_ABSTRACT, IS_CONCRETE };
+ void GenerateMethodSignature(io::Printer* printer,
+ const MethodDescriptor* method,
+ IsAbstract is_abstract);
+
+ // Generate a blocking stub interface and implementation of the service.
+ void GenerateBlockingStub(io::Printer* printer);
+
+ // Generate the method signature for one method of a blocking stub.
+ void GenerateBlockingMethodSignature(io::Printer* printer,
+ const MethodDescriptor* method);
+
+ const ServiceDescriptor* descriptor_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+#endif // NET_PROTO2_COMPILER_JAVA_SERVICE_H__
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc
new file mode 100644
index 0000000..222285b
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc
@@ -0,0 +1,610 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_string_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex,
+ map<string, string>* variables) {
+ (*variables)["name"] =
+ UnderscoresToCamelCase(descriptor);
+ (*variables)["capitalized_name"] =
+ UnderscoresToCapitalizedCamelCase(descriptor);
+ (*variables)["constant_name"] = FieldConstantName(descriptor);
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
+
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_init"] = ("= " + DefaultValue(descriptor));
+ (*variables)["capitalized_type"] = "String";
+ (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+ (*variables)["tag_size"] = SimpleItoa(
+ WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+ (*variables)["null_check"] =
+ " if (value == null) {\n"
+ " throw new NullPointerException();\n"
+ " }\n";
+
+ // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+ // by the proto compiler
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? "@java.lang.Deprecated " : "";
+ (*variables)["on_changed"] =
+ HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+ // For singular messages and builders, one bit is used for the hasField bit.
+ (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+
+ (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_has_field_bit_builder"] =
+ GenerateClearBit(builderBitIndex);
+
+ // For repated builders, one bit is used for whether the array is immutable.
+ (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+ (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+ (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+ (*variables)["get_has_field_bit_from_local"] =
+ GenerateGetBitFromLocal(builderBitIndex);
+ (*variables)["set_has_field_bit_to_local"] =
+ GenerateSetBitToLocal(messageBitIndex);
+}
+
+} // namespace
+
+// ===================================================================
+
+StringFieldGenerator::
+StringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
+}
+
+StringFieldGenerator::~StringFieldGenerator() {}
+
+int StringFieldGenerator::GetNumBitsForMessage() const {
+ return 1;
+}
+
+int StringFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+// A note about how strings are handled. This code used to just store a String
+// in the Message. This had two issues:
+//
+// 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
+// strings, but rather fields that were raw bytes incorrectly marked
+// as strings in the proto file. This is common because in the proto1
+// syntax, string was the way to indicate bytes and C++ engineers can
+// easily make this mistake without affecting the C++ API. By converting to
+// strings immediately, some java code might corrupt these byte arrays as
+// it passes through a java server even if the field was never accessed by
+// application code.
+//
+// 2. There's a performance hit to converting between bytes and strings and
+// it many cases, the field is never even read by the application code. This
+// avoids unnecessary conversions in the common use cases.
+//
+// So now, the field for String is maintained as an Object reference which can
+// either store a String or a ByteString. The code uses an instanceof check
+// to see which one it has and converts to the other one if needed. It remembers
+// the last value requested (in a thread safe manner) as this is most likely
+// the one needed next. The thread safety is such that if two threads both
+// convert the field because the changes made by each thread were not visible to
+// the other, they may cause a conversion to happen more times than would
+// otherwise be necessary. This was deemed better than adding synchronization
+// overhead. It will not cause any corruption issues or affect the behavior of
+// the API. The instanceof check is also highly optimized in the JVM and we
+// decided it was better to reduce the memory overhead by not having two
+// separate fields but rather use dynamic type checking.
+//
+// For single fields, the logic for this is done inside the generated code. For
+// repeated fields, the logic is done in LazyStringArrayList and
+// UnmodifiableLazyStringList.
+void StringFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$boolean has$capitalized_name$();\n"
+ "$deprecation$java.lang.String get$capitalized_name$();\n");
+}
+
+void StringFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.lang.Object $name$_;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_message$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " return (java.lang.String) ref;\n"
+ " } else {\n"
+ " com.google.protobuf.ByteString bs = \n"
+ " (com.google.protobuf.ByteString) ref;\n"
+ " java.lang.String s = bs.toStringUtf8();\n"
+ " if (com.google.protobuf.Internal.isValidUtf8(bs)) {\n"
+ " $name$_ = s;\n"
+ " }\n"
+ " return s;\n"
+ " }\n"
+ "}\n"
+ "private com.google.protobuf.ByteString get$capitalized_name$Bytes() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (ref instanceof java.lang.String) {\n"
+ " com.google.protobuf.ByteString b = \n"
+ " com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " (java.lang.String) ref);\n"
+ " $name$_ = b;\n"
+ " return b;\n"
+ " } else {\n"
+ " return (com.google.protobuf.ByteString) ref;\n"
+ " }\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private java.lang.Object $name$_ $default_init$;\n"
+ "$deprecation$public boolean has$capitalized_name$() {\n"
+ " return $get_has_field_bit_builder$;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+ " java.lang.Object ref = $name$_;\n"
+ " if (!(ref instanceof java.lang.String)) {\n"
+ " java.lang.String s = ((com.google.protobuf.ByteString) ref)\n"
+ " .toStringUtf8();\n"
+ " $name$_ = s;\n"
+ " return s;\n"
+ " } else {\n"
+ " return (java.lang.String) ref;\n"
+ " }\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $clear_has_field_bit_builder$;\n");
+ // The default value is not a simple literal so we want to avoid executing
+ // it multiple times. Instead, get the default out of the default instance.
+ printer->Print(variables_,
+ " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+ printer->Print(variables_,
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "void set$capitalized_name$(com.google.protobuf.ByteString value) {\n"
+ " $set_has_field_bit_builder$;\n"
+ " $name$_ = value;\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void StringFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void StringFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $default$;\n"
+ "$clear_has_field_bit_builder$;\n");
+}
+
+void StringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (other.has$capitalized_name$()) {\n"
+ " set$capitalized_name$(other.get$capitalized_name$());\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_from_local$) {\n"
+ " $set_has_field_bit_to_local$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void StringFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$set_has_field_bit_builder$;\n"
+ "$name$_ = input.readBytes();\n");
+}
+
+void StringFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($get_has_field_bit_message$) {\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$()\n"
+ " .equals(other.get$capitalized_name$());\n");
+}
+
+void StringFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "hash = (37 * hash) + $constant_name$;\n");
+ printer->Print(variables_,
+ "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+string StringFieldGenerator::GetBoxedType() const {
+ return "java.lang.String";
+}
+
+
+// ===================================================================
+
+RepeatedStringFieldGenerator::
+RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex,
+ int builderBitIndex)
+ : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+ builderBitIndex_(builderBitIndex) {
+ SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+ &variables_);
+}
+
+RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
+
+int RepeatedStringFieldGenerator::GetNumBitsForMessage() const {
+ return 0;
+}
+
+int RepeatedStringFieldGenerator::GetNumBitsForBuilder() const {
+ return 1;
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$deprecation$java.util.List<java.lang.String>\n"
+ " get$capitalized_name$List();\n"
+ "$deprecation$int get$capitalized_name$Count();\n"
+ "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
+}
+
+
+void RepeatedStringFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyStringList $name$_;\n"
+ "$deprecation$public java.util.List<java.lang.String>\n"
+ " get$capitalized_name$List() {\n"
+ " return $name$_;\n" // note: unmodifiable list
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n");
+
+ if (descriptor_->options().packed() &&
+ HasGeneratedMethods(descriptor_->containing_type())) {
+ printer->Print(variables_,
+ "private int $name$MemoizedSerializedSize = -1;\n");
+ }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+ // One field is the list and the bit field keeps track of whether the
+ // list is immutable. If it's immutable, the invariant is that it must
+ // either an instance of Collections.emptyList() or it's an ArrayList
+ // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+ // a refererence to the underlying ArrayList. This invariant allows us to
+ // share instances of lists between protocol buffers avoiding expensive
+ // memory allocations. Note, immutable is a strong guarantee here -- not
+ // just that the list cannot be modified via the reference but that the
+ // list can never be modified.
+ printer->Print(variables_,
+ "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
+
+ printer->Print(variables_,
+ "private void ensure$capitalized_name$IsMutable() {\n"
+ " if (!$get_mutable_bit_builder$) {\n"
+ " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
+ " $set_mutable_bit_builder$;\n"
+ " }\n"
+ "}\n");
+
+ // Note: We return an unmodifiable list because otherwise the caller
+ // could hold on to the returned list and modify it after the message
+ // has been built, thus mutating the message which is supposed to be
+ // immutable.
+ printer->Print(variables_,
+ "$deprecation$public java.util.List<java.lang.String>\n"
+ " get$capitalized_name$List() {\n"
+ " return java.util.Collections.unmodifiableList($name$_);\n"
+ "}\n"
+ "$deprecation$public int get$capitalized_name$Count() {\n"
+ " return $name$_.size();\n"
+ "}\n"
+ "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
+ " return $name$_.get(index);\n"
+ "}\n"
+ "$deprecation$public Builder set$capitalized_name$(\n"
+ " int index, java.lang.String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.set(index, value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder add$capitalized_name$(\n"
+ " java.lang.String value) {\n"
+ "$null_check$"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder addAll$capitalized_name$(\n"
+ " java.lang.Iterable<java.lang.String> values) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " super.addAll(values, $name$_);\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n"
+ "$deprecation$public Builder clear$capitalized_name$() {\n"
+ " $name$_ = $empty_list$;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " $on_changed$\n"
+ " return this;\n"
+ "}\n");
+
+ printer->Print(variables_,
+ "void add$capitalized_name$(com.google.protobuf.ByteString value) {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.add(value);\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
+ // noop for primitives
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = $empty_list$;\n"
+ "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ // The code below does two optimizations:
+ // 1. If the other list is empty, there's nothing to do. This ensures we
+ // don't allocate a new array if we already have an immutable one.
+ // 2. If the other list is non-empty and our current list is empty, we can
+ // reuse the other list which is guaranteed to be immutable.
+ printer->Print(variables_,
+ "if (!other.$name$_.isEmpty()) {\n"
+ " if ($name$_.isEmpty()) {\n"
+ " $name$_ = other.$name$_;\n"
+ " $clear_mutable_bit_builder$;\n"
+ " } else {\n"
+ " ensure$capitalized_name$IsMutable();\n"
+ " $name$_.addAll(other.$name$_);\n"
+ " }\n"
+ " $on_changed$\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+ // The code below ensures that the result has an immutable list. If our
+ // list is immutable, we can just reuse it. If not, we make it immutable.
+
+ printer->Print(variables_,
+ "if ($get_mutable_bit_builder$) {\n"
+ " $name$_ = new com.google.protobuf.UnmodifiableLazyStringList(\n"
+ " $name$_);\n"
+ " $clear_mutable_bit_builder$;\n"
+ "}\n"
+ "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "ensure$capitalized_name$IsMutable();\n"
+ "$name$_.add(input.readBytes());\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+ printer->Print(variables_,
+ "int length = input.readRawVarint32();\n"
+ "int limit = input.pushLimit(length);\n"
+ "while (input.getBytesUntilLimit() > 0) {\n"
+ " add$capitalized_name$(input.read$capitalized_type$());\n"
+ "}\n"
+ "input.popLimit(limit);\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (get$capitalized_name$List().size() > 0) {\n"
+ " output.writeRawVarint32($tag$);\n"
+ " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+ "}\n"
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " output.writeBytes($number$, $name$_.getByteString(i));\n"
+ "}\n");
+ }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int dataSize = 0;\n");
+ printer->Indent();
+
+ printer->Print(variables_,
+ "for (int i = 0; i < $name$_.size(); i++) {\n"
+ " dataSize += com.google.protobuf.CodedOutputStream\n"
+ " .computeBytesSizeNoTag($name$_.getByteString(i));\n"
+ "}\n");
+
+ printer->Print(
+ "size += dataSize;\n");
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (!get$capitalized_name$List().isEmpty()) {\n"
+ " size += $tag_size$;\n"
+ " size += com.google.protobuf.CodedOutputStream\n"
+ " .computeInt32SizeNoTag(dataSize);\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "size += $tag_size$ * get$capitalized_name$List().size();\n");
+ }
+
+ // cache the data size for packed fields.
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "$name$MemoizedSerializedSize = dataSize;\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "result = result && get$capitalized_name$List()\n"
+ " .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (get$capitalized_name$Count() > 0) {\n"
+ " hash = (37 * hash) + $constant_name$;\n"
+ " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+ "}\n");
+}
+
+string RepeatedStringFieldGenerator::GetBoxedType() const {
+ return "String";
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h
new file mode 100644
index 0000000..8cb4146
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h
@@ -0,0 +1,120 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class StringFieldGenerator : public FieldGenerator {
+ public:
+ explicit StringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~StringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
+};
+
+class RepeatedStringFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ int messageBitIndex, int builderBitIndex);
+ ~RepeatedStringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ int GetNumBitsForMessage() const;
+ int GetNumBitsForBuilder() const;
+ void GenerateInterfaceMembers(io::Printer* printer) const;
+ void GenerateMembers(io::Printer* printer) const;
+ void GenerateBuilderMembers(io::Printer* printer) const;
+ void GenerateInitializationCode(io::Printer* printer) const;
+ void GenerateBuilderClearCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateBuildingCode(io::Printer* printer) const;
+ void GenerateParsingCode(io::Printer* printer) const;
+ void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+ void GenerateSerializationCode(io::Printer* printer) const;
+ void GenerateSerializedSizeCode(io::Printer* printer) const;
+ void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+ void GenerateEqualsCode(io::Printer* printer) const;
+ void GenerateHashCode(io::Printer* printer) const;
+ string GetBoxedType() const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+ const int messageBitIndex_;
+ const int builderBitIndex_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/main.cc b/src/third_party/protobuf/src/google/protobuf/compiler/main.cc
new file mode 100644
index 0000000..d9b0c3f
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/main.cc
@@ -0,0 +1,61 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+#include <google/protobuf/compiler/python/python_generator.h>
+#include <google/protobuf/compiler/java/java_generator.h>
+
+
+int main(int argc, char* argv[]) {
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.AllowPlugins("protoc-");
+
+ // Proto2 C++
+ google::protobuf::compiler::cpp::CppGenerator cpp_generator;
+ cli.RegisterGenerator("--cpp_out", &cpp_generator,
+ "Generate C++ header and source.");
+
+ // Proto2 Java
+ google::protobuf::compiler::java::JavaGenerator java_generator;
+ cli.RegisterGenerator("--java_out", &java_generator,
+ "Generate Java source file.");
+
+
+ // Proto2 Python
+ google::protobuf::compiler::python::Generator py_generator;
+ cli.RegisterGenerator("--python_out", &py_generator,
+ "Generate Python source file.");
+
+ return cli.Run(argc, argv);
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc b/src/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc
new file mode 100644
index 0000000..5b76af2
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc
@@ -0,0 +1,231 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/mock_code_generator.h>
+
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// Returns the list of the names of files in all_files in the form of a
+// comma-separated string.
+string CommaSeparatedList(const vector<const FileDescriptor*> all_files) {
+ vector<string> names;
+ for (int i = 0; i < all_files.size(); i++) {
+ names.push_back(all_files[i]->name());
+ }
+ return JoinStrings(names, ",");
+}
+
+static const char* kFirstInsertionPointName = "first_mock_insertion_point";
+static const char* kSecondInsertionPointName = "second_mock_insertion_point";
+static const char* kFirstInsertionPoint =
+ "# @@protoc_insertion_point(first_mock_insertion_point) is here\n";
+static const char* kSecondInsertionPoint =
+ " # @@protoc_insertion_point(second_mock_insertion_point) is here\n";
+
+MockCodeGenerator::MockCodeGenerator(const string& name)
+ : name_(name) {}
+
+MockCodeGenerator::~MockCodeGenerator() {}
+
+void MockCodeGenerator::ExpectGenerated(
+ const string& name,
+ const string& parameter,
+ const string& insertions,
+ const string& file,
+ const string& first_message_name,
+ const string& first_parsed_file_name,
+ const string& output_directory) {
+ string content;
+ ASSERT_TRUE(File::ReadFileToString(
+ output_directory + "/" + GetOutputFileName(name, file), &content));
+
+ vector<string> lines;
+ SplitStringUsing(content, "\n", &lines);
+
+ while (!lines.empty() && lines.back().empty()) {
+ lines.pop_back();
+ }
+ for (int i = 0; i < lines.size(); i++) {
+ lines[i] += "\n";
+ }
+
+ vector<string> insertion_list;
+ if (!insertions.empty()) {
+ SplitStringUsing(insertions, ",", &insertion_list);
+ }
+
+ ASSERT_EQ(lines.size(), 3 + insertion_list.size() * 2);
+ EXPECT_EQ(GetOutputFileContent(name, parameter, file,
+ first_parsed_file_name, first_message_name),
+ lines[0]);
+
+ EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]);
+ EXPECT_EQ(kSecondInsertionPoint, lines[2 + insertion_list.size() * 2]);
+
+ for (int i = 0; i < insertion_list.size(); i++) {
+ EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert",
+ file, file, first_message_name),
+ lines[1 + i]);
+ // Second insertion point is indented, so the inserted text should
+ // automatically be indented too.
+ EXPECT_EQ(" " + GetOutputFileContent(insertion_list[i], "second_insert",
+ file, file, first_message_name),
+ lines[2 + insertion_list.size() + i]);
+ }
+}
+
+bool MockCodeGenerator::Generate(
+ const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) {
+ string command = StripPrefixString(file->message_type(i)->name(),
+ "MockCodeGenerator_");
+ if (command == "Error") {
+ *error = "Saw message type MockCodeGenerator_Error.";
+ return false;
+ } else if (command == "Exit") {
+ cerr << "Saw message type MockCodeGenerator_Exit." << endl;
+ exit(123);
+ } else if (command == "Abort") {
+ cerr << "Saw message type MockCodeGenerator_Abort." << endl;
+ abort();
+ } else {
+ GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command;
+ }
+ }
+ }
+
+ if (HasPrefixString(parameter, "insert=")) {
+ vector<string> insert_into;
+ SplitStringUsing(StripPrefixString(parameter, "insert="),
+ ",", &insert_into);
+
+ for (int i = 0; i < insert_into.size(); i++) {
+ {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(
+ GetOutputFileName(insert_into[i], file),
+ kFirstInsertionPointName));
+ io::Printer printer(output.get(), '$');
+ printer.PrintRaw(GetOutputFileContent(name_, "first_insert",
+ file, context));
+ if (printer.failed()) {
+ *error = "MockCodeGenerator detected write error.";
+ return false;
+ }
+ }
+
+ {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(
+ GetOutputFileName(insert_into[i], file),
+ kSecondInsertionPointName));
+ io::Printer printer(output.get(), '$');
+ printer.PrintRaw(GetOutputFileContent(name_, "second_insert",
+ file, context));
+ if (printer.failed()) {
+ *error = "MockCodeGenerator detected write error.";
+ return false;
+ }
+ }
+ }
+ } else {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(GetOutputFileName(name_, file)));
+
+ io::Printer printer(output.get(), '$');
+ printer.PrintRaw(GetOutputFileContent(name_, parameter,
+ file, context));
+ printer.PrintRaw(kFirstInsertionPoint);
+ printer.PrintRaw(kSecondInsertionPoint);
+
+ if (printer.failed()) {
+ *error = "MockCodeGenerator detected write error.";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+string MockCodeGenerator::GetOutputFileName(const string& generator_name,
+ const FileDescriptor* file) {
+ return GetOutputFileName(generator_name, file->name());
+}
+
+string MockCodeGenerator::GetOutputFileName(const string& generator_name,
+ const string& file) {
+ return file + ".MockCodeGenerator." + generator_name;
+}
+
+string MockCodeGenerator::GetOutputFileContent(
+ const string& generator_name,
+ const string& parameter,
+ const FileDescriptor* file,
+ GeneratorContext *context) {
+ vector<const FileDescriptor*> all_files;
+ context->ListParsedFiles(&all_files);
+ return GetOutputFileContent(
+ generator_name, parameter, file->name(),
+ CommaSeparatedList(all_files),
+ file->message_type_count() > 0 ?
+ file->message_type(0)->name() : "(none)");
+}
+
+string MockCodeGenerator::GetOutputFileContent(
+ const string& generator_name,
+ const string& parameter,
+ const string& file,
+ const string& parsed_file_list,
+ const string& first_message_name) {
+ return strings::Substitute("$0: $1, $2, $3, $4\n",
+ generator_name, parameter, file,
+ first_message_name, parsed_file_list);
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h b/src/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h
new file mode 100644
index 0000000..5c7942b
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h
@@ -0,0 +1,113 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
+
+#include <string>
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// A mock CodeGenerator, used by command_line_interface_unittest. This is in
+// its own file so that it can be used both directly and as a plugin.
+//
+// Generate() produces some output which can be checked by ExpectCalled(). The
+// generator can run in a different process (e.g. a plugin).
+//
+// If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines
+// into the files generated by other MockCodeGenerators instead of creating
+// its own file. NAMES is a comma-separated list of the names of those other
+// MockCodeGenerators.
+//
+// MockCodeGenerator will also modify its behavior slightly if the input file
+// contains a message type with one of the following names:
+// MockCodeGenerator_Error: Causes Generate() to return false and set the
+// error message to "Saw message type MockCodeGenerator_Error."
+// MockCodeGenerator_Exit: Generate() prints "Saw message type
+// MockCodeGenerator_Exit." to stderr and then calls exit(123).
+// MockCodeGenerator_Abort: Generate() prints "Saw message type
+// MockCodeGenerator_Abort." to stderr and then calls abort().
+class MockCodeGenerator : public CodeGenerator {
+ public:
+ MockCodeGenerator(const string& name);
+ virtual ~MockCodeGenerator();
+
+ // Expect (via gTest) that a MockCodeGenerator with the given name was called
+ // with the given parameters by inspecting the output location.
+ //
+ // |insertions| is a comma-separated list of names of MockCodeGenerators which
+ // should have inserted lines into this file.
+ // |parsed_file_list| is a comma-separated list of names of the files
+ // that are being compiled together in this run.
+ static void ExpectGenerated(const string& name,
+ const string& parameter,
+ const string& insertions,
+ const string& file,
+ const string& first_message_name,
+ const string& parsed_file_list,
+ const string& output_directory);
+
+ // Get the name of the file which would be written by the given generator.
+ static string GetOutputFileName(const string& generator_name,
+ const FileDescriptor* file);
+ static string GetOutputFileName(const string& generator_name,
+ const string& file);
+
+ // implements CodeGenerator ----------------------------------------
+
+ virtual bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const;
+
+ private:
+ string name_;
+
+ static string GetOutputFileContent(const string& generator_name,
+ const string& parameter,
+ const FileDescriptor* file,
+ GeneratorContext *context);
+ static string GetOutputFileContent(const string& generator_name,
+ const string& parameter,
+ const string& file,
+ const string& parsed_file_list,
+ const string& first_message_name);
+};
+
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/package_info.h b/src/third_party/protobuf/src/google/protobuf/compiler/package_info.h
new file mode 100644
index 0000000..b897126
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/package_info.h
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file exists solely to document the google::protobuf::compiler namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+
+namespace protobuf {
+
+// Implementation of the Protocol Buffer compiler.
+//
+// This package contains code for parsing .proto files and generating code
+// based on them. There are two reasons you might be interested in this
+// package:
+// - You want to parse .proto files at runtime. In this case, you should
+// look at importer.h. Since this functionality is widely useful, it is
+// included in the libprotobuf base library; you do not have to link against
+// libprotoc.
+// - You want to write a custom protocol compiler which generates different
+// kinds of code, e.g. code in a different language which is not supported
+// by the official compiler. For this purpose, command_line_interface.h
+// provides you with a complete compiler front-end, so all you need to do
+// is write a custom implementation of CodeGenerator and a trivial main()
+// function. You can even make your compiler support the official languages
+// in addition to your own. Since this functionality is only useful to those
+// writing custom compilers, it is in a separate library called "libprotoc"
+// which you will have to link against.
+namespace compiler {}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/parser.cc b/src/third_party/protobuf/src/google/protobuf/compiler/parser.cc
new file mode 100644
index 0000000..34317b1
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/parser.cc
@@ -0,0 +1,1473 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Recursive descent FTW.
+
+#include <float.h>
+#include <google/protobuf/stubs/hash.h>
+#include <limits>
+
+
+#include <google/protobuf/compiler/parser.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map-util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+using internal::WireFormat;
+
+namespace {
+
+typedef hash_map<string, FieldDescriptorProto::Type> TypeNameMap;
+
+TypeNameMap MakeTypeNameTable() {
+ TypeNameMap result;
+
+ result["double" ] = FieldDescriptorProto::TYPE_DOUBLE;
+ result["float" ] = FieldDescriptorProto::TYPE_FLOAT;
+ result["uint64" ] = FieldDescriptorProto::TYPE_UINT64;
+ result["fixed64" ] = FieldDescriptorProto::TYPE_FIXED64;
+ result["fixed32" ] = FieldDescriptorProto::TYPE_FIXED32;
+ result["bool" ] = FieldDescriptorProto::TYPE_BOOL;
+ result["string" ] = FieldDescriptorProto::TYPE_STRING;
+ result["group" ] = FieldDescriptorProto::TYPE_GROUP;
+
+ result["bytes" ] = FieldDescriptorProto::TYPE_BYTES;
+ result["uint32" ] = FieldDescriptorProto::TYPE_UINT32;
+ result["sfixed32"] = FieldDescriptorProto::TYPE_SFIXED32;
+ result["sfixed64"] = FieldDescriptorProto::TYPE_SFIXED64;
+ result["int32" ] = FieldDescriptorProto::TYPE_INT32;
+ result["int64" ] = FieldDescriptorProto::TYPE_INT64;
+ result["sint32" ] = FieldDescriptorProto::TYPE_SINT32;
+ result["sint64" ] = FieldDescriptorProto::TYPE_SINT64;
+
+ return result;
+}
+
+const TypeNameMap kTypeNames = MakeTypeNameTable();
+
+} // anonymous namespace
+
+// Makes code slightly more readable. The meaning of "DO(foo)" is
+// "Execute foo and fail if it fails.", where failure is indicated by
+// returning false.
+#define DO(STATEMENT) if (STATEMENT) {} else return false
+
+// ===================================================================
+
+Parser::Parser()
+ : input_(NULL),
+ error_collector_(NULL),
+ source_location_table_(NULL),
+ had_errors_(false),
+ require_syntax_identifier_(false),
+ stop_after_syntax_identifier_(false) {
+}
+
+Parser::~Parser() {
+}
+
+// ===================================================================
+
+inline bool Parser::LookingAt(const char* text) {
+ return input_->current().text == text;
+}
+
+inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) {
+ return input_->current().type == token_type;
+}
+
+inline bool Parser::AtEnd() {
+ return LookingAtType(io::Tokenizer::TYPE_END);
+}
+
+bool Parser::TryConsume(const char* text) {
+ if (LookingAt(text)) {
+ input_->Next();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool Parser::Consume(const char* text, const char* error) {
+ if (TryConsume(text)) {
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::Consume(const char* text) {
+ if (TryConsume(text)) {
+ return true;
+ } else {
+ AddError("Expected \"" + string(text) + "\".");
+ return false;
+ }
+}
+
+bool Parser::ConsumeIdentifier(string* output, const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ *output = input_->current().text;
+ input_->Next();
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::ConsumeInteger(int* output, const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ uint64 value = 0;
+ if (!io::Tokenizer::ParseInteger(input_->current().text,
+ kint32max, &value)) {
+ AddError("Integer out of range.");
+ // We still return true because we did, in fact, parse an integer.
+ }
+ *output = value;
+ input_->Next();
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::ConsumeInteger64(uint64 max_value, uint64* output,
+ const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ if (!io::Tokenizer::ParseInteger(input_->current().text, max_value,
+ output)) {
+ AddError("Integer out of range.");
+ // We still return true because we did, in fact, parse an integer.
+ *output = 0;
+ }
+ input_->Next();
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::ConsumeNumber(double* output, const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
+ *output = io::Tokenizer::ParseFloat(input_->current().text);
+ input_->Next();
+ return true;
+ } else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ // Also accept integers.
+ uint64 value = 0;
+ if (!io::Tokenizer::ParseInteger(input_->current().text,
+ kuint64max, &value)) {
+ AddError("Integer out of range.");
+ // We still return true because we did, in fact, parse a number.
+ }
+ *output = value;
+ input_->Next();
+ return true;
+ } else if (LookingAt("inf")) {
+ *output = numeric_limits<double>::infinity();
+ input_->Next();
+ return true;
+ } else if (LookingAt("nan")) {
+ *output = numeric_limits<double>::quiet_NaN();
+ input_->Next();
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+bool Parser::ConsumeString(string* output, const char* error) {
+ if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ io::Tokenizer::ParseString(input_->current().text, output);
+ input_->Next();
+ // Allow C++ like concatenation of adjacent string tokens.
+ while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ io::Tokenizer::ParseStringAppend(input_->current().text, output);
+ input_->Next();
+ }
+ return true;
+ } else {
+ AddError(error);
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------
+
+void Parser::AddError(int line, int column, const string& error) {
+ if (error_collector_ != NULL) {
+ error_collector_->AddError(line, column, error);
+ }
+ had_errors_ = true;
+}
+
+void Parser::AddError(const string& error) {
+ AddError(input_->current().line, input_->current().column, error);
+}
+
+// -------------------------------------------------------------------
+
+Parser::LocationRecorder::LocationRecorder(Parser* parser)
+ : parser_(parser),
+ location_(parser_->source_code_info_->add_location()) {
+ location_->add_span(parser_->input_->current().line);
+ location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) {
+ Init(parent);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1) {
+ Init(parent);
+ AddPath(path1);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+ int path1, int path2) {
+ Init(parent);
+ AddPath(path1);
+ AddPath(path2);
+}
+
+void Parser::LocationRecorder::Init(const LocationRecorder& parent) {
+ parser_ = parent.parser_;
+ location_ = parser_->source_code_info_->add_location();
+ location_->mutable_path()->CopyFrom(parent.location_->path());
+
+ location_->add_span(parser_->input_->current().line);
+ location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::~LocationRecorder() {
+ if (location_->span_size() <= 2) {
+ EndAt(parser_->input_->previous());
+ }
+}
+
+void Parser::LocationRecorder::AddPath(int path_component) {
+ location_->add_path(path_component);
+}
+
+void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) {
+ location_->set_span(0, token.line);
+ location_->set_span(1, token.column);
+}
+
+void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) {
+ if (token.line != location_->span(0)) {
+ location_->add_span(token.line);
+ }
+ location_->add_span(token.end_column);
+}
+
+void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location) {
+ if (parser_->source_location_table_ != NULL) {
+ parser_->source_location_table_->Add(
+ descriptor, location, location_->span(0), location_->span(1));
+ }
+}
+
+// -------------------------------------------------------------------
+
+void Parser::SkipStatement() {
+ while (true) {
+ if (AtEnd()) {
+ return;
+ } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
+ if (TryConsume(";")) {
+ return;
+ } else if (TryConsume("{")) {
+ SkipRestOfBlock();
+ return;
+ } else if (LookingAt("}")) {
+ return;
+ }
+ }
+ input_->Next();
+ }
+}
+
+void Parser::SkipRestOfBlock() {
+ while (true) {
+ if (AtEnd()) {
+ return;
+ } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
+ if (TryConsume("}")) {
+ return;
+ } else if (TryConsume("{")) {
+ SkipRestOfBlock();
+ }
+ }
+ input_->Next();
+ }
+}
+
+// ===================================================================
+
+bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
+ input_ = input;
+ had_errors_ = false;
+ syntax_identifier_.clear();
+
+ // Note that |file| could be NULL at this point if
+ // stop_after_syntax_identifier_ is true. So, we conservatively allocate
+ // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto
+ // later on.
+ SourceCodeInfo source_code_info;
+ source_code_info_ = &source_code_info;
+
+ if (LookingAtType(io::Tokenizer::TYPE_START)) {
+ // Advance to first token.
+ input_->Next();
+ }
+
+ {
+ LocationRecorder root_location(this);
+
+ if (require_syntax_identifier_ || LookingAt("syntax")) {
+ if (!ParseSyntaxIdentifier()) {
+ // Don't attempt to parse the file if we didn't recognize the syntax
+ // identifier.
+ return false;
+ }
+ } else if (!stop_after_syntax_identifier_) {
+ syntax_identifier_ = "proto2";
+ }
+
+ if (stop_after_syntax_identifier_) return !had_errors_;
+
+ // Repeatedly parse statements until we reach the end of the file.
+ while (!AtEnd()) {
+ if (!ParseTopLevelStatement(file, root_location)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+
+ if (LookingAt("}")) {
+ AddError("Unmatched \"}\".");
+ input_->Next();
+ }
+ }
+ }
+ }
+
+ input_ = NULL;
+ source_code_info_ = NULL;
+ source_code_info.Swap(file->mutable_source_code_info());
+ return !had_errors_;
+}
+
+bool Parser::ParseSyntaxIdentifier() {
+ DO(Consume("syntax", "File must begin with 'syntax = \"proto2\";'."));
+ DO(Consume("="));
+ io::Tokenizer::Token syntax_token = input_->current();
+ string syntax;
+ DO(ConsumeString(&syntax, "Expected syntax identifier."));
+ DO(Consume(";"));
+
+ syntax_identifier_ = syntax;
+
+ if (syntax != "proto2" && !stop_after_syntax_identifier_) {
+ AddError(syntax_token.line, syntax_token.column,
+ "Unrecognized syntax identifier \"" + syntax + "\". This parser "
+ "only recognizes \"proto2\".");
+ return false;
+ }
+
+ return true;
+}
+
+bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
+ const LocationRecorder& root_location) {
+ if (TryConsume(";")) {
+ // empty statement; ignore
+ return true;
+ } else if (LookingAt("message")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size());
+ return ParseMessageDefinition(file->add_message_type(), location);
+ } else if (LookingAt("enum")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size());
+ return ParseEnumDefinition(file->add_enum_type(), location);
+ } else if (LookingAt("service")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kServiceFieldNumber, file->service_size());
+ return ParseServiceDefinition(file->add_service(), location);
+ } else if (LookingAt("extend")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kExtensionFieldNumber);
+ return ParseExtend(file->mutable_extension(),
+ file->mutable_message_type(),
+ root_location,
+ FileDescriptorProto::kMessageTypeFieldNumber,
+ location);
+ } else if (LookingAt("import")) {
+ int index = file->dependency_size();
+ return ParseImport(file->add_dependency(), root_location, index);
+ } else if (LookingAt("package")) {
+ return ParsePackage(file, root_location);
+ } else if (LookingAt("option")) {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(file->mutable_options(), location);
+ } else {
+ AddError("Expected top-level statement (e.g. \"message\").");
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------
+// Messages
+
+bool Parser::ParseMessageDefinition(DescriptorProto* message,
+ const LocationRecorder& message_location) {
+ DO(Consume("message"));
+ {
+ LocationRecorder location(message_location,
+ DescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ message, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
+ }
+ DO(ParseMessageBlock(message, message_location));
+ return true;
+}
+
+bool Parser::ParseMessageBlock(DescriptorProto* message,
+ const LocationRecorder& message_location) {
+ DO(Consume("{"));
+
+ while (!TryConsume("}")) {
+ if (AtEnd()) {
+ AddError("Reached end of input in message definition (missing '}').");
+ return false;
+ }
+
+ if (!ParseMessageStatement(message, message_location)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ }
+
+ return true;
+}
+
+bool Parser::ParseMessageStatement(DescriptorProto* message,
+ const LocationRecorder& message_location) {
+ if (TryConsume(";")) {
+ // empty statement; ignore
+ return true;
+ } else if (LookingAt("message")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ message->nested_type_size());
+ return ParseMessageDefinition(message->add_nested_type(), location);
+ } else if (LookingAt("enum")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kEnumTypeFieldNumber,
+ message->enum_type_size());
+ return ParseEnumDefinition(message->add_enum_type(), location);
+ } else if (LookingAt("extensions")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kExtensionRangeFieldNumber);
+ return ParseExtensions(message, location);
+ } else if (LookingAt("extend")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kExtensionFieldNumber);
+ return ParseExtend(message->mutable_extension(),
+ message->mutable_nested_type(),
+ message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ location);
+ } else if (LookingAt("option")) {
+ LocationRecorder location(message_location,
+ DescriptorProto::kOptionsFieldNumber);
+ return ParseOption(message->mutable_options(), location);
+ } else {
+ LocationRecorder location(message_location,
+ DescriptorProto::kFieldFieldNumber,
+ message->field_size());
+ return ParseMessageField(message->add_field(),
+ message->mutable_nested_type(),
+ message_location,
+ DescriptorProto::kNestedTypeFieldNumber,
+ location);
+ }
+}
+
+bool Parser::ParseMessageField(FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location) {
+ // Parse label and type.
+ io::Tokenizer::Token label_token = input_->current();
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kLabelFieldNumber);
+ FieldDescriptorProto::Label label;
+ DO(ParseLabel(&label));
+ field->set_label(label);
+ }
+
+ {
+ LocationRecorder location(field_location); // add path later
+ location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE);
+
+ FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
+ string type_name;
+ DO(ParseType(&type, &type_name));
+ if (type_name.empty()) {
+ location.AddPath(FieldDescriptorProto::kTypeFieldNumber);
+ field->set_type(type);
+ } else {
+ location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
+ field->set_type_name(type_name);
+ }
+ }
+
+ // Parse name and '='.
+ io::Tokenizer::Token name_token = input_->current();
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
+ }
+ DO(Consume("=", "Missing field number."));
+
+ // Parse field number.
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kNumberFieldNumber);
+ location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::NUMBER);
+ int number;
+ DO(ConsumeInteger(&number, "Expected field number."));
+ field->set_number(number);
+ }
+
+ // Parse options.
+ DO(ParseFieldOptions(field, field_location));
+
+ // Deal with groups.
+ if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) {
+ // Awkward: Since a group declares both a message type and a field, we
+ // have to create overlapping locations.
+ LocationRecorder group_location(parent_location);
+ group_location.StartAt(label_token);
+ group_location.AddPath(location_field_number_for_nested_type);
+ group_location.AddPath(messages->size());
+
+ DescriptorProto* group = messages->Add();
+ group->set_name(field->name());
+
+ // Record name location to match the field name's location.
+ {
+ LocationRecorder location(group_location,
+ DescriptorProto::kNameFieldNumber);
+ location.StartAt(name_token);
+ location.EndAt(name_token);
+ location.RecordLegacyLocation(
+ group, DescriptorPool::ErrorCollector::NAME);
+ }
+
+ // The field's type_name also comes from the name. Confusing!
+ {
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kTypeNameFieldNumber);
+ location.StartAt(name_token);
+ location.EndAt(name_token);
+ }
+
+ // As a hack for backwards-compatibility, we force the group name to start
+ // with a capital letter and lower-case the field name. New code should
+ // not use groups; it should use nested messages.
+ if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
+ AddError(name_token.line, name_token.column,
+ "Group names must start with a capital letter.");
+ }
+ LowerString(field->mutable_name());
+
+ field->set_type_name(group->name());
+ if (LookingAt("{")) {
+ DO(ParseMessageBlock(group, group_location));
+ } else {
+ AddError("Missing group body.");
+ return false;
+ }
+ } else {
+ DO(Consume(";"));
+ }
+
+ return true;
+}
+
+bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
+ const LocationRecorder& field_location) {
+ if (!LookingAt("[")) return true;
+
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kOptionsFieldNumber);
+
+ DO(Consume("["));
+
+ // Parse field options.
+ do {
+ if (LookingAt("default")) {
+ // We intentionally pass field_location rather than location here, since
+ // the default value is not actually an option.
+ DO(ParseDefaultAssignment(field, field_location));
+ } else {
+ DO(ParseOptionAssignment(field->mutable_options(), location));
+ }
+ } while (TryConsume(","));
+
+ DO(Consume("]"));
+ return true;
+}
+
+bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field,
+ const LocationRecorder& field_location) {
+ if (field->has_default_value()) {
+ AddError("Already set option \"default\".");
+ field->clear_default_value();
+ }
+
+ DO(Consume("default"));
+ DO(Consume("="));
+
+ LocationRecorder location(field_location,
+ FieldDescriptorProto::kDefaultValueFieldNumber);
+ location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::DEFAULT_VALUE);
+ string* default_value = field->mutable_default_value();
+
+ if (!field->has_type()) {
+ // The field has a type name, but we don't know if it is a message or an
+ // enum yet. Assume an enum for now.
+ DO(ConsumeIdentifier(default_value, "Expected identifier."));
+ return true;
+ }
+
+ switch (field->type()) {
+ case FieldDescriptorProto::TYPE_INT32:
+ case FieldDescriptorProto::TYPE_INT64:
+ case FieldDescriptorProto::TYPE_SINT32:
+ case FieldDescriptorProto::TYPE_SINT64:
+ case FieldDescriptorProto::TYPE_SFIXED32:
+ case FieldDescriptorProto::TYPE_SFIXED64: {
+ uint64 max_value = kint64max;
+ if (field->type() == FieldDescriptorProto::TYPE_INT32 ||
+ field->type() == FieldDescriptorProto::TYPE_SINT32 ||
+ field->type() == FieldDescriptorProto::TYPE_SFIXED32) {
+ max_value = kint32max;
+ }
+
+ // These types can be negative.
+ if (TryConsume("-")) {
+ default_value->append("-");
+ // Two's complement always has one more negative value than positive.
+ ++max_value;
+ }
+ // Parse the integer to verify that it is not out-of-range.
+ uint64 value;
+ DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+ // And stringify it again.
+ default_value->append(SimpleItoa(value));
+ break;
+ }
+
+ case FieldDescriptorProto::TYPE_UINT32:
+ case FieldDescriptorProto::TYPE_UINT64:
+ case FieldDescriptorProto::TYPE_FIXED32:
+ case FieldDescriptorProto::TYPE_FIXED64: {
+ uint64 max_value = kuint64max;
+ if (field->type() == FieldDescriptorProto::TYPE_UINT32 ||
+ field->type() == FieldDescriptorProto::TYPE_FIXED32) {
+ max_value = kuint32max;
+ }
+
+ // Numeric, not negative.
+ if (TryConsume("-")) {
+ AddError("Unsigned field can't have negative default value.");
+ }
+ // Parse the integer to verify that it is not out-of-range.
+ uint64 value;
+ DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+ // And stringify it again.
+ default_value->append(SimpleItoa(value));
+ break;
+ }
+
+ case FieldDescriptorProto::TYPE_FLOAT:
+ case FieldDescriptorProto::TYPE_DOUBLE:
+ // These types can be negative.
+ if (TryConsume("-")) {
+ default_value->append("-");
+ }
+ // Parse the integer because we have to convert hex integers to decimal
+ // floats.
+ double value;
+ DO(ConsumeNumber(&value, "Expected number."));
+ // And stringify it again.
+ default_value->append(SimpleDtoa(value));
+ break;
+
+ case FieldDescriptorProto::TYPE_BOOL:
+ if (TryConsume("true")) {
+ default_value->assign("true");
+ } else if (TryConsume("false")) {
+ default_value->assign("false");
+ } else {
+ AddError("Expected \"true\" or \"false\".");
+ return false;
+ }
+ break;
+
+ case FieldDescriptorProto::TYPE_STRING:
+ DO(ConsumeString(default_value, "Expected string."));
+ break;
+
+ case FieldDescriptorProto::TYPE_BYTES:
+ DO(ConsumeString(default_value, "Expected string."));
+ *default_value = CEscape(*default_value);
+ break;
+
+ case FieldDescriptorProto::TYPE_ENUM:
+ DO(ConsumeIdentifier(default_value, "Expected identifier."));
+ break;
+
+ case FieldDescriptorProto::TYPE_MESSAGE:
+ case FieldDescriptorProto::TYPE_GROUP:
+ AddError("Messages can't have default values.");
+ return false;
+ }
+
+ return true;
+}
+
+bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+ const LocationRecorder& part_location) {
+ UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
+ string identifier; // We parse identifiers into this string.
+ if (LookingAt("(")) { // This is an extension.
+ DO(Consume("("));
+
+ {
+ LocationRecorder location(
+ part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
+ // An extension name consists of dot-separated identifiers, and may begin
+ // with a dot.
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ }
+ while (LookingAt(".")) {
+ DO(Consume("."));
+ name->mutable_name_part()->append(".");
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ }
+ }
+
+ DO(Consume(")"));
+ name->set_is_extension(true);
+ } else { // This is a regular field.
+ LocationRecorder location(
+ part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ name->mutable_name_part()->append(identifier);
+ name->set_is_extension(false);
+ }
+ return true;
+}
+
+bool Parser::ParseUninterpretedBlock(string* value) {
+ // Note that enclosing braces are not added to *value.
+ DO(Consume("{"));
+ int brace_depth = 1;
+ while (!AtEnd()) {
+ if (LookingAt("{")) {
+ brace_depth++;
+ } else if (LookingAt("}")) {
+ brace_depth--;
+ if (brace_depth == 0) {
+ input_->Next();
+ return true;
+ }
+ }
+ // TODO(sanjay): Interpret line/column numbers to preserve formatting
+ if (!value->empty()) value->push_back(' ');
+ value->append(input_->current().text);
+ input_->Next();
+ }
+ AddError("Unexpected end of stream while parsing aggregate value.");
+ return false;
+}
+
+// We don't interpret the option here. Instead we store it in an
+// UninterpretedOption, to be interpreted later.
+bool Parser::ParseOptionAssignment(Message* options,
+ const LocationRecorder& options_location) {
+ // Create an entry in the uninterpreted_option field.
+ const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
+ FindFieldByName("uninterpreted_option");
+ GOOGLE_CHECK(uninterpreted_option_field != NULL)
+ << "No field named \"uninterpreted_option\" in the Options proto.";
+
+ const Reflection* reflection = options->GetReflection();
+
+ LocationRecorder location(
+ options_location, uninterpreted_option_field->number(),
+ reflection->FieldSize(*options, uninterpreted_option_field));
+
+ UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
+ options->GetReflection()->AddMessage(options,
+ uninterpreted_option_field));
+
+ // Parse dot-separated name.
+ {
+ LocationRecorder name_location(location,
+ UninterpretedOption::kNameFieldNumber);
+ name_location.RecordLegacyLocation(
+ uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME);
+
+ {
+ LocationRecorder part_location(name_location,
+ uninterpreted_option->name_size());
+ DO(ParseOptionNamePart(uninterpreted_option, part_location));
+ }
+
+ while (LookingAt(".")) {
+ DO(Consume("."));
+ LocationRecorder part_location(name_location,
+ uninterpreted_option->name_size());
+ DO(ParseOptionNamePart(uninterpreted_option, part_location));
+ }
+ }
+
+ DO(Consume("="));
+
+ LocationRecorder value_location(location);
+ value_location.RecordLegacyLocation(
+ uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
+
+ // All values are a single token, except for negative numbers, which consist
+ // of a single '-' symbol, followed by a positive number.
+ bool is_negative = TryConsume("-");
+
+ switch (input_->current().type) {
+ case io::Tokenizer::TYPE_START:
+ GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
+ return false;
+
+ case io::Tokenizer::TYPE_END:
+ AddError("Unexpected end of stream while parsing option value.");
+ return false;
+
+ case io::Tokenizer::TYPE_IDENTIFIER: {
+ value_location.AddPath(UninterpretedOption::kIdentifierValueFieldNumber);
+ if (is_negative) {
+ AddError("Invalid '-' symbol before identifier.");
+ return false;
+ }
+ string value;
+ DO(ConsumeIdentifier(&value, "Expected identifier."));
+ uninterpreted_option->set_identifier_value(value);
+ break;
+ }
+
+ case io::Tokenizer::TYPE_INTEGER: {
+ uint64 value;
+ uint64 max_value =
+ is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
+ DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+ if (is_negative) {
+ value_location.AddPath(
+ UninterpretedOption::kNegativeIntValueFieldNumber);
+ uninterpreted_option->set_negative_int_value(-static_cast<int64>(value));
+ } else {
+ value_location.AddPath(
+ UninterpretedOption::kPositiveIntValueFieldNumber);
+ uninterpreted_option->set_positive_int_value(value);
+ }
+ break;
+ }
+
+ case io::Tokenizer::TYPE_FLOAT: {
+ value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber);
+ double value;
+ DO(ConsumeNumber(&value, "Expected number."));
+ uninterpreted_option->set_double_value(is_negative ? -value : value);
+ break;
+ }
+
+ case io::Tokenizer::TYPE_STRING: {
+ value_location.AddPath(UninterpretedOption::kStringValueFieldNumber);
+ if (is_negative) {
+ AddError("Invalid '-' symbol before string.");
+ return false;
+ }
+ string value;
+ DO(ConsumeString(&value, "Expected string."));
+ uninterpreted_option->set_string_value(value);
+ break;
+ }
+
+ case io::Tokenizer::TYPE_SYMBOL:
+ if (LookingAt("{")) {
+ value_location.AddPath(UninterpretedOption::kAggregateValueFieldNumber);
+ DO(ParseUninterpretedBlock(
+ uninterpreted_option->mutable_aggregate_value()));
+ } else {
+ AddError("Expected option value.");
+ return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
+bool Parser::ParseExtensions(DescriptorProto* message,
+ const LocationRecorder& extensions_location) {
+ // Parse the declaration.
+ DO(Consume("extensions"));
+
+ do {
+ // Note that kExtensionRangeFieldNumber was already pushed by the parent.
+ LocationRecorder location(extensions_location,
+ message->extension_range_size());
+
+ DescriptorProto::ExtensionRange* range = message->add_extension_range();
+ location.RecordLegacyLocation(
+ range, DescriptorPool::ErrorCollector::NUMBER);
+
+ int start, end;
+ io::Tokenizer::Token start_token;
+
+ {
+ LocationRecorder start_location(
+ location, DescriptorProto::ExtensionRange::kStartFieldNumber);
+ start_token = input_->current();
+ DO(ConsumeInteger(&start, "Expected field number range."));
+ }
+
+ if (TryConsume("to")) {
+ LocationRecorder end_location(
+ location, DescriptorProto::ExtensionRange::kEndFieldNumber);
+ if (TryConsume("max")) {
+ end = FieldDescriptor::kMaxNumber;
+ } else {
+ DO(ConsumeInteger(&end, "Expected integer."));
+ }
+ } else {
+ LocationRecorder end_location(
+ location, DescriptorProto::ExtensionRange::kEndFieldNumber);
+ end_location.StartAt(start_token);
+ end_location.EndAt(start_token);
+ end = start;
+ }
+
+ // Users like to specify inclusive ranges, but in code we like the end
+ // number to be exclusive.
+ ++end;
+
+ range->set_start(start);
+ range->set_end(end);
+ } while (TryConsume(","));
+
+ DO(Consume(";"));
+ return true;
+}
+
+bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& extend_location) {
+ DO(Consume("extend"));
+
+ // Parse the extendee type.
+ io::Tokenizer::Token extendee_start = input_->current();
+ string extendee;
+ DO(ParseUserDefinedType(&extendee));
+ io::Tokenizer::Token extendee_end = input_->previous();
+
+ // Parse the block.
+ DO(Consume("{"));
+
+ bool is_first = true;
+
+ do {
+ if (AtEnd()) {
+ AddError("Reached end of input in extend definition (missing '}').");
+ return false;
+ }
+
+ // Note that kExtensionFieldNumber was already pushed by the parent.
+ LocationRecorder location(extend_location, extensions->size());
+
+ FieldDescriptorProto* field = extensions->Add();
+
+ {
+ LocationRecorder extendee_location(
+ location, FieldDescriptorProto::kExtendeeFieldNumber);
+ extendee_location.StartAt(extendee_start);
+ extendee_location.EndAt(extendee_end);
+
+ if (is_first) {
+ extendee_location.RecordLegacyLocation(
+ field, DescriptorPool::ErrorCollector::EXTENDEE);
+ is_first = false;
+ }
+ }
+
+ field->set_extendee(extendee);
+
+ if (!ParseMessageField(field, messages, parent_location,
+ location_field_number_for_nested_type,
+ location)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ } while(!TryConsume("}"));
+
+ return true;
+}
+
+// -------------------------------------------------------------------
+// Enums
+
+bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location) {
+ DO(Consume("enum"));
+
+ {
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ enum_type, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
+ }
+
+ DO(ParseEnumBlock(enum_type, enum_location));
+ return true;
+}
+
+bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location) {
+ DO(Consume("{"));
+
+ while (!TryConsume("}")) {
+ if (AtEnd()) {
+ AddError("Reached end of input in enum definition (missing '}').");
+ return false;
+ }
+
+ if (!ParseEnumStatement(enum_type, enum_location)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ }
+
+ return true;
+}
+
+bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location) {
+ if (TryConsume(";")) {
+ // empty statement; ignore
+ return true;
+ } else if (LookingAt("option")) {
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(enum_type->mutable_options(), location);
+ } else {
+ LocationRecorder location(enum_location,
+ EnumDescriptorProto::kValueFieldNumber, enum_type->value_size());
+ return ParseEnumConstant(enum_type->add_value(), location);
+ }
+}
+
+bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+ const LocationRecorder& enum_value_location) {
+ // Parse name.
+ {
+ LocationRecorder location(enum_value_location,
+ EnumValueDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ enum_value, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(enum_value->mutable_name(),
+ "Expected enum constant name."));
+ }
+
+ DO(Consume("=", "Missing numeric value for enum constant."));
+
+ // Parse value.
+ {
+ LocationRecorder location(
+ enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber);
+ location.RecordLegacyLocation(
+ enum_value, DescriptorPool::ErrorCollector::NUMBER);
+
+ bool is_negative = TryConsume("-");
+ int number;
+ DO(ConsumeInteger(&number, "Expected integer."));
+ if (is_negative) number *= -1;
+ enum_value->set_number(number);
+ }
+
+ DO(ParseEnumConstantOptions(enum_value, enum_value_location));
+
+ DO(Consume(";"));
+
+ return true;
+}
+
+bool Parser::ParseEnumConstantOptions(
+ EnumValueDescriptorProto* value,
+ const LocationRecorder& enum_value_location) {
+ if (!LookingAt("[")) return true;
+
+ LocationRecorder location(
+ enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber);
+
+ DO(Consume("["));
+
+ do {
+ DO(ParseOptionAssignment(value->mutable_options(), location));
+ } while (TryConsume(","));
+
+ DO(Consume("]"));
+ return true;
+}
+
+// -------------------------------------------------------------------
+// Services
+
+bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location) {
+ DO(Consume("service"));
+
+ {
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ service, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
+ }
+
+ DO(ParseServiceBlock(service, service_location));
+ return true;
+}
+
+bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location) {
+ DO(Consume("{"));
+
+ while (!TryConsume("}")) {
+ if (AtEnd()) {
+ AddError("Reached end of input in service definition (missing '}').");
+ return false;
+ }
+
+ if (!ParseServiceStatement(service, service_location)) {
+ // This statement failed to parse. Skip it, but keep looping to parse
+ // other statements.
+ SkipStatement();
+ }
+ }
+
+ return true;
+}
+
+bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location) {
+ if (TryConsume(";")) {
+ // empty statement; ignore
+ return true;
+ } else if (LookingAt("option")) {
+ LocationRecorder location(
+ service_location, ServiceDescriptorProto::kOptionsFieldNumber);
+ return ParseOption(service->mutable_options(), location);
+ } else {
+ LocationRecorder location(service_location,
+ ServiceDescriptorProto::kMethodFieldNumber, service->method_size());
+ return ParseServiceMethod(service->add_method(), location);
+ }
+}
+
+bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
+ const LocationRecorder& method_location) {
+ DO(Consume("rpc"));
+
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kNameFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::NAME);
+ DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
+ }
+
+ // Parse input type.
+ DO(Consume("("));
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kInputTypeFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::INPUT_TYPE);
+ DO(ParseUserDefinedType(method->mutable_input_type()));
+ }
+ DO(Consume(")"));
+
+ // Parse output type.
+ DO(Consume("returns"));
+ DO(Consume("("));
+ {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kOutputTypeFieldNumber);
+ location.RecordLegacyLocation(
+ method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
+ DO(ParseUserDefinedType(method->mutable_output_type()));
+ }
+ DO(Consume(")"));
+
+ if (TryConsume("{")) {
+ // Options!
+ while (!TryConsume("}")) {
+ if (AtEnd()) {
+ AddError("Reached end of input in method options (missing '}').");
+ return false;
+ }
+
+ if (TryConsume(";")) {
+ // empty statement; ignore
+ } else {
+ LocationRecorder location(method_location,
+ MethodDescriptorProto::kOptionsFieldNumber);
+ if (!ParseOption(method->mutable_options(), location)) {
+ // This statement failed to parse. Skip it, but keep looping to
+ // parse other statements.
+ SkipStatement();
+ }
+ }
+ }
+ } else {
+ DO(Consume(";"));
+ }
+
+ return true;
+}
+
+// -------------------------------------------------------------------
+
+bool Parser::ParseLabel(FieldDescriptorProto::Label* label) {
+ if (TryConsume("optional")) {
+ *label = FieldDescriptorProto::LABEL_OPTIONAL;
+ return true;
+ } else if (TryConsume("repeated")) {
+ *label = FieldDescriptorProto::LABEL_REPEATED;
+ return true;
+ } else if (TryConsume("required")) {
+ *label = FieldDescriptorProto::LABEL_REQUIRED;
+ return true;
+ } else {
+ AddError("Expected \"required\", \"optional\", or \"repeated\".");
+ // We can actually reasonably recover here by just assuming the user
+ // forgot the label altogether.
+ *label = FieldDescriptorProto::LABEL_OPTIONAL;
+ return true;
+ }
+}
+
+bool Parser::ParseType(FieldDescriptorProto::Type* type,
+ string* type_name) {
+ TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
+ if (iter != kTypeNames.end()) {
+ *type = iter->second;
+ input_->Next();
+ } else {
+ DO(ParseUserDefinedType(type_name));
+ }
+ return true;
+}
+
+bool Parser::ParseUserDefinedType(string* type_name) {
+ type_name->clear();
+
+ TypeNameMap::const_iterator iter = kTypeNames.find(input_->current().text);
+ if (iter != kTypeNames.end()) {
+ // Note: The only place enum types are allowed is for field types, but
+ // if we are parsing a field type then we would not get here because
+ // primitives are allowed there as well. So this error message doesn't
+ // need to account for enums.
+ AddError("Expected message type.");
+
+ // Pretend to accept this type so that we can go on parsing.
+ *type_name = input_->current().text;
+ input_->Next();
+ return true;
+ }
+
+ // A leading "." means the name is fully-qualified.
+ if (TryConsume(".")) type_name->append(".");
+
+ // Consume the first part of the name.
+ string identifier;
+ DO(ConsumeIdentifier(&identifier, "Expected type name."));
+ type_name->append(identifier);
+
+ // Consume more parts.
+ while (TryConsume(".")) {
+ type_name->append(".");
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ type_name->append(identifier);
+ }
+
+ return true;
+}
+
+// ===================================================================
+
+bool Parser::ParsePackage(FileDescriptorProto* file,
+ const LocationRecorder& root_location) {
+ if (file->has_package()) {
+ AddError("Multiple package definitions.");
+ // Don't append the new package to the old one. Just replace it. Not
+ // that it really matters since this is an error anyway.
+ file->clear_package();
+ }
+
+ DO(Consume("package"));
+
+ {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kPackageFieldNumber);
+ location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME);
+
+ while (true) {
+ string identifier;
+ DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+ file->mutable_package()->append(identifier);
+ if (!TryConsume(".")) break;
+ file->mutable_package()->append(".");
+ }
+ }
+
+ DO(Consume(";"));
+ return true;
+}
+
+bool Parser::ParseImport(string* import_filename,
+ const LocationRecorder& root_location,
+ int index) {
+ DO(Consume("import"));
+ {
+ LocationRecorder location(root_location,
+ FileDescriptorProto::kDependencyFieldNumber,
+ index);
+ DO(ConsumeString(import_filename,
+ "Expected a string naming the file to import."));
+ }
+ DO(Consume(";"));
+ return true;
+}
+
+bool Parser::ParseOption(Message* options,
+ const LocationRecorder& options_location) {
+ DO(Consume("option"));
+ DO(ParseOptionAssignment(options, options_location));
+ DO(Consume(";"));
+ return true;
+}
+
+// ===================================================================
+
+SourceLocationTable::SourceLocationTable() {}
+SourceLocationTable::~SourceLocationTable() {}
+
+bool SourceLocationTable::Find(
+ const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ int* line, int* column) const {
+ const pair<int, int>* result =
+ FindOrNull(location_map_, make_pair(descriptor, location));
+ if (result == NULL) {
+ *line = -1;
+ *column = 0;
+ return false;
+ } else {
+ *line = result->first;
+ *column = result->second;
+ return true;
+ }
+}
+
+void SourceLocationTable::Add(
+ const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ int line, int column) {
+ location_map_[make_pair(descriptor, location)] = make_pair(line, column);
+}
+
+void SourceLocationTable::Clear() {
+ location_map_.clear();
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/parser.h b/src/third_party/protobuf/src/google/protobuf/compiler/parser.h
new file mode 100644
index 0000000..4cc90a2
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/parser.h
@@ -0,0 +1,434 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Implements parsing of .proto files to FileDescriptorProtos.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
+#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
+
+#include <map>
+#include <string>
+#include <utility>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/io/tokenizer.h>
+
+namespace google {
+namespace protobuf { class Message; }
+
+namespace protobuf {
+namespace compiler {
+
+// Defined in this file.
+class Parser;
+class SourceLocationTable;
+
+// Implements parsing of protocol definitions (such as .proto files).
+//
+// Note that most users will be more interested in the Importer class.
+// Parser is a lower-level class which simply converts a single .proto file
+// to a FileDescriptorProto. It does not resolve import directives or perform
+// many other kinds of validation needed to construct a complete
+// FileDescriptor.
+class LIBPROTOBUF_EXPORT Parser {
+ public:
+ Parser();
+ ~Parser();
+
+ // Parse the entire input and construct a FileDescriptorProto representing
+ // it. Returns true if no errors occurred, false otherwise.
+ bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
+
+ // Optional fetaures:
+
+ // DEPRECATED: New code should use the SourceCodeInfo embedded in the
+ // FileDescriptorProto.
+ //
+ // Requests that locations of certain definitions be recorded to the given
+ // SourceLocationTable while parsing. This can be used to look up exact line
+ // and column numbers for errors reported by DescriptorPool during validation.
+ // Set to NULL (the default) to discard source location information.
+ void RecordSourceLocationsTo(SourceLocationTable* location_table) {
+ source_location_table_ = location_table;
+ }
+
+ // Requests that errors be recorded to the given ErrorCollector while
+ // parsing. Set to NULL (the default) to discard error messages.
+ void RecordErrorsTo(io::ErrorCollector* error_collector) {
+ error_collector_ = error_collector;
+ }
+
+ // Returns the identifier used in the "syntax = " declaration, if one was
+ // seen during the last call to Parse(), or the empty string otherwise.
+ const string& GetSyntaxIdentifier() { return syntax_identifier_; }
+
+ // If set true, input files will be required to begin with a syntax
+ // identifier. Otherwise, files may omit this. If a syntax identifier
+ // is provided, it must be 'syntax = "proto2";' and must appear at the
+ // top of this file regardless of whether or not it was required.
+ void SetRequireSyntaxIdentifier(bool value) {
+ require_syntax_identifier_ = value;
+ }
+
+ // Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop
+ // parsing as soon as it has seen the syntax identifier, or lack thereof.
+ // This is useful for quickly identifying the syntax of the file without
+ // parsing the whole thing. If this is enabled, no error will be recorded
+ // if the syntax identifier is something other than "proto2" (since
+ // presumably the caller intends to deal with that), but other kinds of
+ // errors (e.g. parse errors) will still be reported. When this is enabled,
+ // you may pass a NULL FileDescriptorProto to Parse().
+ void SetStopAfterSyntaxIdentifier(bool value) {
+ stop_after_syntax_identifier_ = value;
+ }
+
+ private:
+ // =================================================================
+ // Error recovery helpers
+
+ // Consume the rest of the current statement. This consumes tokens
+ // until it sees one of:
+ // ';' Consumes the token and returns.
+ // '{' Consumes the brace then calls SkipRestOfBlock().
+ // '}' Returns without consuming.
+ // EOF Returns (can't consume).
+ // The Parser often calls SkipStatement() after encountering a syntax
+ // error. This allows it to go on parsing the following lines, allowing
+ // it to report more than just one error in the file.
+ void SkipStatement();
+
+ // Consume the rest of the current block, including nested blocks,
+ // ending after the closing '}' is encountered and consumed, or at EOF.
+ void SkipRestOfBlock();
+
+ // -----------------------------------------------------------------
+ // Single-token consuming helpers
+ //
+ // These make parsing code more readable.
+
+ // True if the current token is TYPE_END.
+ inline bool AtEnd();
+
+ // True if the next token matches the given text.
+ inline bool LookingAt(const char* text);
+ // True if the next token is of the given type.
+ inline bool LookingAtType(io::Tokenizer::TokenType token_type);
+
+ // If the next token exactly matches the text given, consume it and return
+ // true. Otherwise, return false without logging an error.
+ bool TryConsume(const char* text);
+
+ // These attempt to read some kind of token from the input. If successful,
+ // they return true. Otherwise they return false and add the given error
+ // to the error list.
+
+ // Consume a token with the exact text given.
+ bool Consume(const char* text, const char* error);
+ // Same as above, but automatically generates the error "Expected \"text\".",
+ // where "text" is the expected token text.
+ bool Consume(const char* text);
+ // Consume a token of type IDENTIFIER and store its text in "output".
+ bool ConsumeIdentifier(string* output, const char* error);
+ // Consume an integer and store its value in "output".
+ bool ConsumeInteger(int* output, const char* error);
+ // Consume a 64-bit integer and store its value in "output". If the value
+ // is greater than max_value, an error will be reported.
+ bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error);
+ // Consume a number and store its value in "output". This will accept
+ // tokens of either INTEGER or FLOAT type.
+ bool ConsumeNumber(double* output, const char* error);
+ // Consume a string literal and store its (unescaped) value in "output".
+ bool ConsumeString(string* output, const char* error);
+
+ // -----------------------------------------------------------------
+ // Error logging helpers
+
+ // Invokes error_collector_->AddError(), if error_collector_ is not NULL.
+ void AddError(int line, int column, const string& error);
+
+ // Invokes error_collector_->AddError() with the line and column number
+ // of the current token.
+ void AddError(const string& error);
+
+ // Records a location in the SourceCodeInfo.location table (see
+ // descriptor.proto). We use RAII to ensure that the start and end locations
+ // are recorded -- the constructor records the start location and the
+ // destructor records the end location. Since the parser is
+ // recursive-descent, this works out beautifully.
+ class LIBPROTOBUF_EXPORT LocationRecorder {
+ public:
+ // Construct the file's "root" location.
+ LocationRecorder(Parser* parser);
+
+ // Construct a location that represents a declaration nested within the
+ // given parent. E.g. a field's location is nested within the location
+ // for a message type. The parent's path will be copied, so you should
+ // call AddPath() only to add the path components leading from the parent
+ // to the child (as opposed to leading from the root to the child).
+ LocationRecorder(const LocationRecorder& parent);
+
+ // Convenience constructors that call AddPath() one or two times.
+ LocationRecorder(const LocationRecorder& parent, int path1);
+ LocationRecorder(const LocationRecorder& parent, int path1, int path2);
+
+ ~LocationRecorder();
+
+ // Add a path component. See SourceCodeInfo.Location.path in
+ // descriptor.proto.
+ void AddPath(int path_component);
+
+ // By default the location is considered to start at the current token at
+ // the time the LocationRecorder is created. StartAt() sets the start
+ // location to the given token instead.
+ void StartAt(const io::Tokenizer::Token& token);
+
+ // By default the location is considered to end at the previous token at
+ // the time the LocationRecorder is destroyed. EndAt() sets the end
+ // location to the given token instead.
+ void EndAt(const io::Tokenizer::Token& token);
+
+ // Records the start point of this location to the SourceLocationTable that
+ // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable
+ // is an older way of keeping track of source locations which is still
+ // used in some places.
+ void RecordLegacyLocation(const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location);
+
+ private:
+ Parser* parser_;
+ SourceCodeInfo::Location* location_;
+
+ void Init(const LocationRecorder& parent);
+ };
+
+ // =================================================================
+ // Parsers for various language constructs
+
+ // Parses the "syntax = \"proto2\";" line at the top of the file. Returns
+ // false if it failed to parse or if the syntax identifier was not
+ // recognized.
+ bool ParseSyntaxIdentifier();
+
+ // These methods parse various individual bits of code. They return
+ // false if they completely fail to parse the construct. In this case,
+ // it is probably necessary to skip the rest of the statement to recover.
+ // However, if these methods return true, it does NOT mean that there
+ // were no errors; only that there were no *syntax* errors. For instance,
+ // if a service method is defined using proper syntax but uses a primitive
+ // type as its input or output, ParseMethodField() still returns true
+ // and only reports the error by calling AddError(). In practice, this
+ // makes logic much simpler for the caller.
+
+ // Parse a top-level message, enum, service, etc.
+ bool ParseTopLevelStatement(FileDescriptorProto* file,
+ const LocationRecorder& root_location);
+
+ // Parse various language high-level language construrcts.
+ bool ParseMessageDefinition(DescriptorProto* message,
+ const LocationRecorder& message_location);
+ bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location);
+ bool ParseServiceDefinition(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location);
+ bool ParsePackage(FileDescriptorProto* file,
+ const LocationRecorder& root_location);
+ bool ParseImport(string* import_filename,
+ const LocationRecorder& root_location,
+ int index);
+ bool ParseOption(Message* options,
+ const LocationRecorder& options_location);
+
+ // These methods parse the contents of a message, enum, or service type and
+ // add them to the given object. They consume the entire block including
+ // the beginning and ending brace.
+ bool ParseMessageBlock(DescriptorProto* message,
+ const LocationRecorder& message_location);
+ bool ParseEnumBlock(EnumDescriptorProto* enum_type,
+ const LocationRecorder& enum_location);
+ bool ParseServiceBlock(ServiceDescriptorProto* service,
+ const LocationRecorder& service_location);
+
+ // Parse one statement within a message, enum, or service block, inclunding
+ // final semicolon.
+ bool ParseMessageStatement(DescriptorProto* message,
+ const LocationRecorder& message_location);
+ bool ParseEnumStatement(EnumDescriptorProto* message,
+ const LocationRecorder& enum_location);
+ bool ParseServiceStatement(ServiceDescriptorProto* message,
+ const LocationRecorder& service_location);
+
+ // Parse a field of a message. If the field is a group, its type will be
+ // added to "messages".
+ //
+ // parent_location and location_field_number_for_nested_type are needed when
+ // parsing groups -- we need to generate a nested message type within the
+ // parent and record its location accordingly. Since the parent could be
+ // either a FileDescriptorProto or a DescriptorProto, we must pass in the
+ // correct field number to use.
+ bool ParseMessageField(FieldDescriptorProto* field,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& field_location);
+
+ // Parse an "extensions" declaration.
+ bool ParseExtensions(DescriptorProto* message,
+ const LocationRecorder& extensions_location);
+
+ // Parse an "extend" declaration. (See also comments for
+ // ParseMessageField().)
+ bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
+ RepeatedPtrField<DescriptorProto>* messages,
+ const LocationRecorder& parent_location,
+ int location_field_number_for_nested_type,
+ const LocationRecorder& extend_location);
+
+ // Parse a single enum value within an enum block.
+ bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+ const LocationRecorder& enum_value_location);
+
+ // Parse enum constant options, i.e. the list in square brackets at the end
+ // of the enum constant value definition.
+ bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
+ const LocationRecorder& enum_value_location);
+
+ // Parse a single method within a service definition.
+ bool ParseServiceMethod(MethodDescriptorProto* method,
+ const LocationRecorder& method_location);
+
+ // Parse "required", "optional", or "repeated" and fill in "label"
+ // with the value.
+ bool ParseLabel(FieldDescriptorProto::Label* label);
+
+ // Parse a type name and fill in "type" (if it is a primitive) or
+ // "type_name" (if it is not) with the type parsed.
+ bool ParseType(FieldDescriptorProto::Type* type,
+ string* type_name);
+ // Parse a user-defined type and fill in "type_name" with the name.
+ // If a primitive type is named, it is treated as an error.
+ bool ParseUserDefinedType(string* type_name);
+
+ // Parses field options, i.e. the stuff in square brackets at the end
+ // of a field definition. Also parses default value.
+ bool ParseFieldOptions(FieldDescriptorProto* field,
+ const LocationRecorder& field_location);
+
+ // Parse the "default" option. This needs special handling because its
+ // type is the field's type.
+ bool ParseDefaultAssignment(FieldDescriptorProto* field,
+ const LocationRecorder& field_location);
+
+ // Parse a single option name/value pair, e.g. "ctype = CORD". The name
+ // identifies a field of the given Message, and the value of that field
+ // is set to the parsed value.
+ bool ParseOptionAssignment(Message* options,
+ const LocationRecorder& options_location);
+
+ // Parses a single part of a multipart option name. A multipart name consists
+ // of names separated by dots. Each name is either an identifier or a series
+ // of identifiers separated by dots and enclosed in parentheses. E.g.,
+ // "foo.(bar.baz).qux".
+ bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+ const LocationRecorder& part_location);
+
+ // Parses a string surrounded by balanced braces. Strips off the outer
+ // braces and stores the enclosed string in *value.
+ // E.g.,
+ // { foo } *value gets 'foo'
+ // { foo { bar: box } } *value gets 'foo { bar: box }'
+ // {} *value gets ''
+ //
+ // REQUIRES: LookingAt("{")
+ // When finished successfully, we are looking at the first token past
+ // the ending brace.
+ bool ParseUninterpretedBlock(string* value);
+
+ // =================================================================
+
+ io::Tokenizer* input_;
+ io::ErrorCollector* error_collector_;
+ SourceCodeInfo* source_code_info_;
+ SourceLocationTable* source_location_table_; // legacy
+ bool had_errors_;
+ bool require_syntax_identifier_;
+ bool stop_after_syntax_identifier_;
+ string syntax_identifier_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
+};
+
+// A table mapping (descriptor, ErrorLocation) pairs -- as reported by
+// DescriptorPool when validating descriptors -- to line and column numbers
+// within the original source code.
+//
+// This is semi-obsolete: FileDescriptorProto.source_code_info now contains
+// far more complete information about source locations. However, as of this
+// writing you still need to use SourceLocationTable when integrating with
+// DescriptorPool.
+class LIBPROTOBUF_EXPORT SourceLocationTable {
+ public:
+ SourceLocationTable();
+ ~SourceLocationTable();
+
+ // Finds the precise location of the given error and fills in *line and
+ // *column with the line and column numbers. If not found, sets *line to
+ // -1 and *column to 0 (since line = -1 is used to mean "error has no exact
+ // location" in the ErrorCollector interface). Returns true if found, false
+ // otherwise.
+ bool Find(const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ int* line, int* column) const;
+
+ // Adds a location to the table.
+ void Add(const Message* descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ int line, int column);
+
+ // Clears the contents of the table.
+ void Clear();
+
+ private:
+ typedef map<
+ pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
+ pair<int, int> > LocationMap;
+ LocationMap location_map_;
+};
+
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc b/src/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc
new file mode 100644
index 0000000..156c0dc
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc
@@ -0,0 +1,2122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+#include <algorithm>
+#include <map>
+
+#include <google/protobuf/compiler/parser.h>
+
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/map-util.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+class MockErrorCollector : public io::ErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(int line, int column, const string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
+ line, column, message);
+ }
+};
+
+class MockValidationErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+ MockValidationErrorCollector(const SourceLocationTable& source_locations,
+ io::ErrorCollector* wrapped_collector)
+ : source_locations_(source_locations),
+ wrapped_collector_(wrapped_collector) {}
+ ~MockValidationErrorCollector() {}
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const string& filename,
+ const string& element_name,
+ const Message* descriptor,
+ ErrorLocation location,
+ const string& message) {
+ int line, column;
+ source_locations_.Find(descriptor, location, &line, &column);
+ wrapped_collector_->AddError(line, column, message);
+ }
+
+ private:
+ const SourceLocationTable& source_locations_;
+ io::ErrorCollector* wrapped_collector_;
+};
+
+class ParserTest : public testing::Test {
+ protected:
+ ParserTest()
+ : require_syntax_identifier_(false) {}
+
+ // Set up the parser to parse the given text.
+ void SetupParser(const char* text) {
+ raw_input_.reset(new io::ArrayInputStream(text, strlen(text)));
+ input_.reset(new io::Tokenizer(raw_input_.get(), &error_collector_));
+ parser_.reset(new Parser());
+ parser_->RecordErrorsTo(&error_collector_);
+ parser_->SetRequireSyntaxIdentifier(require_syntax_identifier_);
+ }
+
+ // Parse the input and expect that the resulting FileDescriptorProto matches
+ // the given output. The output is a FileDescriptorProto in protocol buffer
+ // text format.
+ void ExpectParsesTo(const char* input, const char* output) {
+ SetupParser(input);
+ FileDescriptorProto actual, expected;
+
+ parser_->Parse(input_.get(), &actual);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_);
+
+ // We don't cover SourceCodeInfo in these tests.
+ actual.clear_source_code_info();
+
+ // Parse the ASCII representation in order to canonicalize it. We could
+ // just compare directly to actual.DebugString(), but that would require
+ // that the caller precisely match the formatting that DebugString()
+ // produces.
+ ASSERT_TRUE(TextFormat::ParseFromString(output, &expected));
+
+ // Compare by comparing debug strings.
+ // TODO(kenton): Use differencer, once it is available.
+ EXPECT_EQ(expected.DebugString(), actual.DebugString());
+ }
+
+ // Parse the text and expect that the given errors are reported.
+ void ExpectHasErrors(const char* text, const char* expected_errors) {
+ ExpectHasEarlyExitErrors(text, expected_errors);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ }
+
+ // Same as above but does not expect that the parser parses the complete
+ // input.
+ void ExpectHasEarlyExitErrors(const char* text, const char* expected_errors) {
+ SetupParser(text);
+ FileDescriptorProto file;
+ parser_->Parse(input_.get(), &file);
+ EXPECT_EQ(expected_errors, error_collector_.text_);
+ }
+
+ // Parse the text as a file and validate it (with a DescriptorPool), and
+ // expect that the validation step reports the given errors.
+ void ExpectHasValidationErrors(const char* text,
+ const char* expected_errors) {
+ SetupParser(text);
+ SourceLocationTable source_locations;
+ parser_->RecordSourceLocationsTo(&source_locations);
+
+ FileDescriptorProto file;
+ file.set_name("foo.proto");
+ parser_->Parse(input_.get(), &file);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_);
+
+ MockValidationErrorCollector validation_error_collector(
+ source_locations, &error_collector_);
+ EXPECT_TRUE(pool_.BuildFileCollectingErrors(
+ file, &validation_error_collector) == NULL);
+ EXPECT_EQ(expected_errors, error_collector_.text_);
+ }
+
+ MockErrorCollector error_collector_;
+ DescriptorPool pool_;
+
+ scoped_ptr<io::ZeroCopyInputStream> raw_input_;
+ scoped_ptr<io::Tokenizer> input_;
+ scoped_ptr<Parser> parser_;
+ bool require_syntax_identifier_;
+};
+
+// ===================================================================
+
+TEST_F(ParserTest, StopAfterSyntaxIdentifier) {
+ SetupParser(
+ "// blah\n"
+ "syntax = \"foobar\";\n"
+ "this line will not be parsed\n");
+ parser_->SetStopAfterSyntaxIdentifier(true);
+ EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
+ EXPECT_EQ("", error_collector_.text_);
+ EXPECT_EQ("foobar", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParserTest, StopAfterOmittedSyntaxIdentifier) {
+ SetupParser(
+ "// blah\n"
+ "this line will not be parsed\n");
+ parser_->SetStopAfterSyntaxIdentifier(true);
+ EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
+ EXPECT_EQ("", error_collector_.text_);
+ EXPECT_EQ("", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) {
+ SetupParser(
+ "// blah\n"
+ "syntax = error;\n");
+ parser_->SetStopAfterSyntaxIdentifier(true);
+ EXPECT_FALSE(parser_->Parse(input_.get(), NULL));
+ EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_);
+}
+
+// ===================================================================
+
+typedef ParserTest ParseMessageTest;
+
+TEST_F(ParseMessageTest, SimpleMessage) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, ImplicitSyntaxIdentifier) {
+ require_syntax_identifier_ = false;
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+ EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseMessageTest, ExplicitSyntaxIdentifier) {
+ ExpectParsesTo(
+ "syntax = \"proto2\";\n"
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+ EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseMessageTest, ExplicitRequiredSyntaxIdentifier) {
+ require_syntax_identifier_ = true;
+ ExpectParsesTo(
+ "syntax = \"proto2\";\n"
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ "}");
+ EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseMessageTest, SimpleFields) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 15;\n"
+ " optional int32 bar = 34;\n"
+ " repeated int32 baz = 3;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:15 }"
+ " field { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:34 }"
+ " field { name:\"baz\" label:LABEL_REPEATED type:TYPE_INT32 number:3 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, PrimitiveFieldTypes) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1;\n"
+ " required int64 foo = 1;\n"
+ " required uint32 foo = 1;\n"
+ " required uint64 foo = 1;\n"
+ " required sint32 foo = 1;\n"
+ " required sint64 foo = 1;\n"
+ " required fixed32 foo = 1;\n"
+ " required fixed64 foo = 1;\n"
+ " required sfixed32 foo = 1;\n"
+ " required sfixed64 foo = 1;\n"
+ " required float foo = 1;\n"
+ " required double foo = 1;\n"
+ " required string foo = 1;\n"
+ " required bytes foo = 1;\n"
+ " required bool foo = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT32 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_INT64 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT32 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_UINT64 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT32 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SINT64 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED32 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FIXED64 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED32 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_SFIXED64 number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_FLOAT number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_DOUBLE number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_STRING number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BYTES number:1 }"
+ " field { name:\"foo\" label:LABEL_REQUIRED type:TYPE_BOOL number:1 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, FieldDefaults) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " required int32 foo = 1 [default= 1 ];\n"
+ " required int32 foo = 1 [default= -2 ];\n"
+ " required int64 foo = 1 [default= 3 ];\n"
+ " required int64 foo = 1 [default= -4 ];\n"
+ " required uint32 foo = 1 [default= 5 ];\n"
+ " required uint64 foo = 1 [default= 6 ];\n"
+ " required float foo = 1 [default= 7.5];\n"
+ " required float foo = 1 [default= -8.5];\n"
+ " required float foo = 1 [default= 9 ];\n"
+ " required double foo = 1 [default= 10.5];\n"
+ " required double foo = 1 [default=-11.5];\n"
+ " required double foo = 1 [default= 12 ];\n"
+ " required double foo = 1 [default= inf ];\n"
+ " required double foo = 1 [default=-inf ];\n"
+ " required double foo = 1 [default= nan ];\n"
+ " required string foo = 1 [default='13\\001'];\n"
+ " required string foo = 1 [default='a' \"b\" \n \"c\"];\n"
+ " required bytes foo = 1 [default='14\\002'];\n"
+ " required bytes foo = 1 [default='a' \"b\" \n 'c'];\n"
+ " required bool foo = 1 [default=true ];\n"
+ " required Foo foo = 1 [default=FOO ];\n"
+
+ " required int32 foo = 1 [default= 0x7FFFFFFF];\n"
+ " required int32 foo = 1 [default=-0x80000000];\n"
+ " required uint32 foo = 1 [default= 0xFFFFFFFF];\n"
+ " required int64 foo = 1 [default= 0x7FFFFFFFFFFFFFFF];\n"
+ " required int64 foo = 1 [default=-0x8000000000000000];\n"
+ " required uint64 foo = 1 [default= 0xFFFFFFFFFFFFFFFF];\n"
+ " required double foo = 1 [default= 0xabcd];\n"
+ "}\n",
+
+#define ETC "name:\"foo\" label:LABEL_REQUIRED number:1"
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { type:TYPE_INT32 default_value:\"1\" "ETC" }"
+ " field { type:TYPE_INT32 default_value:\"-2\" "ETC" }"
+ " field { type:TYPE_INT64 default_value:\"3\" "ETC" }"
+ " field { type:TYPE_INT64 default_value:\"-4\" "ETC" }"
+ " field { type:TYPE_UINT32 default_value:\"5\" "ETC" }"
+ " field { type:TYPE_UINT64 default_value:\"6\" "ETC" }"
+ " field { type:TYPE_FLOAT default_value:\"7.5\" "ETC" }"
+ " field { type:TYPE_FLOAT default_value:\"-8.5\" "ETC" }"
+ " field { type:TYPE_FLOAT default_value:\"9\" "ETC" }"
+ " field { type:TYPE_DOUBLE default_value:\"10.5\" "ETC" }"
+ " field { type:TYPE_DOUBLE default_value:\"-11.5\" "ETC" }"
+ " field { type:TYPE_DOUBLE default_value:\"12\" "ETC" }"
+ " field { type:TYPE_DOUBLE default_value:\"inf\" "ETC" }"
+ " field { type:TYPE_DOUBLE default_value:\"-inf\" "ETC" }"
+ " field { type:TYPE_DOUBLE default_value:\"nan\" "ETC" }"
+ " field { type:TYPE_STRING default_value:\"13\\001\" "ETC" }"
+ " field { type:TYPE_STRING default_value:\"abc\" "ETC" }"
+ " field { type:TYPE_BYTES default_value:\"14\\\\002\" "ETC" }"
+ " field { type:TYPE_BYTES default_value:\"abc\" "ETC" }"
+ " field { type:TYPE_BOOL default_value:\"true\" "ETC" }"
+ " field { type_name:\"Foo\" default_value:\"FOO\" "ETC" }"
+
+ " field { type:TYPE_INT32 default_value:\"2147483647\" "ETC" }"
+ " field { type:TYPE_INT32 default_value:\"-2147483648\" "ETC" }"
+ " field { type:TYPE_UINT32 default_value:\"4294967295\" "ETC" }"
+ " field { type:TYPE_INT64 default_value:\"9223372036854775807\" "ETC" }"
+ " field { type:TYPE_INT64 default_value:\"-9223372036854775808\" "ETC" }"
+ " field { type:TYPE_UINT64 default_value:\"18446744073709551615\" "ETC" }"
+ " field { type:TYPE_DOUBLE default_value:\"43981\" "ETC" }"
+ "}");
+#undef ETC
+}
+
+TEST_F(ParseMessageTest, FieldOptions) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " optional string foo = 1\n"
+ " [ctype=CORD, (foo)=7, foo.(.bar.baz).qux.quux.(corge)=-33, \n"
+ " (quux)=\"x\040y\", (baz.qux)=hey];\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: 1"
+ " options { uninterpreted_option: { name { name_part: \"ctype\" "
+ " is_extension: false } "
+ " identifier_value: \"CORD\" }"
+ " uninterpreted_option: { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " positive_int_value: 7 }"
+ " uninterpreted_option: { name { name_part: \"foo\" "
+ " is_extension: false } "
+ " name { name_part: \".bar.baz\""
+ " is_extension: true } "
+ " name { name_part: \"qux\" "
+ " is_extension: false } "
+ " name { name_part: \"quux\" "
+ " is_extension: false } "
+ " name { name_part: \"corge\" "
+ " is_extension: true } "
+ " negative_int_value: -33 }"
+ " uninterpreted_option: { name { name_part: \"quux\" "
+ " is_extension: true } "
+ " string_value: \"x y\" }"
+ " uninterpreted_option: { name { name_part: \"baz.qux\" "
+ " is_extension: true } "
+ " identifier_value: \"hey\" }"
+ " }"
+ " }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, Group) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " optional group TestGroup = 1 {};\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " nested_type { name: \"TestGroup\" }"
+ " field { name:\"testgroup\" label:LABEL_OPTIONAL number:1"
+ " type:TYPE_GROUP type_name: \"TestGroup\" }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, NestedMessage) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " message Nested {}\n"
+ " optional Nested test_nested = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " nested_type { name: \"Nested\" }"
+ " field { name:\"test_nested\" label:LABEL_OPTIONAL number:1"
+ " type_name: \"Nested\" }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, NestedEnum) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " enum NestedEnum {}\n"
+ " optional NestedEnum test_enum = 1;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " enum_type { name: \"NestedEnum\" }"
+ " field { name:\"test_enum\" label:LABEL_OPTIONAL number:1"
+ " type_name: \"NestedEnum\" }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, ExtensionRange) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extensions 10 to 19;\n"
+ " extensions 30 to max;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension_range { start:10 end:20 }"
+ " extension_range { start:30 end:536870912 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, CompoundExtensionRange) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extensions 2, 15, 9 to 11, 100 to max, 3;\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension_range { start:2 end:3 }"
+ " extension_range { start:15 end:16 }"
+ " extension_range { start:9 end:12 }"
+ " extension_range { start:100 end:536870912 }"
+ " extension_range { start:3 end:4 }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, Extensions) {
+ ExpectParsesTo(
+ "extend Extendee1 { optional int32 foo = 12; }\n"
+ "extend Extendee2 { repeated TestMessage bar = 22; }\n",
+
+ "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
+ " extendee: \"Extendee1\" } "
+ "extension { name:\"bar\" label:LABEL_REPEATED number:22"
+ " type_name:\"TestMessage\" extendee: \"Extendee2\" }");
+}
+
+TEST_F(ParseMessageTest, ExtensionsInMessageScope) {
+ ExpectParsesTo(
+ "message TestMessage {\n"
+ " extend Extendee1 { optional int32 foo = 12; }\n"
+ " extend Extendee2 { repeated TestMessage bar = 22; }\n"
+ "}\n",
+
+ "message_type {"
+ " name: \"TestMessage\""
+ " extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
+ " extendee: \"Extendee1\" }"
+ " extension { name:\"bar\" label:LABEL_REPEATED number:22"
+ " type_name:\"TestMessage\" extendee: \"Extendee2\" }"
+ "}");
+}
+
+TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) {
+ ExpectParsesTo(
+ "extend Extendee1 {\n"
+ " optional int32 foo = 12;\n"
+ " repeated TestMessage bar = 22;\n"
+ "}\n",
+
+ "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:12"
+ " extendee: \"Extendee1\" } "
+ "extension { name:\"bar\" label:LABEL_REPEATED number:22"
+ " type_name:\"TestMessage\" extendee: \"Extendee1\" }");
+}
+
+// ===================================================================
+
+typedef ParserTest ParseEnumTest;
+
+TEST_F(ParseEnumTest, SimpleEnum) {
+ ExpectParsesTo(
+ "enum TestEnum {\n"
+ " FOO = 0;\n"
+ "}\n",
+
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"FOO\" number:0 }"
+ "}");
+}
+
+TEST_F(ParseEnumTest, Values) {
+ ExpectParsesTo(
+ "enum TestEnum {\n"
+ " FOO = 13;\n"
+ " BAR = -10;\n"
+ " BAZ = 500;\n"
+ "}\n",
+
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"FOO\" number:13 }"
+ " value { name:\"BAR\" number:-10 }"
+ " value { name:\"BAZ\" number:500 }"
+ "}");
+}
+
+TEST_F(ParseEnumTest, ValueOptions) {
+ ExpectParsesTo(
+ "enum TestEnum {\n"
+ " FOO = 13;\n"
+ " BAR = -10 [ (something.text) = 'abc' ];\n"
+ " BAZ = 500 [ (something.text) = 'def', other = 1 ];\n"
+ "}\n",
+
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name: \"FOO\" number: 13 }"
+ " value { name: \"BAR\" number: -10 "
+ " options { "
+ " uninterpreted_option { "
+ " name { name_part: \"something.text\" is_extension: true } "
+ " string_value: \"abc\" "
+ " } "
+ " } "
+ " } "
+ " value { name: \"BAZ\" number: 500 "
+ " options { "
+ " uninterpreted_option { "
+ " name { name_part: \"something.text\" is_extension: true } "
+ " string_value: \"def\" "
+ " } "
+ " uninterpreted_option { "
+ " name { name_part: \"other\" is_extension: false } "
+ " positive_int_value: 1 "
+ " } "
+ " } "
+ " } "
+ "}");
+}
+
+// ===================================================================
+
+typedef ParserTest ParseServiceTest;
+
+TEST_F(ParseServiceTest, SimpleService) {
+ ExpectParsesTo(
+ "service TestService {\n"
+ " rpc Foo(In) returns (Out);\n"
+ "}\n",
+
+ "service {"
+ " name: \"TestService\""
+ " method { name:\"Foo\" input_type:\"In\" output_type:\"Out\" }"
+ "}");
+}
+
+TEST_F(ParseServiceTest, Methods) {
+ ExpectParsesTo(
+ "service TestService {\n"
+ " rpc Foo(In1) returns (Out1);\n"
+ " rpc Bar(In2) returns (Out2);\n"
+ " rpc Baz(In3) returns (Out3);\n"
+ "}\n",
+
+ "service {"
+ " name: \"TestService\""
+ " method { name:\"Foo\" input_type:\"In1\" output_type:\"Out1\" }"
+ " method { name:\"Bar\" input_type:\"In2\" output_type:\"Out2\" }"
+ " method { name:\"Baz\" input_type:\"In3\" output_type:\"Out3\" }"
+ "}");
+}
+
+// ===================================================================
+// imports and packages
+
+typedef ParserTest ParseMiscTest;
+
+TEST_F(ParseMiscTest, ParseImport) {
+ ExpectParsesTo(
+ "import \"foo/bar/baz.proto\";\n",
+ "dependency: \"foo/bar/baz.proto\"");
+}
+
+TEST_F(ParseMiscTest, ParseMultipleImports) {
+ ExpectParsesTo(
+ "import \"foo.proto\";\n"
+ "import \"bar.proto\";\n"
+ "import \"baz.proto\";\n",
+ "dependency: \"foo.proto\""
+ "dependency: \"bar.proto\""
+ "dependency: \"baz.proto\"");
+}
+
+TEST_F(ParseMiscTest, ParsePackage) {
+ ExpectParsesTo(
+ "package foo.bar.baz;\n",
+ "package: \"foo.bar.baz\"");
+}
+
+TEST_F(ParseMiscTest, ParsePackageWithSpaces) {
+ ExpectParsesTo(
+ "package foo . bar. \n"
+ " baz;\n",
+ "package: \"foo.bar.baz\"");
+}
+
+// ===================================================================
+// options
+
+TEST_F(ParseMiscTest, ParseFileOptions) {
+ ExpectParsesTo(
+ "option java_package = \"com.google.foo\";\n"
+ "option optimize_for = CODE_SIZE;",
+
+ "options {"
+ "uninterpreted_option { name { name_part: \"java_package\" "
+ " is_extension: false }"
+ " string_value: \"com.google.foo\"} "
+ "uninterpreted_option { name { name_part: \"optimize_for\" "
+ " is_extension: false }"
+ " identifier_value: \"CODE_SIZE\" } "
+ "}");
+}
+
+// ===================================================================
+// Error tests
+//
+// There are a very large number of possible errors that the parser could
+// report, so it's infeasible to test every single one of them. Instead,
+// we test each unique call to AddError() in parser.h. This does not mean
+// we are testing every possible error that Parser can generate because
+// each variant of the Consume() helper only counts as one unique call to
+// AddError().
+
+typedef ParserTest ParseErrorTest;
+
+TEST_F(ParseErrorTest, MissingSyntaxIdentifier) {
+ require_syntax_identifier_ = true;
+ ExpectHasEarlyExitErrors(
+ "message TestMessage {}",
+ "0:0: File must begin with 'syntax = \"proto2\";'.\n");
+ EXPECT_EQ("", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseErrorTest, UnknownSyntaxIdentifier) {
+ ExpectHasEarlyExitErrors(
+ "syntax = \"no_such_syntax\";",
+ "0:9: Unrecognized syntax identifier \"no_such_syntax\". This parser "
+ "only recognizes \"proto2\".\n");
+ EXPECT_EQ("no_such_syntax", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseErrorTest, SimpleSyntaxError) {
+ ExpectHasErrors(
+ "message TestMessage @#$ { blah }",
+ "0:20: Expected \"{\".\n");
+ EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseErrorTest, ExpectedTopLevel) {
+ ExpectHasErrors(
+ "blah;",
+ "0:0: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(ParseErrorTest, UnmatchedCloseBrace) {
+ // This used to cause an infinite loop. Doh.
+ ExpectHasErrors(
+ "}",
+ "0:0: Expected top-level statement (e.g. \"message\").\n"
+ "0:0: Unmatched \"}\".\n");
+}
+
+// -------------------------------------------------------------------
+// Message errors
+
+TEST_F(ParseErrorTest, MessageMissingName) {
+ ExpectHasErrors(
+ "message {}",
+ "0:8: Expected message name.\n");
+}
+
+TEST_F(ParseErrorTest, MessageMissingBody) {
+ ExpectHasErrors(
+ "message TestMessage;",
+ "0:19: Expected \"{\".\n");
+}
+
+TEST_F(ParseErrorTest, EofInMessage) {
+ ExpectHasErrors(
+ "message TestMessage {",
+ "0:21: Reached end of input in message definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, MissingFieldNumber) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo;\n"
+ "}\n",
+ "1:20: Missing field number.\n");
+}
+
+TEST_F(ParseErrorTest, ExpectedFieldNumber) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo = ;\n"
+ "}\n",
+ "1:23: Expected field number.\n");
+}
+
+TEST_F(ParseErrorTest, FieldNumberOutOfRange) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo = 0x100000000;\n"
+ "}\n",
+ "1:23: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, MissingLabel) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " int32 foo = 1;\n"
+ "}\n",
+ "1:2: Expected \"required\", \"optional\", or \"repeated\".\n");
+}
+
+TEST_F(ParseErrorTest, ExpectedOptionName) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [];\n"
+ "}\n",
+ "1:27: Expected identifier.\n");
+}
+
+TEST_F(ParseErrorTest, NonExtensionOptionNameBeginningWithDot) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [.foo=1];\n"
+ "}\n",
+ "1:27: Expected identifier.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueTypeMismatch) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [default=true];\n"
+ "}\n",
+ "1:35: Expected integer.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueNotBoolean) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional bool foo = 1 [default=blah];\n"
+ "}\n",
+ "1:33: Expected \"true\" or \"false\".\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueNotString) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional string foo = 1 [default=1];\n"
+ "}\n",
+ "1:35: Expected string.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueUnsignedNegative) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [default=-1];\n"
+ "}\n",
+ "1:36: Unsigned field can't have negative default value.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueTooLarge) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo = 1 [default= 0x80000000];\n"
+ " optional int32 foo = 1 [default=-0x80000001];\n"
+ " optional uint32 foo = 1 [default= 0x100000000];\n"
+ " optional int64 foo = 1 [default= 0x80000000000000000];\n"
+ " optional int64 foo = 1 [default=-0x80000000000000001];\n"
+ " optional uint64 foo = 1 [default= 0x100000000000000000];\n"
+ "}\n",
+ "1:36: Integer out of range.\n"
+ "2:36: Integer out of range.\n"
+ "3:36: Integer out of range.\n"
+ "4:36: Integer out of range.\n"
+ "5:36: Integer out of range.\n"
+ "6:36: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueMissing) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [default=];\n"
+ "}\n",
+ "1:35: Expected integer.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueForGroup) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional group Foo = 1 [default=blah] {}\n"
+ "}\n",
+ "1:34: Messages can't have default values.\n");
+}
+
+TEST_F(ParseErrorTest, DuplicateDefaultValue) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional uint32 foo = 1 [default=1,default=2];\n"
+ "}\n",
+ "1:37: Already set option \"default\".\n");
+}
+
+TEST_F(ParseErrorTest, GroupNotCapitalized) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional group foo = 1 {}\n"
+ "}\n",
+ "1:17: Group names must start with a capital letter.\n");
+}
+
+TEST_F(ParseErrorTest, GroupMissingBody) {
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional group Foo = 1;\n"
+ "}\n",
+ "1:24: Missing group body.\n");
+}
+
+TEST_F(ParseErrorTest, ExtendingPrimitive) {
+ ExpectHasErrors(
+ "extend int32 { optional string foo = 4; }\n",
+ "0:7: Expected message type.\n");
+}
+
+TEST_F(ParseErrorTest, ErrorInExtension) {
+ ExpectHasErrors(
+ "message Foo { extensions 100 to 199; }\n"
+ "extend Foo { optional string foo; }\n",
+ "1:32: Missing field number.\n");
+}
+
+TEST_F(ParseErrorTest, MultipleParseErrors) {
+ // When a statement has a parse error, the parser should be able to continue
+ // parsing at the next statement.
+ ExpectHasErrors(
+ "message TestMessage {\n"
+ " optional int32 foo;\n"
+ " !invalid statement ending in a block { blah blah { blah } blah }\n"
+ " optional int32 bar = 3 {}\n"
+ "}\n",
+ "1:20: Missing field number.\n"
+ "2:2: Expected \"required\", \"optional\", or \"repeated\".\n"
+ "2:2: Expected type name.\n"
+ "3:25: Expected \";\".\n");
+}
+
+TEST_F(ParseErrorTest, EofInAggregateValue) {
+ ExpectHasErrors(
+ "option (fileopt) = { i:100\n",
+ "1:0: Unexpected end of stream while parsing aggregate value.\n");
+}
+
+// -------------------------------------------------------------------
+// Enum errors
+
+TEST_F(ParseErrorTest, EofInEnum) {
+ ExpectHasErrors(
+ "enum TestEnum {",
+ "0:15: Reached end of input in enum definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, EnumValueMissingNumber) {
+ ExpectHasErrors(
+ "enum TestEnum {\n"
+ " FOO;\n"
+ "}\n",
+ "1:5: Missing numeric value for enum constant.\n");
+}
+
+// -------------------------------------------------------------------
+// Service errors
+
+TEST_F(ParseErrorTest, EofInService) {
+ ExpectHasErrors(
+ "service TestService {",
+ "0:21: Reached end of input in service definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, ServiceMethodPrimitiveParams) {
+ ExpectHasErrors(
+ "service TestService {\n"
+ " rpc Foo(int32) returns (string);\n"
+ "}\n",
+ "1:10: Expected message type.\n"
+ "1:26: Expected message type.\n");
+}
+
+TEST_F(ParseErrorTest, EofInMethodOptions) {
+ ExpectHasErrors(
+ "service TestService {\n"
+ " rpc Foo(Bar) returns(Bar) {",
+ "1:29: Reached end of input in method options (missing '}').\n"
+ "1:29: Reached end of input in service definition (missing '}').\n");
+}
+
+TEST_F(ParseErrorTest, PrimitiveMethodInput) {
+ ExpectHasErrors(
+ "service TestService {\n"
+ " rpc Foo(int32) returns(Bar);\n"
+ "}\n",
+ "1:10: Expected message type.\n");
+}
+
+TEST_F(ParseErrorTest, MethodOptionTypeError) {
+ // This used to cause an infinite loop.
+ ExpectHasErrors(
+ "message Baz {}\n"
+ "service Foo {\n"
+ " rpc Bar(Baz) returns(Baz) { option invalid syntax; }\n"
+ "}\n",
+ "2:45: Expected \"=\".\n");
+}
+
+// -------------------------------------------------------------------
+// Import and package errors
+
+TEST_F(ParseErrorTest, ImportNotQuoted) {
+ ExpectHasErrors(
+ "import foo;\n",
+ "0:7: Expected a string naming the file to import.\n");
+}
+
+TEST_F(ParseErrorTest, MultiplePackagesInFile) {
+ ExpectHasErrors(
+ "package foo;\n"
+ "package bar;\n",
+ "1:0: Multiple package definitions.\n");
+}
+
+// ===================================================================
+// Test that errors detected by DescriptorPool correctly report line and
+// column numbers. We have one test for every call to RecordLocation() in
+// parser.cc.
+
+typedef ParserTest ParserValidationErrorTest;
+
+TEST_F(ParserValidationErrorTest, PackageNameError) {
+ // Create another file which defines symbol "foo".
+ FileDescriptorProto other_file;
+ other_file.set_name("bar.proto");
+ other_file.add_message_type()->set_name("foo");
+ EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+ // Now try to define it as a package.
+ ExpectHasValidationErrors(
+ "package foo.bar;",
+ "0:8: \"foo\" is already defined (as something other than a package) "
+ "in file \"bar.proto\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, MessageNameError) {
+ ExpectHasValidationErrors(
+ "message Foo {}\n"
+ "message Foo {}\n",
+ "1:8: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldNameError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional int32 bar = 1;\n"
+ " optional int32 bar = 2;\n"
+ "}\n",
+ "2:17: \"bar\" is already defined in \"Foo\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldTypeError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional Baz bar = 1;\n"
+ "}\n",
+ "1:11: \"Baz\" is not defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldNumberError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional int32 bar = 0;\n"
+ "}\n",
+ "1:23: Field numbers must be positive integers.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldExtendeeError) {
+ ExpectHasValidationErrors(
+ "extend Baz { optional int32 bar = 1; }\n",
+ "0:7: \"Baz\" is not defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldDefaultValueError) {
+ ExpectHasValidationErrors(
+ "enum Baz { QUX = 1; }\n"
+ "message Foo {\n"
+ " optional Baz bar = 1 [default=NO_SUCH_VALUE];\n"
+ "}\n",
+ "2:32: Enum type \"Baz\" has no value named \"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, FileOptionNameError) {
+ ExpectHasValidationErrors(
+ "option foo = 5;",
+ "0:7: Option \"foo\" unknown.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FileOptionValueError) {
+ ExpectHasValidationErrors(
+ "option java_outer_classname = 5;",
+ "0:30: Value must be quoted string for string option "
+ "\"google.protobuf.FileOptions.java_outer_classname\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldOptionNameError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional bool bar = 1 [foo=1];\n"
+ "}\n",
+ "1:25: Option \"foo\" unknown.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldOptionValueError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " optional int32 bar = 1 [ctype=1];\n"
+ "}\n",
+ "1:32: Value must be identifier for enum-valued option "
+ "\"google.protobuf.FieldOptions.ctype\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, ExtensionRangeNumberError) {
+ ExpectHasValidationErrors(
+ "message Foo {\n"
+ " extensions 0;\n"
+ "}\n",
+ "1:13: Extension numbers must be positive integers.\n");
+}
+
+TEST_F(ParserValidationErrorTest, EnumNameError) {
+ ExpectHasValidationErrors(
+ "enum Foo {A = 1;}\n"
+ "enum Foo {B = 1;}\n",
+ "1:5: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, EnumValueNameError) {
+ ExpectHasValidationErrors(
+ "enum Foo {\n"
+ " BAR = 1;\n"
+ " BAR = 1;\n"
+ "}\n",
+ "2:2: \"BAR\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ServiceNameError) {
+ ExpectHasValidationErrors(
+ "service Foo {}\n"
+ "service Foo {}\n",
+ "1:8: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, MethodNameError) {
+ ExpectHasValidationErrors(
+ "message Baz {}\n"
+ "service Foo {\n"
+ " rpc Bar(Baz) returns(Baz);\n"
+ " rpc Bar(Baz) returns(Baz);\n"
+ "}\n",
+ "3:6: \"Bar\" is already defined in \"Foo\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, MethodInputTypeError) {
+ ExpectHasValidationErrors(
+ "message Baz {}\n"
+ "service Foo {\n"
+ " rpc Bar(Qux) returns(Baz);\n"
+ "}\n",
+ "2:10: \"Qux\" is not defined.\n");
+}
+
+TEST_F(ParserValidationErrorTest, MethodOutputTypeError) {
+ ExpectHasValidationErrors(
+ "message Baz {}\n"
+ "service Foo {\n"
+ " rpc Bar(Baz) returns(Qux);\n"
+ "}\n",
+ "2:23: \"Qux\" is not defined.\n");
+}
+
+// ===================================================================
+// Test that the output from FileDescriptor::DebugString() (and all other
+// descriptor types) is parseable, and results in the same Descriptor
+// definitions again afoter parsing (not, however, that the order of messages
+// cannot be guaranteed to be the same)
+
+typedef ParserTest ParseDecriptorDebugTest;
+
+class CompareDescriptorNames {
+ public:
+ bool operator()(const DescriptorProto* left, const DescriptorProto* right) {
+ return left->name() < right->name();
+ }
+};
+
+// Sorts nested DescriptorProtos of a DescriptoProto, by name.
+void SortMessages(DescriptorProto *descriptor_proto) {
+ int size = descriptor_proto->nested_type_size();
+ // recursively sort; we can't guarantee the order of nested messages either
+ for (int i = 0; i < size; ++i) {
+ SortMessages(descriptor_proto->mutable_nested_type(i));
+ }
+ DescriptorProto **data =
+ descriptor_proto->mutable_nested_type()->mutable_data();
+ sort(data, data + size, CompareDescriptorNames());
+}
+
+// Sorts DescriptorProtos belonging to a FileDescriptorProto, by name.
+void SortMessages(FileDescriptorProto *file_descriptor_proto) {
+ int size = file_descriptor_proto->message_type_size();
+ // recursively sort; we can't guarantee the order of nested messages either
+ for (int i = 0; i < size; ++i) {
+ SortMessages(file_descriptor_proto->mutable_message_type(i));
+ }
+ DescriptorProto **data =
+ file_descriptor_proto->mutable_message_type()->mutable_data();
+ sort(data, data + size, CompareDescriptorNames());
+}
+
+TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) {
+ const FileDescriptor* original_file =
+ protobuf_unittest::TestAllTypes::descriptor()->file();
+ FileDescriptorProto expected;
+ original_file->CopyTo(&expected);
+
+ // Get the DebugString of the unittest.proto FileDecriptor, which includes
+ // all other descriptor types
+ string debug_string = original_file->DebugString();
+
+ // Parse the debug string
+ SetupParser(debug_string.c_str());
+ FileDescriptorProto parsed;
+ parser_->Parse(input_.get(), &parsed);
+ EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type);
+ ASSERT_EQ("", error_collector_.text_);
+
+ // We now have a FileDescriptorProto, but to compare with the expected we
+ // need to link to a FileDecriptor, then output back to a proto. We'll
+ // also need to give it the same name as the original.
+ parsed.set_name("google/protobuf/unittest.proto");
+ // We need the imported dependency before we can build our parsed proto
+ const FileDescriptor* import =
+ protobuf_unittest_import::ImportMessage::descriptor()->file();
+ FileDescriptorProto import_proto;
+ import->CopyTo(&import_proto);
+ ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
+ const FileDescriptor* actual = pool_.BuildFile(parsed);
+ parsed.Clear();
+ actual->CopyTo(&parsed);
+ ASSERT_TRUE(actual != NULL);
+
+ // The messages might be in different orders, making them hard to compare.
+ // So, sort the messages in the descriptor protos (including nested messages,
+ // recursively).
+ SortMessages(&expected);
+ SortMessages(&parsed);
+
+ // I really wanted to use StringDiff here for the debug output on fail,
+ // but the strings are too long for it, and if I increase its max size,
+ // we get a memory allocation failure :(
+ EXPECT_EQ(expected.DebugString(), parsed.DebugString());
+}
+
+// ===================================================================
+// SourceCodeInfo tests.
+
+// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
+// message to a particular sub-field.
+// * If the target is itself a message, sets *output_message to point at it,
+// *output_field to NULL, and *output_index to -1.
+// * Otherwise, if the target is an element of a repeated field, sets
+// *output_message to the containing message, *output_field to the descriptor
+// of the field, and *output_index to the index of the element.
+// * Otherwise, the target is a field (possibly a repeated field, but not any
+// one element). Sets *output_message to the containing message,
+// *output_field to the descriptor of the field, and *output_index to -1.
+// Returns true if the path was valid, false otherwise. A gTest failure is
+// recorded before returning false.
+bool FollowPath(const Message& root,
+ const int* path_begin, const int* path_end,
+ const Message** output_message,
+ const FieldDescriptor** output_field,
+ int* output_index) {
+ if (path_begin == path_end) {
+ // Path refers to this whole message.
+ *output_message = &root;
+ *output_field = NULL;
+ *output_index = -1;
+ return true;
+ }
+
+ const Descriptor* descriptor = root.GetDescriptor();
+ const Reflection* reflection = root.GetReflection();
+
+ const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin);
+
+ if (field == NULL) {
+ ADD_FAILURE() << descriptor->name() << " has no field number: "
+ << *path_begin;
+ return false;
+ }
+
+ ++path_begin;
+
+ if (field->is_repeated()) {
+ if (path_begin == path_end) {
+ // Path refers to the whole repeated field.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = -1;
+ return true;
+ }
+
+ int index = *path_begin++;
+ int size = reflection->FieldSize(root, field);
+
+ if (index >= size) {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " has size " << size << ", but path contained index: "
+ << index;
+ return false;
+ }
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Descend into child message.
+ const Message& child = reflection->GetRepeatedMessage(root, field, index);
+ return FollowPath(child, path_begin, path_end,
+ output_message, output_field, output_index);
+ } else if (path_begin == path_end) {
+ // Path refers to this element.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = index;
+ return true;
+ } else {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " is not a message; cannot descend into it.";
+ return false;
+ }
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ const Message& child = reflection->GetMessage(root, field);
+ return FollowPath(child, path_begin, path_end,
+ output_message, output_field, output_index);
+ } else if (path_begin == path_end) {
+ // Path refers to this field.
+ *output_message = &root;
+ *output_field = field;
+ *output_index = -1;
+ return true;
+ } else {
+ ADD_FAILURE() << descriptor->name() << "." << field->name()
+ << " is not a message; cannot descend into it.";
+ return false;
+ }
+ }
+}
+
+// Split some text on line breaks. The line breaks are retained in the output,
+// so each line (except the last) ends with a '\n', and the lines can be
+// concatenated to produce the original text.
+//
+// I couldn't find the proper string utility function for this. Our
+// split-on-delimiter functions don't include the delimiter in the output.
+void SplitLines(const string& text, vector<string>* lines) {
+ string::size_type pos = 0;
+
+ while (pos != string::npos) {
+ string::size_type last_pos = pos;
+ pos = text.find_first_of('\n', pos);
+ if (pos != string::npos) ++pos;
+ lines->push_back(text.substr(last_pos, pos - last_pos));
+ }
+}
+
+// Look for the given tags in the given text and construct a span (as defined
+// by SourceCodeInfo.Location.span) from them. E.g. for text like:
+// /*a*/message /*b*/Foo/*c*/ {}/*d*/
+// There are four tags: "a", "b", "c", and "d". The constructed span starts
+// immediately after the start tag's trailing '/' and ends immediately before
+// the end tags leading '/'.
+void MakeExpectedSpan(const vector<string>& lines,
+ const string& start_tag, const string& end_tag,
+ RepeatedField<int>* output) {
+ string start_comment = "/*" + start_tag + "*/";
+ string end_comment = "/*" + end_tag + "*/";
+
+ int start_line = -1;
+ int start_column = -1;
+ for (int i = 0; i < lines.size(); i++) {
+ string::size_type pos = lines[i].find(start_comment);
+ if (pos != string::npos) {
+ start_line = i;
+ start_column = pos + start_comment.size();
+ break;
+ }
+ }
+ ASSERT_NE(start_line, -1)
+ << "Tag \"" << start_comment << "\" not found in text.";
+
+ int end_line = -1;
+ int end_column = -1;
+ for (int i = start_line; i < lines.size(); i++) {
+ string::size_type pos = lines[i].find(end_comment);
+ if (pos != string::npos) {
+ end_line = i;
+ end_column = pos;
+ break;
+ }
+ }
+ ASSERT_NE(end_line, -1)
+ << "Tag \"" << end_comment << "\" not found in text.";
+
+ output->Add(start_line);
+ output->Add(start_column);
+ if (end_line != start_line) output->Add(end_line);
+ output->Add(end_column);
+}
+
+// Check if two spans are equal.
+bool CompareSpans(const RepeatedField<int>& span1,
+ const RepeatedField<int>& span2) {
+ if (span1.size() != span2.size()) return false;
+ for (int i = 0; i < span1.size(); i++) {
+ if (span1.Get(i) != span2.Get(i)) return false;
+ }
+ return true;
+}
+
+// Test fixture for source info tests, which check that source locations are
+// recorded correctly in FileDescriptorProto.source_code_info.location.
+class SourceInfoTest : public ParserTest {
+ protected:
+ // The parsed file (initialized by Parse()).
+ FileDescriptorProto file_;
+
+ // Parse the given text as a .proto file and populate the spans_ map with
+ // all the source location spans in its SourceCodeInfo table.
+ bool Parse(const char* text) {
+ SetupParser(text);
+ SplitLines(text, &lines_);
+ if (!parser_->Parse(input_.get(), &file_)) {
+ return false;
+ }
+
+ const SourceCodeInfo& source_info = file_.source_code_info();
+ for (int i = 0; i < source_info.location_size(); i++) {
+ const SourceCodeInfo::Location& location = source_info.location(i);
+ const Message* descriptor_proto = NULL;
+ const FieldDescriptor* field = NULL;
+ int index = 0;
+ if (!FollowPath(file_, location.path().begin(), location.path().end(),
+ &descriptor_proto, &field, &index)) {
+ return false;
+ }
+
+ spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index),
+ &location));
+ }
+
+ return true;
+ }
+
+ virtual void TearDown() {
+ EXPECT_TRUE(spans_.empty())
+ << "Forgot to call HasSpan() for:\n"
+ << spans_.begin()->second->DebugString();
+ }
+
+ // -----------------------------------------------------------------
+ // HasSpan() checks that the span of source code delimited by the given
+ // tags (comments) correspond via the SourceCodeInfo table to the given
+ // part of the FileDescriptorProto. (If unclear, look at the actual tests;
+ // it should quickly become obvious.)
+
+ bool HasSpan(const char* start_tag, const char* end_tag,
+ const Message& descriptor_proto) {
+ return HasSpan(start_tag, end_tag, descriptor_proto, NULL, -1);
+ }
+
+ bool HasSpan(const char* start_tag, const char* end_tag,
+ const Message& descriptor_proto, const string& field_name) {
+ return HasSpan(start_tag, end_tag, descriptor_proto, field_name, -1);
+ }
+
+ bool HasSpan(const char* start_tag, const char* end_tag,
+ const Message& descriptor_proto, const string& field_name,
+ int index) {
+ const FieldDescriptor* field =
+ descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
+ if (field == NULL) {
+ ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
+ << " has no such field: " << field_name;
+ return false;
+ }
+
+ return HasSpan(start_tag, end_tag, descriptor_proto, field, index);
+ }
+
+ bool HasSpan(const Message& descriptor_proto) {
+ return HasSpan(NULL, NULL, descriptor_proto, NULL, -1);
+ }
+
+ bool HasSpan(const Message& descriptor_proto, const string& field_name) {
+ return HasSpan(NULL, NULL, descriptor_proto, field_name, -1);
+ }
+
+ bool HasSpan(const Message& descriptor_proto, const string& field_name,
+ int index) {
+ return HasSpan(NULL, NULL, descriptor_proto, field_name, index);
+ }
+
+ bool HasSpan(const char* start_tag, const char* end_tag,
+ const Message& descriptor_proto, const FieldDescriptor* field,
+ int index) {
+ pair<SpanMap::iterator, SpanMap::iterator> range =
+ spans_.equal_range(SpanKey(descriptor_proto, field, index));
+
+ if (start_tag == NULL) {
+ if (range.first == range.second) {
+ return false;
+ } else {
+ spans_.erase(range.first);
+ return true;
+ }
+ } else {
+ RepeatedField<int> expected_span;
+ MakeExpectedSpan(lines_, start_tag, end_tag, &expected_span);
+
+ for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) {
+ if (CompareSpans(expected_span, iter->second->span())) {
+ spans_.erase(iter);
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ private:
+ struct SpanKey {
+ const Message* descriptor_proto;
+ const FieldDescriptor* field;
+ int index;
+
+ inline SpanKey() {}
+ inline SpanKey(const Message& descriptor_proto,
+ const FieldDescriptor* field,
+ int index)
+ : descriptor_proto(&descriptor_proto), field(field), index(index) {}
+
+ inline bool operator<(const SpanKey& other) const {
+ if (descriptor_proto < other.descriptor_proto) return true;
+ if (descriptor_proto > other.descriptor_proto) return false;
+ if (field < other.field) return true;
+ if (field > other.field) return false;
+ return index < other.index;
+ }
+ };
+
+ typedef multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap;
+ SpanMap spans_;
+ vector<string> lines_;
+};
+
+TEST_F(SourceInfoTest, BasicFileDecls) {
+ EXPECT_TRUE(Parse(
+ "/*a*/syntax = \"proto2\";\n"
+ "package /*b*/foo.bar/*c*/;\n"
+ "import /*d*/\"baz.proto\"/*e*/;\n"
+ "import /*f*/\"qux.proto\"/*g*/;/*h*/\n"
+ "// comment ignored\n"));
+
+ EXPECT_TRUE(HasSpan("a", "h", file_));
+ EXPECT_TRUE(HasSpan("b", "c", file_, "package"));
+ EXPECT_TRUE(HasSpan("d", "e", file_, "dependency", 0));
+ EXPECT_TRUE(HasSpan("f", "g", file_, "dependency", 1));
+}
+
+TEST_F(SourceInfoTest, Messages) {
+ EXPECT_TRUE(Parse(
+ "/*a*/message /*b*/Foo/*c*/ {}/*d*/\n"
+ "/*e*/message /*f*/Bar/*g*/ {}/*h*/\n"));
+
+ EXPECT_TRUE(HasSpan("a", "d", file_.message_type(0)));
+ EXPECT_TRUE(HasSpan("b", "c", file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan("e", "h", file_.message_type(1)));
+ EXPECT_TRUE(HasSpan("f", "g", file_.message_type(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, Fields) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " /*a*/optional/*b*/ /*c*/int32/*d*/ /*e*/bar/*f*/ = /*g*/1/*h*/;/*i*/\n"
+ " /*j*/repeated/*k*/ /*l*/X.Y/*m*/ /*n*/baz/*o*/ = /*p*/2/*q*/;/*r*/\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
+
+ EXPECT_TRUE(HasSpan("a", "i", field1));
+ EXPECT_TRUE(HasSpan("a", "b", field1, "label"));
+ EXPECT_TRUE(HasSpan("c", "d", field1, "type"));
+ EXPECT_TRUE(HasSpan("e", "f", field1, "name"));
+ EXPECT_TRUE(HasSpan("g", "h", field1, "number"));
+
+ EXPECT_TRUE(HasSpan("j", "r", field2));
+ EXPECT_TRUE(HasSpan("j", "k", field2, "label"));
+ EXPECT_TRUE(HasSpan("l", "m", field2, "type_name"));
+ EXPECT_TRUE(HasSpan("n", "o", field2, "name"));
+ EXPECT_TRUE(HasSpan("p", "q", field2, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Extensions) {
+ EXPECT_TRUE(Parse(
+ "/*a*/extend /*b*/Foo/*c*/ {\n"
+ " /*d*/optional/*e*/ int32 bar = 1;/*f*/\n"
+ " /*g*/repeated/*h*/ X.Y baz = 2;/*i*/\n"
+ "}/*j*/\n"
+ "/*k*/extend /*l*/Bar/*m*/ {\n"
+ " /*n*/optional int32 qux = 1;/*o*/\n"
+ "}/*p*/\n"));
+
+ const FieldDescriptorProto& field1 = file_.extension(0);
+ const FieldDescriptorProto& field2 = file_.extension(1);
+ const FieldDescriptorProto& field3 = file_.extension(2);
+
+ EXPECT_TRUE(HasSpan("a", "j", file_, "extension"));
+ EXPECT_TRUE(HasSpan("k", "p", file_, "extension"));
+
+ EXPECT_TRUE(HasSpan("d", "f", field1));
+ EXPECT_TRUE(HasSpan("d", "e", field1, "label"));
+ EXPECT_TRUE(HasSpan("b", "c", field1, "extendee"));
+
+ EXPECT_TRUE(HasSpan("g", "i", field2));
+ EXPECT_TRUE(HasSpan("g", "h", field2, "label"));
+ EXPECT_TRUE(HasSpan("b", "c", field2, "extendee"));
+
+ EXPECT_TRUE(HasSpan("n", "o", field3));
+ EXPECT_TRUE(HasSpan("l", "m", field3, "extendee"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(field1, "type"));
+ EXPECT_TRUE(HasSpan(field1, "name"));
+ EXPECT_TRUE(HasSpan(field1, "number"));
+ EXPECT_TRUE(HasSpan(field2, "type_name"));
+ EXPECT_TRUE(HasSpan(field2, "name"));
+ EXPECT_TRUE(HasSpan(field2, "number"));
+ EXPECT_TRUE(HasSpan(field3, "label"));
+ EXPECT_TRUE(HasSpan(field3, "type"));
+ EXPECT_TRUE(HasSpan(field3, "name"));
+ EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, NestedExtensions) {
+ EXPECT_TRUE(Parse(
+ "message Message {\n"
+ " /*a*/extend /*b*/Foo/*c*/ {\n"
+ " /*d*/optional/*e*/ int32 bar = 1;/*f*/\n"
+ " /*g*/repeated/*h*/ X.Y baz = 2;/*i*/\n"
+ " }/*j*/\n"
+ " /*k*/extend /*l*/Bar/*m*/ {\n"
+ " /*n*/optional int32 qux = 1;/*o*/\n"
+ " }/*p*/\n"
+ "}\n"));
+
+ const FieldDescriptorProto& field1 = file_.message_type(0).extension(0);
+ const FieldDescriptorProto& field2 = file_.message_type(0).extension(1);
+ const FieldDescriptorProto& field3 = file_.message_type(0).extension(2);
+
+ EXPECT_TRUE(HasSpan("a", "j", file_.message_type(0), "extension"));
+ EXPECT_TRUE(HasSpan("k", "p", file_.message_type(0), "extension"));
+
+ EXPECT_TRUE(HasSpan("d", "f", field1));
+ EXPECT_TRUE(HasSpan("d", "e", field1, "label"));
+ EXPECT_TRUE(HasSpan("b", "c", field1, "extendee"));
+
+ EXPECT_TRUE(HasSpan("g", "i", field2));
+ EXPECT_TRUE(HasSpan("g", "h", field2, "label"));
+ EXPECT_TRUE(HasSpan("b", "c", field2, "extendee"));
+
+ EXPECT_TRUE(HasSpan("n", "o", field3));
+ EXPECT_TRUE(HasSpan("l", "m", field3, "extendee"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(field1, "type"));
+ EXPECT_TRUE(HasSpan(field1, "name"));
+ EXPECT_TRUE(HasSpan(field1, "number"));
+ EXPECT_TRUE(HasSpan(field2, "type_name"));
+ EXPECT_TRUE(HasSpan(field2, "name"));
+ EXPECT_TRUE(HasSpan(field2, "number"));
+ EXPECT_TRUE(HasSpan(field3, "label"));
+ EXPECT_TRUE(HasSpan(field3, "type"));
+ EXPECT_TRUE(HasSpan(field3, "name"));
+ EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, ExtensionRanges) {
+ EXPECT_TRUE(Parse(
+ "message Message {\n"
+ " /*a*/extensions /*b*/1/*c*/ to /*d*/4/*e*/, /*f*/6/*g*/;/*h*/\n"
+ " /*i*/extensions /*j*/8/*k*/ to /*l*/max/*m*/;/*n*/\n"
+ "}\n"));
+
+ const DescriptorProto::ExtensionRange& range1 =
+ file_.message_type(0).extension_range(0);
+ const DescriptorProto::ExtensionRange& range2 =
+ file_.message_type(0).extension_range(1);
+ const DescriptorProto::ExtensionRange& range3 =
+ file_.message_type(0).extension_range(2);
+
+ EXPECT_TRUE(HasSpan("a", "h", file_.message_type(0), "extension_range"));
+ EXPECT_TRUE(HasSpan("i", "n", file_.message_type(0), "extension_range"));
+
+ EXPECT_TRUE(HasSpan("b", "e", range1));
+ EXPECT_TRUE(HasSpan("b", "c", range1, "start"));
+ EXPECT_TRUE(HasSpan("d", "e", range1, "end"));
+
+ EXPECT_TRUE(HasSpan("f", "g", range2));
+ EXPECT_TRUE(HasSpan("f", "g", range2, "start"));
+ EXPECT_TRUE(HasSpan("f", "g", range2, "end"));
+
+ EXPECT_TRUE(HasSpan("j", "m", range3));
+ EXPECT_TRUE(HasSpan("j", "k", range3, "start"));
+ EXPECT_TRUE(HasSpan("l", "m", range3, "end"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedMessages) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " /*a*/message /*b*/Bar/*c*/ {\n"
+ " /*d*/message /*e*/Baz/*f*/ {}/*g*/\n"
+ " }/*h*/\n"
+ " /*i*/message /*j*/Qux/*k*/ {}/*l*/\n"
+ "}\n"));
+
+ const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+ const DescriptorProto& baz = bar.nested_type(0);
+ const DescriptorProto& qux = file_.message_type(0).nested_type(1);
+
+ EXPECT_TRUE(HasSpan("a", "h", bar));
+ EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
+ EXPECT_TRUE(HasSpan("d", "g", baz));
+ EXPECT_TRUE(HasSpan("e", "f", baz, "name"));
+ EXPECT_TRUE(HasSpan("i", "l", qux));
+ EXPECT_TRUE(HasSpan("j", "k", qux, "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Groups) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " message Bar {}\n"
+ " /*a*/optional/*b*/ /*c*/group/*d*/ /*e*/Baz/*f*/ = /*g*/1/*h*/ {\n"
+ " /*i*/message Qux {}/*j*/\n"
+ " }/*k*/\n"
+ "}\n"));
+
+ const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+ const DescriptorProto& baz = file_.message_type(0).nested_type(1);
+ const DescriptorProto& qux = baz.nested_type(0);
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+
+ EXPECT_TRUE(HasSpan("a", "k", field));
+ EXPECT_TRUE(HasSpan("a", "b", field, "label"));
+ EXPECT_TRUE(HasSpan("c", "d", field, "type"));
+ EXPECT_TRUE(HasSpan("e", "f", field, "name"));
+ EXPECT_TRUE(HasSpan("e", "f", field, "type_name"));
+ EXPECT_TRUE(HasSpan("g", "h", field, "number"));
+
+ EXPECT_TRUE(HasSpan("a", "k", baz));
+ EXPECT_TRUE(HasSpan("e", "f", baz, "name"));
+ EXPECT_TRUE(HasSpan("i", "j", qux));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(bar));
+ EXPECT_TRUE(HasSpan(bar, "name"));
+ EXPECT_TRUE(HasSpan(qux, "name"));
+}
+
+TEST_F(SourceInfoTest, Enums) {
+ EXPECT_TRUE(Parse(
+ "/*a*/enum /*b*/Foo/*c*/ {}/*d*/\n"
+ "/*e*/enum /*f*/Bar/*g*/ {}/*h*/\n"));
+
+ EXPECT_TRUE(HasSpan("a", "d", file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan("b", "c", file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan("e", "h", file_.enum_type(1)));
+ EXPECT_TRUE(HasSpan("f", "g", file_.enum_type(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, EnumValues) {
+ EXPECT_TRUE(Parse(
+ "enum Foo {\n"
+ " /*a*/BAR/*b*/ = /*c*/1/*d*/;/*e*/\n"
+ " /*f*/BAZ/*g*/ = /*h*/2/*i*/;/*j*/\n"
+ "}"));
+
+ const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0);
+ const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1);
+
+ EXPECT_TRUE(HasSpan("a", "e", bar));
+ EXPECT_TRUE(HasSpan("a", "b", bar, "name"));
+ EXPECT_TRUE(HasSpan("c", "d", bar, "number"));
+ EXPECT_TRUE(HasSpan("f", "j", baz));
+ EXPECT_TRUE(HasSpan("f", "g", baz, "name"));
+ EXPECT_TRUE(HasSpan("h", "i", baz, "number"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedEnums) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " /*a*/enum /*b*/Bar/*c*/ {}/*d*/\n"
+ " /*e*/enum /*f*/Baz/*g*/ {}/*h*/\n"
+ "}\n"));
+
+ const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0);
+ const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1);
+
+ EXPECT_TRUE(HasSpan("a", "d", bar));
+ EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
+ EXPECT_TRUE(HasSpan("e", "h", baz));
+ EXPECT_TRUE(HasSpan("f", "g", baz, "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Services) {
+ EXPECT_TRUE(Parse(
+ "/*a*/service /*b*/Foo/*c*/ {}/*d*/\n"
+ "/*e*/service /*f*/Bar/*g*/ {}/*h*/\n"));
+
+ EXPECT_TRUE(HasSpan("a", "d", file_.service(0)));
+ EXPECT_TRUE(HasSpan("b", "c", file_.service(0), "name"));
+ EXPECT_TRUE(HasSpan("e", "h", file_.service(1)));
+ EXPECT_TRUE(HasSpan("f", "g", file_.service(1), "name"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, Methods) {
+ EXPECT_TRUE(Parse(
+ "service Foo {\n"
+ " /*a*/rpc /*b*/Bar/*c*/(/*d*/X/*e*/) returns(/*f*/Y/*g*/);/*h*/"
+ " /*i*/rpc /*j*/Baz/*k*/(/*l*/Z/*m*/) returns(/*n*/W/*o*/);/*p*/"
+ "}"));
+
+ const MethodDescriptorProto& bar = file_.service(0).method(0);
+ const MethodDescriptorProto& baz = file_.service(0).method(1);
+
+ EXPECT_TRUE(HasSpan("a", "h", bar));
+ EXPECT_TRUE(HasSpan("b", "c", bar, "name"));
+ EXPECT_TRUE(HasSpan("d", "e", bar, "input_type"));
+ EXPECT_TRUE(HasSpan("f", "g", bar, "output_type"));
+
+ EXPECT_TRUE(HasSpan("i", "p", baz));
+ EXPECT_TRUE(HasSpan("j", "k", baz, "name"));
+ EXPECT_TRUE(HasSpan("l", "m", baz, "input_type"));
+ EXPECT_TRUE(HasSpan("n", "o", baz, "output_type"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.service(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Options) {
+ EXPECT_TRUE(Parse(
+ "/*a*/option /*b*/foo/*c*/./*d*/(/*e*/bar.baz/*f*/)/*g*/ = "
+ "/*h*/123/*i*/;/*j*/\n"
+ "/*k*/option qux = /*l*/-123/*m*/;/*n*/\n"
+ "/*o*/option corge = /*p*/abc/*q*/;/*r*/\n"
+ "/*s*/option grault = /*t*/'blah'/*u*/;/*v*/\n"
+ "/*w*/option garply = /*x*/{ yadda yadda }/*y*/;/*z*/\n"
+ "/*0*/option waldo = /*1*/123.0/*2*/;/*3*/\n"
+ ));
+
+ const UninterpretedOption& option1 = file_.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = file_.options().uninterpreted_option(1);
+ const UninterpretedOption& option3 = file_.options().uninterpreted_option(2);
+ const UninterpretedOption& option4 = file_.options().uninterpreted_option(3);
+ const UninterpretedOption& option5 = file_.options().uninterpreted_option(4);
+ const UninterpretedOption& option6 = file_.options().uninterpreted_option(5);
+
+ EXPECT_TRUE(HasSpan("a", "j", file_.options()));
+ EXPECT_TRUE(HasSpan("b", "i", option1));
+ EXPECT_TRUE(HasSpan("b", "g", option1, "name"));
+ EXPECT_TRUE(HasSpan("b", "c", option1.name(0)));
+ EXPECT_TRUE(HasSpan("b", "c", option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan("d", "g", option1.name(1)));
+ EXPECT_TRUE(HasSpan("e", "f", option1.name(1), "name_part"));
+ EXPECT_TRUE(HasSpan("h", "i", option1, "positive_int_value"));
+
+ EXPECT_TRUE(HasSpan("k", "n", file_.options()));
+ EXPECT_TRUE(HasSpan("l", "m", option2, "negative_int_value"));
+
+ EXPECT_TRUE(HasSpan("o", "r", file_.options()));
+ EXPECT_TRUE(HasSpan("p", "q", option3, "identifier_value"));
+
+ EXPECT_TRUE(HasSpan("s", "v", file_.options()));
+ EXPECT_TRUE(HasSpan("t", "u", option4, "string_value"));
+
+ EXPECT_TRUE(HasSpan("w", "z", file_.options()));
+ EXPECT_TRUE(HasSpan("x", "y", option5, "aggregate_value"));
+
+ EXPECT_TRUE(HasSpan("0", "3", file_.options()));
+ EXPECT_TRUE(HasSpan("1", "2", option6, "double_value"));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(option2));
+ EXPECT_TRUE(HasSpan(option3));
+ EXPECT_TRUE(HasSpan(option4));
+ EXPECT_TRUE(HasSpan(option5));
+ EXPECT_TRUE(HasSpan(option6));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option3, "name"));
+ EXPECT_TRUE(HasSpan(option4, "name"));
+ EXPECT_TRUE(HasSpan(option5, "name"));
+ EXPECT_TRUE(HasSpan(option6, "name"));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option3.name(0)));
+ EXPECT_TRUE(HasSpan(option4.name(0)));
+ EXPECT_TRUE(HasSpan(option5.name(0)));
+ EXPECT_TRUE(HasSpan(option6.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option3.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option4.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option5.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option6.name(0), "name_part"));
+}
+
+TEST_F(SourceInfoTest, ScopedOptions) {
+ EXPECT_TRUE(Parse(
+ "message Foo {\n"
+ " /*a*/option mopt = 1;/*b*/\n"
+ "}\n"
+ "enum Bar {\n"
+ " /*c*/option eopt = 1;/*d*/\n"
+ "}\n"
+ "service Baz {\n"
+ " /*e*/option sopt = 1;/*f*/\n"
+ " rpc M(X) returns(Y) {\n"
+ " /*g*/option mopt = 1;/*h*/\n"
+ " }\n"
+ "}\n"));
+
+ EXPECT_TRUE(HasSpan("a", "b", file_.message_type(0).options()));
+ EXPECT_TRUE(HasSpan("c", "d", file_.enum_type(0).options()));
+ EXPECT_TRUE(HasSpan("e", "f", file_.service(0).options()));
+ EXPECT_TRUE(HasSpan("g", "h", file_.service(0).method(0).options()));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.service(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.service(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0), "name"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0).name(0)));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0).name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+ .uninterpreted_option(0), "positive_int_value"));
+}
+
+TEST_F(SourceInfoTest, FieldOptions) {
+ // The actual "name = value" pairs are parsed by the same code as for
+ // top-level options so we won't re-test that -- just make sure that the
+ // syntax used for field options is understood.
+ EXPECT_TRUE(Parse(
+ "message Foo {"
+ " optional int32 bar = 1 "
+ "/*a*/[default=/*b*/123/*c*/,/*d*/opt1=123/*e*/,"
+ "/*f*/opt2='hi'/*g*/]/*h*/;"
+ "}\n"
+ ));
+
+ const FieldDescriptorProto& field = file_.message_type(0).field(0);
+ const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
+
+ EXPECT_TRUE(HasSpan("a", "h", field.options()));
+ EXPECT_TRUE(HasSpan("b", "c", field, "default_value"));
+ EXPECT_TRUE(HasSpan("d", "e", option1));
+ EXPECT_TRUE(HasSpan("f", "g", option2));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.message_type(0)));
+ EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+ EXPECT_TRUE(HasSpan(field));
+ EXPECT_TRUE(HasSpan(field, "label"));
+ EXPECT_TRUE(HasSpan(field, "type"));
+ EXPECT_TRUE(HasSpan(field, "name"));
+ EXPECT_TRUE(HasSpan(field, "number"));
+ EXPECT_TRUE(HasSpan(option1, "name"));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option1.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+ EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+TEST_F(SourceInfoTest, EnumValueOptions) {
+ // The actual "name = value" pairs are parsed by the same code as for
+ // top-level options so we won't re-test that -- just make sure that the
+ // syntax used for enum options is understood.
+ EXPECT_TRUE(Parse(
+ "enum Foo {"
+ " BAR = 1 /*a*/[/*b*/opt1=123/*c*/,/*d*/opt2='hi'/*e*/]/*f*/;"
+ "}\n"
+ ));
+
+ const EnumValueDescriptorProto& value = file_.enum_type(0).value(0);
+ const UninterpretedOption& option1 = value.options().uninterpreted_option(0);
+ const UninterpretedOption& option2 = value.options().uninterpreted_option(1);
+
+ EXPECT_TRUE(HasSpan("a", "f", value.options()));
+ EXPECT_TRUE(HasSpan("b", "c", option1));
+ EXPECT_TRUE(HasSpan("d", "e", option2));
+
+ // Ignore these.
+ EXPECT_TRUE(HasSpan(file_));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+ EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+ EXPECT_TRUE(HasSpan(value));
+ EXPECT_TRUE(HasSpan(value, "name"));
+ EXPECT_TRUE(HasSpan(value, "number"));
+ EXPECT_TRUE(HasSpan(option1, "name"));
+ EXPECT_TRUE(HasSpan(option2, "name"));
+ EXPECT_TRUE(HasSpan(option1.name(0)));
+ EXPECT_TRUE(HasSpan(option2.name(0)));
+ EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+ EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+ EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+// ===================================================================
+
+} // anonymous namespace
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/plugin.cc b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.cc
new file mode 100644
index 0000000..727f942
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.cc
@@ -0,0 +1,163 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/plugin.h>
+
+#include <iostream>
+#include <set>
+
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#else
+#include <unistd.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/plugin.pb.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+class GeneratorResponseContext : public GeneratorContext {
+ public:
+ GeneratorResponseContext(CodeGeneratorResponse* response,
+ const vector<const FileDescriptor*>& parsed_files)
+ : response_(response),
+ parsed_files_(parsed_files) {}
+ virtual ~GeneratorResponseContext() {}
+
+ // implements GeneratorContext --------------------------------------
+
+ virtual io::ZeroCopyOutputStream* Open(const string& filename) {
+ CodeGeneratorResponse::File* file = response_->add_file();
+ file->set_name(filename);
+ return new io::StringOutputStream(file->mutable_content());
+ }
+
+ virtual io::ZeroCopyOutputStream* OpenForInsert(
+ const string& filename, const string& insertion_point) {
+ CodeGeneratorResponse::File* file = response_->add_file();
+ file->set_name(filename);
+ file->set_insertion_point(insertion_point);
+ return new io::StringOutputStream(file->mutable_content());
+ }
+
+ void ListParsedFiles(vector<const FileDescriptor*>* output) {
+ *output = parsed_files_;
+ }
+
+ private:
+ CodeGeneratorResponse* response_;
+ const vector<const FileDescriptor*>& parsed_files_;
+};
+
+int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
+
+ if (argc > 1) {
+ cerr << argv[0] << ": Unknown option: " << argv[1] << endl;
+ return 1;
+ }
+
+#ifdef _WIN32
+ _setmode(STDIN_FILENO, _O_BINARY);
+ _setmode(STDOUT_FILENO, _O_BINARY);
+#endif
+
+ CodeGeneratorRequest request;
+ if (!request.ParseFromFileDescriptor(STDIN_FILENO)) {
+ cerr << argv[0] << ": protoc sent unparseable request to plugin." << endl;
+ return 1;
+ }
+
+ DescriptorPool pool;
+ for (int i = 0; i < request.proto_file_size(); i++) {
+ const FileDescriptor* file = pool.BuildFile(request.proto_file(i));
+ if (file == NULL) {
+ // BuildFile() already wrote an error message.
+ return 1;
+ }
+ }
+
+ vector<const FileDescriptor*> parsed_files;
+ for (int i = 0; i < request.file_to_generate_size(); i++) {
+ parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i)));
+ if (parsed_files.back() == NULL) {
+ cerr << argv[0] << ": protoc asked plugin to generate a file but "
+ "did not provide a descriptor for the file: "
+ << request.file_to_generate(i) << endl;
+ return 1;
+ }
+ }
+
+ CodeGeneratorResponse response;
+ GeneratorResponseContext context(&response, parsed_files);
+
+ for (int i = 0; i < parsed_files.size(); i++) {
+ const FileDescriptor* file = parsed_files[i];
+
+ string error;
+ bool succeeded = generator->Generate(
+ file, request.parameter(), &context, &error);
+
+ if (!succeeded && error.empty()) {
+ error = "Code generator returned false but provided no error "
+ "description.";
+ }
+ if (!error.empty()) {
+ response.set_error(file->name() + ": " + error);
+ break;
+ }
+ }
+
+ if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) {
+ cerr << argv[0] << ": Error writing to stdout." << endl;
+ return 1;
+ }
+
+ return 0;
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/plugin.h b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.h
new file mode 100644
index 0000000..7c40333
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.h
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Front-end for protoc code generator plugins written in C++.
+//
+// To implement a protoc plugin in C++, simply write an implementation of
+// CodeGenerator, then create a main() function like:
+// int main(int argc, char* argv[]) {
+// MyCodeGenerator generator;
+// return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+// }
+// You must link your plugin against libprotobuf and libprotoc.
+//
+// To get protoc to use the plugin, do one of the following:
+// * Place the plugin binary somewhere in the PATH and give it the name
+// "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you
+// then invoke protoc with the parameter --NAME_out=OUT_DIR (again, replace
+// "NAME" with your plugin's name), protoc will invoke your plugin to generate
+// the output, which will be placed in OUT_DIR.
+// * Place the plugin binary anywhere, with any name, and pass the --plugin
+// parameter to protoc to direct it to your plugin like so:
+// protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR
+// On Windows, make sure to include the .exe suffix:
+// protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
+#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+class CodeGenerator; // code_generator.h
+
+// Implements main() for a protoc plugin exposing the given code generator.
+LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator);
+
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc
new file mode 100644
index 0000000..c956188
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc
@@ -0,0 +1,1081 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "google/protobuf/compiler/plugin.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+const ::google::protobuf::Descriptor* CodeGeneratorRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ CodeGeneratorRequest_reflection_ = NULL;
+const ::google::protobuf::Descriptor* CodeGeneratorResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ CodeGeneratorResponse_reflection_ = NULL;
+const ::google::protobuf::Descriptor* CodeGeneratorResponse_File_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ CodeGeneratorResponse_File_reflection_ = NULL;
+
+} // namespace
+
+
+void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+ protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ const ::google::protobuf::FileDescriptor* file =
+ ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+ "google/protobuf/compiler/plugin.proto");
+ GOOGLE_CHECK(file != NULL);
+ CodeGeneratorRequest_descriptor_ = file->message_type(0);
+ static const int CodeGeneratorRequest_offsets_[3] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, file_to_generate_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, parameter_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_),
+ };
+ CodeGeneratorRequest_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ CodeGeneratorRequest_descriptor_,
+ CodeGeneratorRequest::default_instance_,
+ CodeGeneratorRequest_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(CodeGeneratorRequest));
+ CodeGeneratorResponse_descriptor_ = file->message_type(1);
+ static const int CodeGeneratorResponse_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, file_),
+ };
+ CodeGeneratorResponse_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ CodeGeneratorResponse_descriptor_,
+ CodeGeneratorResponse::default_instance_,
+ CodeGeneratorResponse_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(CodeGeneratorResponse));
+ CodeGeneratorResponse_File_descriptor_ = CodeGeneratorResponse_descriptor_->nested_type(0);
+ static const int CodeGeneratorResponse_File_offsets_[3] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, insertion_point_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, content_),
+ };
+ CodeGeneratorResponse_File_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ CodeGeneratorResponse_File_descriptor_,
+ CodeGeneratorResponse_File::default_instance_,
+ CodeGeneratorResponse_File_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(CodeGeneratorResponse_File));
+}
+
+namespace {
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
+inline void protobuf_AssignDescriptorsOnce() {
+ ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
+ &protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ CodeGeneratorRequest_descriptor_, &CodeGeneratorRequest::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ CodeGeneratorResponse_descriptor_, &CodeGeneratorResponse::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ CodeGeneratorResponse_File_descriptor_, &CodeGeneratorResponse_File::default_instance());
+}
+
+} // namespace
+
+void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+ delete CodeGeneratorRequest::default_instance_;
+ delete CodeGeneratorRequest_reflection_;
+ delete CodeGeneratorResponse::default_instance_;
+ delete CodeGeneratorResponse_reflection_;
+ delete CodeGeneratorResponse_File::default_instance_;
+ delete CodeGeneratorResponse_File_reflection_;
+}
+
+void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+ static bool already_here = false;
+ if (already_here) return;
+ already_here = true;
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+ ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ "\n%google/protobuf/compiler/plugin.proto\022"
+ "\030google.protobuf.compiler\032 google/protob"
+ "uf/descriptor.proto\"}\n\024CodeGeneratorRequ"
+ "est\022\030\n\020file_to_generate\030\001 \003(\t\022\021\n\tparamet"
+ "er\030\002 \001(\t\0228\n\nproto_file\030\017 \003(\0132$.google.pr"
+ "otobuf.FileDescriptorProto\"\252\001\n\025CodeGener"
+ "atorResponse\022\r\n\005error\030\001 \001(\t\022B\n\004file\030\017 \003("
+ "\01324.google.protobuf.compiler.CodeGenerat"
+ "orResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n"
+ "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\t", 399);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes);
+ CodeGeneratorRequest::default_instance_ = new CodeGeneratorRequest();
+ CodeGeneratorResponse::default_instance_ = new CodeGeneratorResponse();
+ CodeGeneratorResponse_File::default_instance_ = new CodeGeneratorResponse_File();
+ CodeGeneratorRequest::default_instance_->InitAsDefaultInstance();
+ CodeGeneratorResponse::default_instance_->InitAsDefaultInstance();
+ CodeGeneratorResponse_File::default_instance_->InitAsDefaultInstance();
+ ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
+ StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+ protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ }
+} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_;
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int CodeGeneratorRequest::kFileToGenerateFieldNumber;
+const int CodeGeneratorRequest::kParameterFieldNumber;
+const int CodeGeneratorRequest::kProtoFileFieldNumber;
+#endif // !_MSC_VER
+
+CodeGeneratorRequest::CodeGeneratorRequest()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void CodeGeneratorRequest::InitAsDefaultInstance() {
+}
+
+CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void CodeGeneratorRequest::SharedCtor() {
+ _cached_size_ = 0;
+ parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+CodeGeneratorRequest::~CodeGeneratorRequest() {
+ SharedDtor();
+}
+
+void CodeGeneratorRequest::SharedDtor() {
+ if (parameter_ != &::google::protobuf::internal::kEmptyString) {
+ delete parameter_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void CodeGeneratorRequest::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return CodeGeneratorRequest_descriptor_;
+}
+
+const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ return *default_instance_;
+}
+
+CodeGeneratorRequest* CodeGeneratorRequest::default_instance_ = NULL;
+
+CodeGeneratorRequest* CodeGeneratorRequest::New() const {
+ return new CodeGeneratorRequest;
+}
+
+void CodeGeneratorRequest::Clear() {
+ if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ if (has_parameter()) {
+ if (parameter_ != &::google::protobuf::internal::kEmptyString) {
+ parameter_->clear();
+ }
+ }
+ }
+ file_to_generate_.Clear();
+ proto_file_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool CodeGeneratorRequest::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated string file_to_generate = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_file_to_generate:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->add_file_to_generate()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->file_to_generate(this->file_to_generate_size() - 1).data(),
+ this->file_to_generate(this->file_to_generate_size() - 1).length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(10)) goto parse_file_to_generate;
+ if (input->ExpectTag(18)) goto parse_parameter;
+ break;
+ }
+
+ // optional string parameter = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_parameter:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_parameter()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->parameter().data(), this->parameter().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(122)) goto parse_proto_file;
+ break;
+ }
+
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ case 15: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_proto_file:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_proto_file()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(122)) goto parse_proto_file;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void CodeGeneratorRequest::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated string file_to_generate = 1;
+ for (int i = 0; i < this->file_to_generate_size(); i++) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->file_to_generate(i).data(), this->file_to_generate(i).length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->file_to_generate(i), output);
+ }
+
+ // optional string parameter = 2;
+ if (has_parameter()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->parameter().data(), this->parameter().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 2, this->parameter(), output);
+ }
+
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ for (int i = 0; i < this->proto_file_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 15, this->proto_file(i), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* CodeGeneratorRequest::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated string file_to_generate = 1;
+ for (int i = 0; i < this->file_to_generate_size(); i++) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->file_to_generate(i).data(), this->file_to_generate(i).length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteStringToArray(1, this->file_to_generate(i), target);
+ }
+
+ // optional string parameter = 2;
+ if (has_parameter()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->parameter().data(), this->parameter().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 2, this->parameter(), target);
+ }
+
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ for (int i = 0; i < this->proto_file_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 15, this->proto_file(i), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int CodeGeneratorRequest::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ // optional string parameter = 2;
+ if (has_parameter()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->parameter());
+ }
+
+ }
+ // repeated string file_to_generate = 1;
+ total_size += 1 * this->file_to_generate_size();
+ for (int i = 0; i < this->file_to_generate_size(); i++) {
+ total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->file_to_generate(i));
+ }
+
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ total_size += 1 * this->proto_file_size();
+ for (int i = 0; i < this->proto_file_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->proto_file(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const CodeGeneratorRequest* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorRequest*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ file_to_generate_.MergeFrom(from.file_to_generate_);
+ proto_file_.MergeFrom(from.proto_file_);
+ if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ if (from.has_parameter()) {
+ set_parameter(from.parameter());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void CodeGeneratorRequest::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool CodeGeneratorRequest::IsInitialized() const {
+
+ for (int i = 0; i < proto_file_size(); i++) {
+ if (!this->proto_file(i).IsInitialized()) return false;
+ }
+ return true;
+}
+
+void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) {
+ if (other != this) {
+ file_to_generate_.Swap(&other->file_to_generate_);
+ std::swap(parameter_, other->parameter_);
+ proto_file_.Swap(&other->proto_file_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = CodeGeneratorRequest_descriptor_;
+ metadata.reflection = CodeGeneratorRequest_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int CodeGeneratorResponse_File::kNameFieldNumber;
+const int CodeGeneratorResponse_File::kInsertionPointFieldNumber;
+const int CodeGeneratorResponse_File::kContentFieldNumber;
+#endif // !_MSC_VER
+
+CodeGeneratorResponse_File::CodeGeneratorResponse_File()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void CodeGeneratorResponse_File::InitAsDefaultInstance() {
+}
+
+CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void CodeGeneratorResponse_File::SharedCtor() {
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
+ SharedDtor();
+}
+
+void CodeGeneratorResponse_File::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_;
+ }
+ if (insertion_point_ != &::google::protobuf::internal::kEmptyString) {
+ delete insertion_point_;
+ }
+ if (content_ != &::google::protobuf::internal::kEmptyString) {
+ delete content_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void CodeGeneratorResponse_File::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return CodeGeneratorResponse_File_descriptor_;
+}
+
+const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ return *default_instance_;
+}
+
+CodeGeneratorResponse_File* CodeGeneratorResponse_File::default_instance_ = NULL;
+
+CodeGeneratorResponse_File* CodeGeneratorResponse_File::New() const {
+ return new CodeGeneratorResponse_File;
+}
+
+void CodeGeneratorResponse_File::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ }
+ if (has_insertion_point()) {
+ if (insertion_point_ != &::google::protobuf::internal::kEmptyString) {
+ insertion_point_->clear();
+ }
+ }
+ if (has_content()) {
+ if (content_ != &::google::protobuf::internal::kEmptyString) {
+ content_->clear();
+ }
+ }
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool CodeGeneratorResponse_File::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_insertion_point;
+ break;
+ }
+
+ // optional string insertion_point = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_insertion_point:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_insertion_point()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->insertion_point().data(), this->insertion_point().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(122)) goto parse_content;
+ break;
+ }
+
+ // optional string content = 15;
+ case 15: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_content:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_content()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->content().data(), this->content().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void CodeGeneratorResponse_File::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name(), output);
+ }
+
+ // optional string insertion_point = 2;
+ if (has_insertion_point()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->insertion_point().data(), this->insertion_point().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 2, this->insertion_point(), output);
+ }
+
+ // optional string content = 15;
+ if (has_content()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->content().data(), this->content().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 15, this->content(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // optional string insertion_point = 2;
+ if (has_insertion_point()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->insertion_point().data(), this->insertion_point().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 2, this->insertion_point(), target);
+ }
+
+ // optional string content = 15;
+ if (has_content()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->content().data(), this->content().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 15, this->content(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int CodeGeneratorResponse_File::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional string insertion_point = 2;
+ if (has_insertion_point()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->insertion_point());
+ }
+
+ // optional string content = 15;
+ if (has_content()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->content());
+ }
+
+ }
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const CodeGeneratorResponse_File* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse_File*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ if (from.has_insertion_point()) {
+ set_insertion_point(from.insertion_point());
+ }
+ if (from.has_content()) {
+ set_content(from.content());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void CodeGeneratorResponse_File::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool CodeGeneratorResponse_File::IsInitialized() const {
+
+ return true;
+}
+
+void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ std::swap(insertion_point_, other->insertion_point_);
+ std::swap(content_, other->content_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = CodeGeneratorResponse_File_descriptor_;
+ metadata.reflection = CodeGeneratorResponse_File_reflection_;
+ return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int CodeGeneratorResponse::kErrorFieldNumber;
+const int CodeGeneratorResponse::kFileFieldNumber;
+#endif // !_MSC_VER
+
+CodeGeneratorResponse::CodeGeneratorResponse()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void CodeGeneratorResponse::InitAsDefaultInstance() {
+}
+
+CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void CodeGeneratorResponse::SharedCtor() {
+ _cached_size_ = 0;
+ error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+CodeGeneratorResponse::~CodeGeneratorResponse() {
+ SharedDtor();
+}
+
+void CodeGeneratorResponse::SharedDtor() {
+ if (error_ != &::google::protobuf::internal::kEmptyString) {
+ delete error_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void CodeGeneratorResponse::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return CodeGeneratorResponse_descriptor_;
+}
+
+const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ return *default_instance_;
+}
+
+CodeGeneratorResponse* CodeGeneratorResponse::default_instance_ = NULL;
+
+CodeGeneratorResponse* CodeGeneratorResponse::New() const {
+ return new CodeGeneratorResponse;
+}
+
+void CodeGeneratorResponse::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_error()) {
+ if (error_ != &::google::protobuf::internal::kEmptyString) {
+ error_->clear();
+ }
+ }
+ }
+ file_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool CodeGeneratorResponse::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string error = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_error()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->error().data(), this->error().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(122)) goto parse_file;
+ break;
+ }
+
+ // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ case 15: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_file:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_file()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(122)) goto parse_file;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void CodeGeneratorResponse::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string error = 1;
+ if (has_error()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->error().data(), this->error().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->error(), output);
+ }
+
+ // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ for (int i = 0; i < this->file_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 15, this->file(i), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string error = 1;
+ if (has_error()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->error().data(), this->error().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->error(), target);
+ }
+
+ // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ for (int i = 0; i < this->file_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 15, this->file(i), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int CodeGeneratorResponse::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string error = 1;
+ if (has_error()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->error());
+ }
+
+ }
+ // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ total_size += 1 * this->file_size();
+ for (int i = 0; i < this->file_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->file(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const CodeGeneratorResponse* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ file_.MergeFrom(from.file_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_error()) {
+ set_error(from.error());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void CodeGeneratorResponse::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool CodeGeneratorResponse::IsInitialized() const {
+
+ return true;
+}
+
+void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) {
+ if (other != this) {
+ std::swap(error_, other->error_);
+ file_.Swap(&other->file_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = CodeGeneratorResponse_descriptor_;
+ metadata.reflection = CodeGeneratorResponse_reflection_;
+ return metadata;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h
new file mode 100644
index 0000000..64246fc
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h
@@ -0,0 +1,791 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/compiler/plugin.proto
+
+#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED
+#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 2004002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include "google/protobuf/descriptor.pb.h"
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// Internal implementation detail -- do not call these.
+void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+class CodeGeneratorRequest;
+class CodeGeneratorResponse;
+class CodeGeneratorResponse_File;
+
+// ===================================================================
+
+class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message {
+ public:
+ CodeGeneratorRequest();
+ virtual ~CodeGeneratorRequest();
+
+ CodeGeneratorRequest(const CodeGeneratorRequest& from);
+
+ inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const CodeGeneratorRequest& default_instance();
+
+ void Swap(CodeGeneratorRequest* other);
+
+ // implements Message ----------------------------------------------
+
+ CodeGeneratorRequest* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const CodeGeneratorRequest& from);
+ void MergeFrom(const CodeGeneratorRequest& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated string file_to_generate = 1;
+ inline int file_to_generate_size() const;
+ inline void clear_file_to_generate();
+ static const int kFileToGenerateFieldNumber = 1;
+ inline const ::std::string& file_to_generate(int index) const;
+ inline ::std::string* mutable_file_to_generate(int index);
+ inline void set_file_to_generate(int index, const ::std::string& value);
+ inline void set_file_to_generate(int index, const char* value);
+ inline void set_file_to_generate(int index, const char* value, size_t size);
+ inline ::std::string* add_file_to_generate();
+ inline void add_file_to_generate(const ::std::string& value);
+ inline void add_file_to_generate(const char* value);
+ inline void add_file_to_generate(const char* value, size_t size);
+ inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const;
+ inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate();
+
+ // optional string parameter = 2;
+ inline bool has_parameter() const;
+ inline void clear_parameter();
+ static const int kParameterFieldNumber = 2;
+ inline const ::std::string& parameter() const;
+ inline void set_parameter(const ::std::string& value);
+ inline void set_parameter(const char* value);
+ inline void set_parameter(const char* value, size_t size);
+ inline ::std::string* mutable_parameter();
+ inline ::std::string* release_parameter();
+
+ // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+ inline int proto_file_size() const;
+ inline void clear_proto_file();
+ static const int kProtoFileFieldNumber = 15;
+ inline const ::google::protobuf::FileDescriptorProto& proto_file(int index) const;
+ inline ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index);
+ inline ::google::protobuf::FileDescriptorProto* add_proto_file();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+ proto_file() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+ mutable_proto_file();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
+ private:
+ inline void set_has_parameter();
+ inline void clear_has_parameter();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_;
+ ::std::string* parameter_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+
+ friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+ void InitAsDefaultInstance();
+ static CodeGeneratorRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message {
+ public:
+ CodeGeneratorResponse_File();
+ virtual ~CodeGeneratorResponse_File();
+
+ CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from);
+
+ inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const CodeGeneratorResponse_File& default_instance();
+
+ void Swap(CodeGeneratorResponse_File* other);
+
+ // implements Message ----------------------------------------------
+
+ CodeGeneratorResponse_File* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const CodeGeneratorResponse_File& from);
+ void MergeFrom(const CodeGeneratorResponse_File& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+
+ // optional string insertion_point = 2;
+ inline bool has_insertion_point() const;
+ inline void clear_insertion_point();
+ static const int kInsertionPointFieldNumber = 2;
+ inline const ::std::string& insertion_point() const;
+ inline void set_insertion_point(const ::std::string& value);
+ inline void set_insertion_point(const char* value);
+ inline void set_insertion_point(const char* value, size_t size);
+ inline ::std::string* mutable_insertion_point();
+ inline ::std::string* release_insertion_point();
+
+ // optional string content = 15;
+ inline bool has_content() const;
+ inline void clear_content();
+ static const int kContentFieldNumber = 15;
+ inline const ::std::string& content() const;
+ inline void set_content(const ::std::string& value);
+ inline void set_content(const char* value);
+ inline void set_content(const char* value, size_t size);
+ inline ::std::string* mutable_content();
+ inline ::std::string* release_content();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_insertion_point();
+ inline void clear_has_insertion_point();
+ inline void set_has_content();
+ inline void clear_has_content();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_;
+ ::std::string* insertion_point_;
+ ::std::string* content_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+
+ friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+ void InitAsDefaultInstance();
+ static CodeGeneratorResponse_File* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message {
+ public:
+ CodeGeneratorResponse();
+ virtual ~CodeGeneratorResponse();
+
+ CodeGeneratorResponse(const CodeGeneratorResponse& from);
+
+ inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const CodeGeneratorResponse& default_instance();
+
+ void Swap(CodeGeneratorResponse* other);
+
+ // implements Message ----------------------------------------------
+
+ CodeGeneratorResponse* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const CodeGeneratorResponse& from);
+ void MergeFrom(const CodeGeneratorResponse& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef CodeGeneratorResponse_File File;
+
+ // accessors -------------------------------------------------------
+
+ // optional string error = 1;
+ inline bool has_error() const;
+ inline void clear_error();
+ static const int kErrorFieldNumber = 1;
+ inline const ::std::string& error() const;
+ inline void set_error(const ::std::string& value);
+ inline void set_error(const char* value);
+ inline void set_error(const char* value, size_t size);
+ inline ::std::string* mutable_error();
+ inline ::std::string* release_error();
+
+ // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+ inline int file_size() const;
+ inline void clear_file();
+ static const int kFileFieldNumber = 15;
+ inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const;
+ inline ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index);
+ inline ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+ file() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
+ mutable_file();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
+ private:
+ inline void set_has_error();
+ inline void clear_has_error();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* error_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
+
+ friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+ void InitAsDefaultInstance();
+ static CodeGeneratorResponse* default_instance_;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+// CodeGeneratorRequest
+
+// repeated string file_to_generate = 1;
+inline int CodeGeneratorRequest::file_to_generate_size() const {
+ return file_to_generate_.size();
+}
+inline void CodeGeneratorRequest::clear_file_to_generate() {
+ file_to_generate_.Clear();
+}
+inline const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const {
+ return file_to_generate_.Get(index);
+}
+inline ::std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) {
+ return file_to_generate_.Mutable(index);
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string& value) {
+ file_to_generate_.Mutable(index)->assign(value);
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
+ file_to_generate_.Mutable(index)->assign(value);
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) {
+ file_to_generate_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* CodeGeneratorRequest::add_file_to_generate() {
+ return file_to_generate_.Add();
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) {
+ file_to_generate_.Add()->assign(value);
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const char* value) {
+ file_to_generate_.Add()->assign(value);
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) {
+ file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size);
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+CodeGeneratorRequest::file_to_generate() const {
+ return file_to_generate_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+CodeGeneratorRequest::mutable_file_to_generate() {
+ return &file_to_generate_;
+}
+
+// optional string parameter = 2;
+inline bool CodeGeneratorRequest::has_parameter() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorRequest::set_has_parameter() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorRequest::clear_has_parameter() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void CodeGeneratorRequest::clear_parameter() {
+ if (parameter_ != &::google::protobuf::internal::kEmptyString) {
+ parameter_->clear();
+ }
+ clear_has_parameter();
+}
+inline const ::std::string& CodeGeneratorRequest::parameter() const {
+ return *parameter_;
+}
+inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
+ parameter_ = new ::std::string;
+ }
+ parameter_->assign(value);
+}
+inline void CodeGeneratorRequest::set_parameter(const char* value) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
+ parameter_ = new ::std::string;
+ }
+ parameter_->assign(value);
+}
+inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
+ parameter_ = new ::std::string;
+ }
+ parameter_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* CodeGeneratorRequest::mutable_parameter() {
+ set_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
+ parameter_ = new ::std::string;
+ }
+ return parameter_;
+}
+inline ::std::string* CodeGeneratorRequest::release_parameter() {
+ clear_has_parameter();
+ if (parameter_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = parameter_;
+ parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+inline int CodeGeneratorRequest::proto_file_size() const {
+ return proto_file_.size();
+}
+inline void CodeGeneratorRequest::clear_proto_file() {
+ proto_file_.Clear();
+}
+inline const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
+ return proto_file_.Get(index);
+}
+inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
+ return proto_file_.Mutable(index);
+}
+inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
+ return proto_file_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+CodeGeneratorRequest::proto_file() const {
+ return proto_file_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+CodeGeneratorRequest::mutable_proto_file() {
+ return &proto_file_;
+}
+
+// -------------------------------------------------------------------
+
+// CodeGeneratorResponse_File
+
+// optional string name = 1;
+inline bool CodeGeneratorResponse_File::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void CodeGeneratorResponse_File::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void CodeGeneratorResponse_File::clear_name() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& CodeGeneratorResponse_File::name() const {
+ return *name_;
+}
+inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void CodeGeneratorResponse_File::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* CodeGeneratorResponse_File::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ return name_;
+}
+inline ::std::string* CodeGeneratorResponse_File::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string insertion_point = 2;
+inline bool CodeGeneratorResponse_File::has_insertion_point() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_insertion_point() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorResponse_File::clear_has_insertion_point() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void CodeGeneratorResponse_File::clear_insertion_point() {
+ if (insertion_point_ != &::google::protobuf::internal::kEmptyString) {
+ insertion_point_->clear();
+ }
+ clear_has_insertion_point();
+}
+inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const {
+ return *insertion_point_;
+}
+inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
+ insertion_point_ = new ::std::string;
+ }
+ insertion_point_->assign(value);
+}
+inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
+ insertion_point_ = new ::std::string;
+ }
+ insertion_point_->assign(value);
+}
+inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
+ insertion_point_ = new ::std::string;
+ }
+ insertion_point_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
+ set_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
+ insertion_point_ = new ::std::string;
+ }
+ return insertion_point_;
+}
+inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() {
+ clear_has_insertion_point();
+ if (insertion_point_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = insertion_point_;
+ insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string content = 15;
+inline bool CodeGeneratorResponse_File::has_content() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_content() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void CodeGeneratorResponse_File::clear_has_content() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void CodeGeneratorResponse_File::clear_content() {
+ if (content_ != &::google::protobuf::internal::kEmptyString) {
+ content_->clear();
+ }
+ clear_has_content();
+}
+inline const ::std::string& CodeGeneratorResponse_File::content() const {
+ return *content_;
+}
+inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
+ content_ = new ::std::string;
+ }
+ content_->assign(value);
+}
+inline void CodeGeneratorResponse_File::set_content(const char* value) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
+ content_ = new ::std::string;
+ }
+ content_->assign(value);
+}
+inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
+ content_ = new ::std::string;
+ }
+ content_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
+ set_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
+ content_ = new ::std::string;
+ }
+ return content_;
+}
+inline ::std::string* CodeGeneratorResponse_File::release_content() {
+ clear_has_content();
+ if (content_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = content_;
+ content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// -------------------------------------------------------------------
+
+// CodeGeneratorResponse
+
+// optional string error = 1;
+inline bool CodeGeneratorResponse::has_error() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void CodeGeneratorResponse::set_has_error() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void CodeGeneratorResponse::clear_has_error() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void CodeGeneratorResponse::clear_error() {
+ if (error_ != &::google::protobuf::internal::kEmptyString) {
+ error_->clear();
+ }
+ clear_has_error();
+}
+inline const ::std::string& CodeGeneratorResponse::error() const {
+ return *error_;
+}
+inline void CodeGeneratorResponse::set_error(const ::std::string& value) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
+ error_ = new ::std::string;
+ }
+ error_->assign(value);
+}
+inline void CodeGeneratorResponse::set_error(const char* value) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
+ error_ = new ::std::string;
+ }
+ error_->assign(value);
+}
+inline void CodeGeneratorResponse::set_error(const char* value, size_t size) {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
+ error_ = new ::std::string;
+ }
+ error_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* CodeGeneratorResponse::mutable_error() {
+ set_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
+ error_ = new ::std::string;
+ }
+ return error_;
+}
+inline ::std::string* CodeGeneratorResponse::release_error() {
+ clear_has_error();
+ if (error_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = error_;
+ error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+inline int CodeGeneratorResponse::file_size() const {
+ return file_.size();
+}
+inline void CodeGeneratorResponse::clear_file() {
+ file_.Clear();
+}
+inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
+ return file_.Get(index);
+}
+inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
+ return file_.Mutable(index);
+}
+inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
+ return file_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+CodeGeneratorResponse::file() const {
+ return file_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
+CodeGeneratorResponse::mutable_file() {
+ return &file_;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#ifndef SWIG
+namespace google {
+namespace protobuf {
+
+
+} // namespace google
+} // namespace protobuf
+#endif // SWIG
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/plugin.proto b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.proto
new file mode 100644
index 0000000..651ed10
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/plugin.proto
@@ -0,0 +1,145 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to
+// change.
+//
+// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
+// just a program that reads a CodeGeneratorRequest from stdin and writes a
+// CodeGeneratorResponse to stdout.
+//
+// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
+// of dealing with the raw protocol defined here.
+//
+// A plugin executable needs only to be placed somewhere in the path. The
+// plugin should be named "protoc-gen-$NAME", and will then be used when the
+// flag "--${NAME}_out" is passed to protoc.
+
+package google.protobuf.compiler;
+
+import "google/protobuf/descriptor.proto";
+
+// An encoded CodeGeneratorRequest is written to the plugin's stdin.
+message CodeGeneratorRequest {
+ // The .proto files that were explicitly listed on the command-line. The
+ // code generator should generate code only for these files. Each file's
+ // descriptor will be included in proto_file, below.
+ repeated string file_to_generate = 1;
+
+ // The generator parameter passed on the command-line.
+ optional string parameter = 2;
+
+ // FileDescriptorProtos for all files in files_to_generate and everything
+ // they import. The files will appear in topological order, so each file
+ // appears before any file that imports it.
+ //
+ // protoc guarantees that all proto_files will be written after
+ // the fields above, even though this is not technically guaranteed by the
+ // protobuf wire format. This theoretically could allow a plugin to stream
+ // in the FileDescriptorProtos and handle them one by one rather than read
+ // the entire set into memory at once. However, as of this writing, this
+ // is not similarly optimized on protoc's end -- it will store all fields in
+ // memory at once before sending them to the plugin.
+ repeated FileDescriptorProto proto_file = 15;
+}
+
+// The plugin writes an encoded CodeGeneratorResponse to stdout.
+message CodeGeneratorResponse {
+ // Error message. If non-empty, code generation failed. The plugin process
+ // should exit with status code zero even if it reports an error in this way.
+ //
+ // This should be used to indicate errors in .proto files which prevent the
+ // code generator from generating correct code. Errors which indicate a
+ // problem in protoc itself -- such as the input CodeGeneratorRequest being
+ // unparseable -- should be reported by writing a message to stderr and
+ // exiting with a non-zero status code.
+ optional string error = 1;
+
+ // Represents a single generated file.
+ message File {
+ // The file name, relative to the output directory. The name must not
+ // contain "." or ".." components and must be relative, not be absolute (so,
+ // the file cannot lie outside the output directory). "/" must be used as
+ // the path separator, not "\".
+ //
+ // If the name is omitted, the content will be appended to the previous
+ // file. This allows the generator to break large files into small chunks,
+ // and allows the generated text to be streamed back to protoc so that large
+ // files need not reside completely in memory at one time. Note that as of
+ // this writing protoc does not optimize for this -- it will read the entire
+ // CodeGeneratorResponse before writing files to disk.
+ optional string name = 1;
+
+ // If non-empty, indicates that the named file should already exist, and the
+ // content here is to be inserted into that file at a defined insertion
+ // point. This feature allows a code generator to extend the output
+ // produced by another code generator. The original generator may provide
+ // insertion points by placing special annotations in the file that look
+ // like:
+ // @@protoc_insertion_point(NAME)
+ // The annotation can have arbitrary text before and after it on the line,
+ // which allows it to be placed in a comment. NAME should be replaced with
+ // an identifier naming the point -- this is what other generators will use
+ // as the insertion_point. Code inserted at this point will be placed
+ // immediately above the line containing the insertion point (thus multiple
+ // insertions to the same point will come out in the order they were added).
+ // The double-@ is intended to make it unlikely that the generated code
+ // could contain things that look like insertion points by accident.
+ //
+ // For example, the C++ code generator places the following line in the
+ // .pb.h files that it generates:
+ // // @@protoc_insertion_point(namespace_scope)
+ // This line appears within the scope of the file's package namespace, but
+ // outside of any particular class. Another plugin can then specify the
+ // insertion_point "namespace_scope" to generate additional classes or
+ // other declarations that should be placed in this scope.
+ //
+ // Note that if the line containing the insertion point begins with
+ // whitespace, the same whitespace will be added to every line of the
+ // inserted text. This is useful for languages like Python, where
+ // indentation matters. In these languages, the insertion point comment
+ // should be indented the same amount as any inserted code will need to be
+ // in order to work correctly in that context.
+ //
+ // The code generator that generates the initial file and the one which
+ // inserts into it must both run as part of a single invocation of protoc.
+ // Code generators are executed in the order in which they appear on the
+ // command line.
+ //
+ // If |insertion_point| is present, |name| must also be present.
+ optional string insertion_point = 2;
+
+ // The file contents.
+ optional string content = 15;
+ }
+ repeated File file = 15;
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc b/src/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc
new file mode 100644
index 0000000..9b10937
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc
@@ -0,0 +1,1006 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: robinson@google.com (Will Robinson)
+//
+// This module outputs pure-Python protocol message classes that will
+// largely be constructed at runtime via the metaclass in reflection.py.
+// In other words, our job is basically to output a Python equivalent
+// of the C++ *Descriptor objects, and fix up all circular references
+// within these objects.
+//
+// Note that the runtime performance of protocol message classes created in
+// this way is expected to be lousy. The plan is to create an alternate
+// generator that outputs a Python/C extension module that lets
+// performance-minded Python code leverage the fast C++ implementation
+// directly.
+
+#include <limits>
+#include <map>
+#include <utility>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/compiler/python/python_generator.h>
+#include <google/protobuf/descriptor.pb.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace python {
+
+namespace {
+
+// Returns a copy of |filename| with any trailing ".protodevel" or ".proto
+// suffix stripped.
+// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc.
+string StripProto(const string& filename) {
+ const char* suffix = HasSuffixString(filename, ".protodevel")
+ ? ".protodevel" : ".proto";
+ return StripSuffixString(filename, suffix);
+}
+
+
+// Returns the Python module name expected for a given .proto filename.
+string ModuleName(const string& filename) {
+ string basename = StripProto(filename);
+ StripString(&basename, "-", '_');
+ StripString(&basename, "/", '.');
+ return basename + "_pb2";
+}
+
+
+// Returns the name of all containing types for descriptor,
+// in order from outermost to innermost, followed by descriptor's
+// own name. Each name is separated by |separator|.
+template <typename DescriptorT>
+string NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
+ const string& separator) {
+ string name = descriptor.name();
+ for (const Descriptor* current = descriptor.containing_type();
+ current != NULL; current = current->containing_type()) {
+ name = current->name() + separator + name;
+ }
+ return name;
+}
+
+
+// Name of the class attribute where we store the Python
+// descriptor.Descriptor instance for the generated class.
+// Must stay consistent with the _DESCRIPTOR_KEY constant
+// in proto2/public/reflection.py.
+const char kDescriptorKey[] = "DESCRIPTOR";
+
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor *file) {
+ return file->service_count() > 0 &&
+ file->options().py_generic_services();
+}
+
+
+// Prints the common boilerplate needed at the top of every .py
+// file output by this generator.
+void PrintTopBoilerplate(
+ io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) {
+ // TODO(robinson): Allow parameterization of Python version?
+ printer->Print(
+ "# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "\n"
+ "from google.protobuf import descriptor\n"
+ "from google.protobuf import message\n"
+ "from google.protobuf import reflection\n");
+ if (HasGenericServices(file)) {
+ printer->Print(
+ "from google.protobuf import service\n"
+ "from google.protobuf import service_reflection\n");
+ }
+
+ // Avoid circular imports if this module is descriptor_pb2.
+ if (!descriptor_proto) {
+ printer->Print(
+ "from google.protobuf import descriptor_pb2\n");
+ }
+ printer->Print(
+ "# @@protoc_insertion_point(imports)\n");
+ printer->Print("\n\n");
+}
+
+
+// Returns a Python literal giving the default value for a field.
+// If the field specifies no explicit default value, we'll return
+// the default default value for the field type (zero for numbers,
+// empty string for strings, empty list for repeated fields, and
+// None for non-repeated, composite fields).
+//
+// TODO(robinson): Unify with code from
+// //compiler/cpp/internal/primitive_field.cc
+// //compiler/cpp/internal/enum_field.cc
+// //compiler/cpp/internal/string_field.cc
+string StringifyDefaultValue(const FieldDescriptor& field) {
+ if (field.is_repeated()) {
+ return "[]";
+ }
+
+ switch (field.cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return SimpleItoa(field.default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return SimpleItoa(field.default_value_uint32());
+ case FieldDescriptor::CPPTYPE_INT64:
+ return SimpleItoa(field.default_value_int64());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return SimpleItoa(field.default_value_uint64());
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field.default_value_double();
+ if (value == numeric_limits<double>::infinity()) {
+ // Python pre-2.6 on Windows does not parse "inf" correctly. However,
+ // a numeric literal that is too big for a double will become infinity.
+ return "1e10000";
+ } else if (value == -numeric_limits<double>::infinity()) {
+ // See above.
+ return "-1e10000";
+ } else if (value != value) {
+ // infinity * 0 = nan
+ return "(1e10000 * 0)";
+ } else {
+ return SimpleDtoa(value);
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ float value = field.default_value_float();
+ if (value == numeric_limits<float>::infinity()) {
+ // Python pre-2.6 on Windows does not parse "inf" correctly. However,
+ // a numeric literal that is too big for a double will become infinity.
+ return "1e10000";
+ } else if (value == -numeric_limits<float>::infinity()) {
+ // See above.
+ return "-1e10000";
+ } else if (value != value) {
+ // infinity - infinity = nan
+ return "(1e10000 * 0)";
+ } else {
+ return SimpleFtoa(value);
+ }
+ }
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field.default_value_bool() ? "True" : "False";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return SimpleItoa(field.default_value_enum()->number());
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (field.type() == FieldDescriptor::TYPE_STRING) {
+ return "unicode(\"" + CEscape(field.default_value_string()) +
+ "\", \"utf-8\")";
+ } else {
+ return "\"" + CEscape(field.default_value_string()) + "\"";
+ }
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return "None";
+ }
+ // (We could add a default case above but then we wouldn't get the nice
+ // compiler warning when a new type is added.)
+ GOOGLE_LOG(FATAL) << "Not reached.";
+ return "";
+}
+
+
+
+} // namespace
+
+
+Generator::Generator() : file_(NULL) {
+}
+
+Generator::~Generator() {
+}
+
+bool Generator::Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+
+ // Completely serialize all Generate() calls on this instance. The
+ // thread-safety constraints of the CodeGenerator interface aren't clear so
+ // just be as conservative as possible. It's easier to relax this later if
+ // we need to, but I doubt it will be an issue.
+ // TODO(kenton): The proper thing to do would be to allocate any state on
+ // the stack and use that, so that the Generator class itself does not need
+ // to have any mutable members. Then it is implicitly thread-safe.
+ MutexLock lock(&mutex_);
+ file_ = file;
+ string module_name = ModuleName(file->name());
+ string filename = module_name;
+ StripString(&filename, ".", '/');
+ filename += ".py";
+
+ FileDescriptorProto fdp;
+ file_->CopyTo(&fdp);
+ fdp.SerializeToString(&file_descriptor_serialized_);
+
+
+ scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+ GOOGLE_CHECK(output.get());
+ io::Printer printer(output.get(), '$');
+ printer_ = &printer;
+
+ PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
+ PrintImports();
+ PrintFileDescriptor();
+ PrintTopLevelEnums();
+ PrintTopLevelExtensions();
+ PrintAllNestedEnumsInFile();
+ PrintMessageDescriptors();
+ FixForeignFieldsInDescriptors();
+ PrintMessages();
+ // We have to fix up the extensions after the message classes themselves,
+ // since they need to call static RegisterExtension() methods on these
+ // classes.
+ FixForeignFieldsInExtensions();
+ if (HasGenericServices(file)) {
+ PrintServices();
+ }
+
+ printer.Print(
+ "# @@protoc_insertion_point(module_scope)\n");
+
+ return !printer.failed();
+}
+
+// Prints Python imports for all modules imported by |file|.
+void Generator::PrintImports() const {
+ for (int i = 0; i < file_->dependency_count(); ++i) {
+ string module_name = ModuleName(file_->dependency(i)->name());
+ printer_->Print("import $module$\n", "module",
+ module_name);
+ }
+ printer_->Print("\n");
+}
+
+// Prints the single file descriptor for this file.
+void Generator::PrintFileDescriptor() const {
+ map<string, string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["name"] = file_->name();
+ m["package"] = file_->package();
+ const char file_descriptor_template[] =
+ "$descriptor_name$ = descriptor.FileDescriptor(\n"
+ " name='$name$',\n"
+ " package='$package$',\n";
+ printer_->Print(m, file_descriptor_template);
+ printer_->Indent();
+ printer_->Print(
+ "serialized_pb='$value$'",
+ "value", strings::CHexEscape(file_descriptor_serialized_));
+
+ // TODO(falk): Also print options and fix the message_type, enum_type,
+ // service and extension later in the generation.
+
+ printer_->Outdent();
+ printer_->Print(")\n");
+ printer_->Print("\n");
+}
+
+// Prints descriptors and module-level constants for all top-level
+// enums defined in |file|.
+void Generator::PrintTopLevelEnums() const {
+ vector<pair<string, int> > top_level_enum_values;
+ for (int i = 0; i < file_->enum_type_count(); ++i) {
+ const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
+ PrintEnum(enum_descriptor);
+ printer_->Print("\n");
+
+ for (int j = 0; j < enum_descriptor.value_count(); ++j) {
+ const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j);
+ top_level_enum_values.push_back(
+ make_pair(value_descriptor.name(), value_descriptor.number()));
+ }
+ }
+
+ for (int i = 0; i < top_level_enum_values.size(); ++i) {
+ printer_->Print("$name$ = $value$\n",
+ "name", top_level_enum_values[i].first,
+ "value", SimpleItoa(top_level_enum_values[i].second));
+ }
+ printer_->Print("\n");
+}
+
+// Prints all enums contained in all message types in |file|.
+void Generator::PrintAllNestedEnumsInFile() const {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ PrintNestedEnums(*file_->message_type(i));
+ }
+}
+
+// Prints a Python statement assigning the appropriate module-level
+// enum name to a Python EnumDescriptor object equivalent to
+// enum_descriptor.
+void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
+ map<string, string> m;
+ m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor);
+ m["name"] = enum_descriptor.name();
+ m["full_name"] = enum_descriptor.full_name();
+ m["file"] = kDescriptorKey;
+ const char enum_descriptor_template[] =
+ "$descriptor_name$ = descriptor.EnumDescriptor(\n"
+ " name='$name$',\n"
+ " full_name='$full_name$',\n"
+ " filename=None,\n"
+ " file=$file$,\n"
+ " values=[\n";
+ string options_string;
+ enum_descriptor.options().SerializeToString(&options_string);
+ printer_->Print(m, enum_descriptor_template);
+ printer_->Indent();
+ printer_->Indent();
+ for (int i = 0; i < enum_descriptor.value_count(); ++i) {
+ PrintEnumValueDescriptor(*enum_descriptor.value(i));
+ printer_->Print(",\n");
+ }
+ printer_->Outdent();
+ printer_->Print("],\n");
+ printer_->Print("containing_type=None,\n");
+ printer_->Print("options=$options_value$,\n",
+ "options_value",
+ OptionsValue("EnumOptions", options_string));
+ EnumDescriptorProto edp;
+ PrintSerializedPbInterval(enum_descriptor, edp);
+ printer_->Outdent();
+ printer_->Print(")\n");
+ printer_->Print("\n");
+}
+
+// Recursively prints enums in nested types within descriptor, then
+// prints enums contained at the top level in descriptor.
+void Generator::PrintNestedEnums(const Descriptor& descriptor) const {
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ PrintNestedEnums(*descriptor.nested_type(i));
+ }
+
+ for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+ PrintEnum(*descriptor.enum_type(i));
+ }
+}
+
+void Generator::PrintTopLevelExtensions() const {
+ const bool is_extension = true;
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ const FieldDescriptor& extension_field = *file_->extension(i);
+ string constant_name = extension_field.name() + "_FIELD_NUMBER";
+ UpperString(&constant_name);
+ printer_->Print("$constant_name$ = $number$\n",
+ "constant_name", constant_name,
+ "number", SimpleItoa(extension_field.number()));
+ printer_->Print("$name$ = ", "name", extension_field.name());
+ PrintFieldDescriptor(extension_field, is_extension);
+ printer_->Print("\n");
+ }
+ printer_->Print("\n");
+}
+
+// Prints Python equivalents of all Descriptors in |file|.
+void Generator::PrintMessageDescriptors() const {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ PrintDescriptor(*file_->message_type(i));
+ printer_->Print("\n");
+ }
+}
+
+void Generator::PrintServices() const {
+ for (int i = 0; i < file_->service_count(); ++i) {
+ PrintServiceDescriptor(*file_->service(i));
+ PrintServiceClass(*file_->service(i));
+ PrintServiceStub(*file_->service(i));
+ printer_->Print("\n");
+ }
+}
+
+void Generator::PrintServiceDescriptor(
+ const ServiceDescriptor& descriptor) const {
+ printer_->Print("\n");
+ string service_name = ModuleLevelServiceDescriptorName(descriptor);
+ string options_string;
+ descriptor.options().SerializeToString(&options_string);
+
+ printer_->Print(
+ "$service_name$ = descriptor.ServiceDescriptor(\n",
+ "service_name", service_name);
+ printer_->Indent();
+ map<string, string> m;
+ m["name"] = descriptor.name();
+ m["full_name"] = descriptor.full_name();
+ m["file"] = kDescriptorKey;
+ m["index"] = SimpleItoa(descriptor.index());
+ m["options_value"] = OptionsValue("ServiceOptions", options_string);
+ const char required_function_arguments[] =
+ "name='$name$',\n"
+ "full_name='$full_name$',\n"
+ "file=$file$,\n"
+ "index=$index$,\n"
+ "options=$options_value$,\n";
+ printer_->Print(m, required_function_arguments);
+
+ ServiceDescriptorProto sdp;
+ PrintSerializedPbInterval(descriptor, sdp);
+
+ printer_->Print("methods=[\n");
+ for (int i = 0; i < descriptor.method_count(); ++i) {
+ const MethodDescriptor* method = descriptor.method(i);
+ string options_string;
+ method->options().SerializeToString(&options_string);
+
+ m.clear();
+ m["name"] = method->name();
+ m["full_name"] = method->full_name();
+ m["index"] = SimpleItoa(method->index());
+ m["serialized_options"] = CEscape(options_string);
+ m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
+ m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
+ m["options_value"] = OptionsValue("MethodOptions", options_string);
+ printer_->Print("descriptor.MethodDescriptor(\n");
+ printer_->Indent();
+ printer_->Print(
+ m,
+ "name='$name$',\n"
+ "full_name='$full_name$',\n"
+ "index=$index$,\n"
+ "containing_service=None,\n"
+ "input_type=$input_type$,\n"
+ "output_type=$output_type$,\n"
+ "options=$options_value$,\n");
+ printer_->Outdent();
+ printer_->Print("),\n");
+ }
+
+ printer_->Outdent();
+ printer_->Print("])\n\n");
+}
+
+void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
+ // Print the service.
+ printer_->Print("class $class_name$(service.Service):\n",
+ "class_name", descriptor.name());
+ printer_->Indent();
+ printer_->Print(
+ "__metaclass__ = service_reflection.GeneratedServiceType\n"
+ "$descriptor_key$ = $descriptor_name$\n",
+ "descriptor_key", kDescriptorKey,
+ "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
+ printer_->Outdent();
+}
+
+void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
+ // Print the service stub.
+ printer_->Print("class $class_name$_Stub($class_name$):\n",
+ "class_name", descriptor.name());
+ printer_->Indent();
+ printer_->Print(
+ "__metaclass__ = service_reflection.GeneratedServiceStubType\n"
+ "$descriptor_key$ = $descriptor_name$\n",
+ "descriptor_key", kDescriptorKey,
+ "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
+ printer_->Outdent();
+}
+
+// Prints statement assigning ModuleLevelDescriptorName(message_descriptor)
+// to a Python Descriptor object for message_descriptor.
+//
+// Mutually recursive with PrintNestedDescriptors().
+void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
+ PrintNestedDescriptors(message_descriptor);
+
+ printer_->Print("\n");
+ printer_->Print("$descriptor_name$ = descriptor.Descriptor(\n",
+ "descriptor_name",
+ ModuleLevelDescriptorName(message_descriptor));
+ printer_->Indent();
+ map<string, string> m;
+ m["name"] = message_descriptor.name();
+ m["full_name"] = message_descriptor.full_name();
+ m["file"] = kDescriptorKey;
+ const char required_function_arguments[] =
+ "name='$name$',\n"
+ "full_name='$full_name$',\n"
+ "filename=None,\n"
+ "file=$file$,\n"
+ "containing_type=None,\n";
+ printer_->Print(m, required_function_arguments);
+ PrintFieldsInDescriptor(message_descriptor);
+ PrintExtensionsInDescriptor(message_descriptor);
+
+ // Nested types
+ printer_->Print("nested_types=[");
+ for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
+ const string nested_name = ModuleLevelDescriptorName(
+ *message_descriptor.nested_type(i));
+ printer_->Print("$name$, ", "name", nested_name);
+ }
+ printer_->Print("],\n");
+
+ // Enum types
+ printer_->Print("enum_types=[\n");
+ printer_->Indent();
+ for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
+ const string descriptor_name = ModuleLevelDescriptorName(
+ *message_descriptor.enum_type(i));
+ printer_->Print(descriptor_name.c_str());
+ printer_->Print(",\n");
+ }
+ printer_->Outdent();
+ printer_->Print("],\n");
+ string options_string;
+ message_descriptor.options().SerializeToString(&options_string);
+ printer_->Print(
+ "options=$options_value$,\n"
+ "is_extendable=$extendable$",
+ "options_value", OptionsValue("MessageOptions", options_string),
+ "extendable", message_descriptor.extension_range_count() > 0 ?
+ "True" : "False");
+ printer_->Print(",\n");
+
+ // Extension ranges
+ printer_->Print("extension_ranges=[");
+ for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
+ const Descriptor::ExtensionRange* range =
+ message_descriptor.extension_range(i);
+ printer_->Print("($start$, $end$), ",
+ "start", SimpleItoa(range->start),
+ "end", SimpleItoa(range->end));
+ }
+ printer_->Print("],\n");
+
+ // Serialization of proto
+ DescriptorProto edp;
+ PrintSerializedPbInterval(message_descriptor, edp);
+
+ printer_->Outdent();
+ printer_->Print(")\n");
+}
+
+// Prints Python Descriptor objects for all nested types contained in
+// message_descriptor.
+//
+// Mutually recursive with PrintDescriptor().
+void Generator::PrintNestedDescriptors(
+ const Descriptor& containing_descriptor) const {
+ for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
+ PrintDescriptor(*containing_descriptor.nested_type(i));
+ }
+}
+
+// Prints all messages in |file|.
+void Generator::PrintMessages() const {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ PrintMessage(*file_->message_type(i));
+ printer_->Print("\n");
+ }
+}
+
+// Prints a Python class for the given message descriptor. We defer to the
+// metaclass to do almost all of the work of actually creating a useful class.
+// The purpose of this function and its many helper functions above is merely
+// to output a Python version of the descriptors, which the metaclass in
+// reflection.py will use to construct the meat of the class itself.
+//
+// Mutually recursive with PrintNestedMessages().
+void Generator::PrintMessage(
+ const Descriptor& message_descriptor) const {
+ printer_->Print("class $name$(message.Message):\n", "name",
+ message_descriptor.name());
+ printer_->Indent();
+ printer_->Print("__metaclass__ = reflection.GeneratedProtocolMessageType\n");
+ PrintNestedMessages(message_descriptor);
+ map<string, string> m;
+ m["descriptor_key"] = kDescriptorKey;
+ m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
+ printer_->Print(m, "$descriptor_key$ = $descriptor_name$\n");
+
+ printer_->Print(
+ "\n"
+ "# @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", message_descriptor.full_name());
+
+ printer_->Outdent();
+}
+
+// Prints all nested messages within |containing_descriptor|.
+// Mutually recursive with PrintMessage().
+void Generator::PrintNestedMessages(
+ const Descriptor& containing_descriptor) const {
+ for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
+ printer_->Print("\n");
+ PrintMessage(*containing_descriptor.nested_type(i));
+ }
+}
+
+// Recursively fixes foreign fields in all nested types in |descriptor|, then
+// sets the message_type and enum_type of all message and enum fields to point
+// to their respective descriptors.
+// Args:
+// descriptor: descriptor to print fields for.
+// containing_descriptor: if descriptor is a nested type, this is its
+// containing type, or NULL if this is a root/top-level type.
+void Generator::FixForeignFieldsInDescriptor(
+ const Descriptor& descriptor,
+ const Descriptor* containing_descriptor) const {
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor);
+ }
+
+ for (int i = 0; i < descriptor.field_count(); ++i) {
+ const FieldDescriptor& field_descriptor = *descriptor.field(i);
+ FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
+ }
+
+ FixContainingTypeInDescriptor(descriptor, containing_descriptor);
+ for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+ const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
+ FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
+ }
+}
+
+void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
+ map<string, string> m;
+ m["descriptor_name"] = kDescriptorKey;
+ m["message_name"] = descriptor.name();
+ m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+ const char file_descriptor_template[] =
+ "$descriptor_name$.message_types_by_name['$message_name$'] = "
+ "$message_descriptor_name$\n";
+ printer_->Print(m, file_descriptor_template);
+}
+
+// Sets any necessary message_type and enum_type attributes
+// for the Python version of |field|.
+//
+// containing_type may be NULL, in which case this is a module-level field.
+//
+// python_dict_name is the name of the Python dict where we should
+// look the field up in the containing type. (e.g., fields_by_name
+// or extensions_by_name). We ignore python_dict_name if containing_type
+// is NULL.
+void Generator::FixForeignFieldsInField(const Descriptor* containing_type,
+ const FieldDescriptor& field,
+ const string& python_dict_name) const {
+ const string field_referencing_expression = FieldReferencingExpression(
+ containing_type, field, python_dict_name);
+ map<string, string> m;
+ m["field_ref"] = field_referencing_expression;
+ const Descriptor* foreign_message_type = field.message_type();
+ if (foreign_message_type) {
+ m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type);
+ printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n");
+ }
+ const EnumDescriptor* enum_type = field.enum_type();
+ if (enum_type) {
+ m["enum_type"] = ModuleLevelDescriptorName(*enum_type);
+ printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n");
+ }
+}
+
+// Returns the module-level expression for the given FieldDescriptor.
+// Only works for fields in the .proto file this Generator is generating for.
+//
+// containing_type may be NULL, in which case this is a module-level field.
+//
+// python_dict_name is the name of the Python dict where we should
+// look the field up in the containing type. (e.g., fields_by_name
+// or extensions_by_name). We ignore python_dict_name if containing_type
+// is NULL.
+string Generator::FieldReferencingExpression(
+ const Descriptor* containing_type,
+ const FieldDescriptor& field,
+ const string& python_dict_name) const {
+ // We should only ever be looking up fields in the current file.
+ // The only things we refer to from other files are message descriptors.
+ GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. "
+ << file_->name();
+ if (!containing_type) {
+ return field.name();
+ }
+ return strings::Substitute(
+ "$0.$1['$2']",
+ ModuleLevelDescriptorName(*containing_type),
+ python_dict_name, field.name());
+}
+
+// Prints containing_type for nested descriptors or enum descriptors.
+template <typename DescriptorT>
+void Generator::FixContainingTypeInDescriptor(
+ const DescriptorT& descriptor,
+ const Descriptor* containing_descriptor) const {
+ if (containing_descriptor != NULL) {
+ const string nested_name = ModuleLevelDescriptorName(descriptor);
+ const string parent_name = ModuleLevelDescriptorName(
+ *containing_descriptor);
+ printer_->Print(
+ "$nested_name$.containing_type = $parent_name$;\n",
+ "nested_name", nested_name,
+ "parent_name", parent_name);
+ }
+}
+
+// Prints statements setting the message_type and enum_type fields in the
+// Python descriptor objects we've already output in ths file. We must
+// do this in a separate step due to circular references (otherwise, we'd
+// just set everything in the initial assignment statements).
+void Generator::FixForeignFieldsInDescriptors() const {
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ FixForeignFieldsInDescriptor(*file_->message_type(i), NULL);
+ }
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ AddMessageToFileDescriptor(*file_->message_type(i));
+ }
+ printer_->Print("\n");
+}
+
+// We need to not only set any necessary message_type fields, but
+// also need to call RegisterExtension() on each message we're
+// extending.
+void Generator::FixForeignFieldsInExtensions() const {
+ // Top-level extensions.
+ for (int i = 0; i < file_->extension_count(); ++i) {
+ FixForeignFieldsInExtension(*file_->extension(i));
+ }
+ // Nested extensions.
+ for (int i = 0; i < file_->message_type_count(); ++i) {
+ FixForeignFieldsInNestedExtensions(*file_->message_type(i));
+ }
+}
+
+void Generator::FixForeignFieldsInExtension(
+ const FieldDescriptor& extension_field) const {
+ GOOGLE_CHECK(extension_field.is_extension());
+ // extension_scope() will be NULL for top-level extensions, which is
+ // exactly what FixForeignFieldsInField() wants.
+ FixForeignFieldsInField(extension_field.extension_scope(), extension_field,
+ "extensions_by_name");
+
+ map<string, string> m;
+ // Confusingly, for FieldDescriptors that happen to be extensions,
+ // containing_type() means "extended type."
+ // On the other hand, extension_scope() will give us what we normally
+ // mean by containing_type().
+ m["extended_message_class"] = ModuleLevelMessageName(
+ *extension_field.containing_type());
+ m["field"] = FieldReferencingExpression(extension_field.extension_scope(),
+ extension_field,
+ "extensions_by_name");
+ printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n");
+}
+
+void Generator::FixForeignFieldsInNestedExtensions(
+ const Descriptor& descriptor) const {
+ // Recursively fix up extensions in all nested types.
+ for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+ FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i));
+ }
+ // Fix up extensions directly contained within this type.
+ for (int i = 0; i < descriptor.extension_count(); ++i) {
+ FixForeignFieldsInExtension(*descriptor.extension(i));
+ }
+}
+
+// Returns a Python expression that instantiates a Python EnumValueDescriptor
+// object for the given C++ descriptor.
+void Generator::PrintEnumValueDescriptor(
+ const EnumValueDescriptor& descriptor) const {
+ // TODO(robinson): Fix up EnumValueDescriptor "type" fields.
+ // More circular references. ::sigh::
+ string options_string;
+ descriptor.options().SerializeToString(&options_string);
+ map<string, string> m;
+ m["name"] = descriptor.name();
+ m["index"] = SimpleItoa(descriptor.index());
+ m["number"] = SimpleItoa(descriptor.number());
+ m["options"] = OptionsValue("EnumValueOptions", options_string);
+ printer_->Print(
+ m,
+ "descriptor.EnumValueDescriptor(\n"
+ " name='$name$', index=$index$, number=$number$,\n"
+ " options=$options$,\n"
+ " type=None)");
+}
+
+// Returns a Python expression that calls descriptor._ParseOptions using
+// the given descriptor class name and serialized options protobuf string.
+string Generator::OptionsValue(
+ const string& class_name, const string& serialized_options) const {
+ if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
+ return "None";
+ } else {
+ string full_class_name = "descriptor_pb2." + class_name;
+ return "descriptor._ParseOptions(" + full_class_name + "(), '"
+ + CEscape(serialized_options)+ "')";
+ }
+}
+
+// Prints an expression for a Python FieldDescriptor for |field|.
+void Generator::PrintFieldDescriptor(
+ const FieldDescriptor& field, bool is_extension) const {
+ string options_string;
+ field.options().SerializeToString(&options_string);
+ map<string, string> m;
+ m["name"] = field.name();
+ m["full_name"] = field.full_name();
+ m["index"] = SimpleItoa(field.index());
+ m["number"] = SimpleItoa(field.number());
+ m["type"] = SimpleItoa(field.type());
+ m["cpp_type"] = SimpleItoa(field.cpp_type());
+ m["label"] = SimpleItoa(field.label());
+ m["has_default_value"] = field.has_default_value() ? "True" : "False";
+ m["default_value"] = StringifyDefaultValue(field);
+ m["is_extension"] = is_extension ? "True" : "False";
+ m["options"] = OptionsValue("FieldOptions", options_string);
+ // We always set message_type and enum_type to None at this point, and then
+ // these fields in correctly after all referenced descriptors have been
+ // defined and/or imported (see FixForeignFieldsInDescriptors()).
+ const char field_descriptor_decl[] =
+ "descriptor.FieldDescriptor(\n"
+ " name='$name$', full_name='$full_name$', index=$index$,\n"
+ " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
+ " has_default_value=$has_default_value$, default_value=$default_value$,\n"
+ " message_type=None, enum_type=None, containing_type=None,\n"
+ " is_extension=$is_extension$, extension_scope=None,\n"
+ " options=$options$)";
+ printer_->Print(m, field_descriptor_decl);
+}
+
+// Helper for Print{Fields,Extensions}InDescriptor().
+void Generator::PrintFieldDescriptorsInDescriptor(
+ const Descriptor& message_descriptor,
+ bool is_extension,
+ const string& list_variable_name,
+ int (Descriptor::*CountFn)() const,
+ const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const {
+ printer_->Print("$list$=[\n", "list", list_variable_name);
+ printer_->Indent();
+ for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
+ PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i),
+ is_extension);
+ printer_->Print(",\n");
+ }
+ printer_->Outdent();
+ printer_->Print("],\n");
+}
+
+// Prints a statement assigning "fields" to a list of Python FieldDescriptors,
+// one for each field present in message_descriptor.
+void Generator::PrintFieldsInDescriptor(
+ const Descriptor& message_descriptor) const {
+ const bool is_extension = false;
+ PrintFieldDescriptorsInDescriptor(
+ message_descriptor, is_extension, "fields",
+ &Descriptor::field_count, &Descriptor::field);
+}
+
+// Prints a statement assigning "extensions" to a list of Python
+// FieldDescriptors, one for each extension present in message_descriptor.
+void Generator::PrintExtensionsInDescriptor(
+ const Descriptor& message_descriptor) const {
+ const bool is_extension = true;
+ PrintFieldDescriptorsInDescriptor(
+ message_descriptor, is_extension, "extensions",
+ &Descriptor::extension_count, &Descriptor::extension);
+}
+
+bool Generator::GeneratingDescriptorProto() const {
+ return file_->name() == "google/protobuf/descriptor.proto";
+}
+
+// Returns the unique Python module-level identifier given to a descriptor.
+// This name is module-qualified iff the given descriptor describes an
+// entity that doesn't come from the current file.
+template <typename DescriptorT>
+string Generator::ModuleLevelDescriptorName(
+ const DescriptorT& descriptor) const {
+ // FIXME(robinson):
+ // We currently don't worry about collisions with underscores in the type
+ // names, so these would collide in nasty ways if found in the same file:
+ // OuterProto.ProtoA.ProtoB
+ // OuterProto_ProtoA.ProtoB # Underscore instead of period.
+ // As would these:
+ // OuterProto.ProtoA_.ProtoB
+ // OuterProto.ProtoA._ProtoB # Leading vs. trailing underscore.
+ // (Contrived, but certainly possible).
+ //
+ // The C++ implementation doesn't guard against this either. Leaving
+ // it for now...
+ string name = NamePrefixedWithNestedTypes(descriptor, "_");
+ UpperString(&name);
+ // Module-private for now. Easy to make public later; almost impossible
+ // to make private later.
+ name = "_" + name;
+ // We now have the name relative to its own module. Also qualify with
+ // the module name iff this descriptor is from a different .proto file.
+ if (descriptor.file() != file_) {
+ name = ModuleName(descriptor.file()->name()) + "." + name;
+ }
+ return name;
+}
+
+// Returns the name of the message class itself, not the descriptor.
+// Like ModuleLevelDescriptorName(), module-qualifies the name iff
+// the given descriptor describes an entity that doesn't come from
+// the current file.
+string Generator::ModuleLevelMessageName(const Descriptor& descriptor) const {
+ string name = NamePrefixedWithNestedTypes(descriptor, ".");
+ if (descriptor.file() != file_) {
+ name = ModuleName(descriptor.file()->name()) + "." + name;
+ }
+ return name;
+}
+
+// Returns the unique Python module-level identifier given to a service
+// descriptor.
+string Generator::ModuleLevelServiceDescriptorName(
+ const ServiceDescriptor& descriptor) const {
+ string name = descriptor.name();
+ UpperString(&name);
+ name = "_" + name;
+ if (descriptor.file() != file_) {
+ name = ModuleName(descriptor.file()->name()) + "." + name;
+ }
+ return name;
+}
+
+// Prints standard constructor arguments serialized_start and serialized_end.
+// Args:
+// descriptor: The cpp descriptor to have a serialized reference.
+// proto: A proto
+// Example printer output:
+// serialized_start=41,
+// serialized_end=43,
+//
+template <typename DescriptorT, typename DescriptorProtoT>
+void Generator::PrintSerializedPbInterval(
+ const DescriptorT& descriptor, DescriptorProtoT& proto) const {
+ descriptor.CopyTo(&proto);
+ string sp;
+ proto.SerializeToString(&sp);
+ int offset = file_descriptor_serialized_.find(sp);
+ GOOGLE_CHECK_GE(offset, 0);
+
+ printer_->Print("serialized_start=$serialized_start$,\n"
+ "serialized_end=$serialized_end$,\n",
+ "serialized_start", SimpleItoa(offset),
+ "serialized_end", SimpleItoa(offset + sp.size()));
+}
+
+} // namespace python
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h b/src/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h
new file mode 100644
index 0000000..84eaf8a
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h
@@ -0,0 +1,156 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: robinson@google.com (Will Robinson)
+//
+// Generates Python code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
+
+#include <string>
+
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+class Descriptor;
+class EnumDescriptor;
+class EnumValueDescriptor;
+class FieldDescriptor;
+class ServiceDescriptor;
+
+namespace io { class Printer; }
+
+namespace compiler {
+namespace python {
+
+// CodeGenerator implementation for generated Python protocol buffer classes.
+// If you create your own protocol compiler binary and you want it to support
+// Python output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class LIBPROTOC_EXPORT Generator : public CodeGenerator {
+ public:
+ Generator();
+ virtual ~Generator();
+
+ // CodeGenerator methods.
+ virtual bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* generator_context,
+ string* error) const;
+
+ private:
+ void PrintImports() const;
+ void PrintFileDescriptor() const;
+ void PrintTopLevelEnums() const;
+ void PrintAllNestedEnumsInFile() const;
+ void PrintNestedEnums(const Descriptor& descriptor) const;
+ void PrintEnum(const EnumDescriptor& enum_descriptor) const;
+
+ void PrintTopLevelExtensions() const;
+
+ void PrintFieldDescriptor(
+ const FieldDescriptor& field, bool is_extension) const;
+ void PrintFieldDescriptorsInDescriptor(
+ const Descriptor& message_descriptor,
+ bool is_extension,
+ const string& list_variable_name,
+ int (Descriptor::*CountFn)() const,
+ const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const;
+ void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const;
+ void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const;
+ void PrintMessageDescriptors() const;
+ void PrintDescriptor(const Descriptor& message_descriptor) const;
+ void PrintNestedDescriptors(const Descriptor& containing_descriptor) const;
+
+ void PrintMessages() const;
+ void PrintMessage(const Descriptor& message_descriptor) const;
+ void PrintNestedMessages(const Descriptor& containing_descriptor) const;
+
+ void FixForeignFieldsInDescriptors() const;
+ void FixForeignFieldsInDescriptor(
+ const Descriptor& descriptor,
+ const Descriptor* containing_descriptor) const;
+ void FixForeignFieldsInField(const Descriptor* containing_type,
+ const FieldDescriptor& field,
+ const string& python_dict_name) const;
+ void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
+ string FieldReferencingExpression(const Descriptor* containing_type,
+ const FieldDescriptor& field,
+ const string& python_dict_name) const;
+ template <typename DescriptorT>
+ void FixContainingTypeInDescriptor(
+ const DescriptorT& descriptor,
+ const Descriptor* containing_descriptor) const;
+
+ void FixForeignFieldsInExtensions() const;
+ void FixForeignFieldsInExtension(
+ const FieldDescriptor& extension_field) const;
+ void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const;
+
+ void PrintServices() const;
+ void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const;
+ void PrintServiceClass(const ServiceDescriptor& descriptor) const;
+ void PrintServiceStub(const ServiceDescriptor& descriptor) const;
+
+ void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const;
+ string OptionsValue(const string& class_name,
+ const string& serialized_options) const;
+ bool GeneratingDescriptorProto() const;
+
+ template <typename DescriptorT>
+ string ModuleLevelDescriptorName(const DescriptorT& descriptor) const;
+ string ModuleLevelMessageName(const Descriptor& descriptor) const;
+ string ModuleLevelServiceDescriptorName(
+ const ServiceDescriptor& descriptor) const;
+
+ template <typename DescriptorT, typename DescriptorProtoT>
+ void PrintSerializedPbInterval(
+ const DescriptorT& descriptor, DescriptorProtoT& proto) const;
+
+ // Very coarse-grained lock to ensure that Generate() is reentrant.
+ // Guards file_, printer_ and file_descriptor_serialized_.
+ mutable Mutex mutex_;
+ mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_.
+ mutable string file_descriptor_serialized_;
+ mutable io::Printer* printer_; // Set in Generate(). Under mutex_.
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
+};
+
+} // namespace python
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc
new file mode 100644
index 0000000..da619ad
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc
@@ -0,0 +1,116 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// TODO(kenton): Share code with the versions of this test in other languages?
+// It seemed like parameterizing it would add more complexity than it is
+// worth.
+
+#include <google/protobuf/compiler/python/python_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/printer.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace python {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+ TestGenerator() {}
+ ~TestGenerator() {}
+
+ virtual bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
+ TryInsert("test_pb2.py", "imports", context);
+ TryInsert("test_pb2.py", "module_scope", context);
+ TryInsert("test_pb2.py", "class_scope:foo.Bar", context);
+ TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", context);
+ return true;
+ }
+
+ void TryInsert(const string& filename, const string& insertion_point,
+ GeneratorContext* context) const {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->OpenForInsert(filename, insertion_point));
+ io::Printer printer(output.get(), '$');
+ printer.Print("// inserted $name$\n", "name", insertion_point);
+ }
+};
+
+// This test verifies that all the expected insertion points exist. It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(PythonPluginTest, PluginTest) {
+ File::WriteStringToFileOrDie(
+ "syntax = \"proto2\";\n"
+ "package foo;\n"
+ "message Bar {\n"
+ " message Baz {}\n"
+ "}\n",
+ TestTempDir() + "/test.proto");
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ python::Generator python_generator;
+ TestGenerator test_generator;
+ cli.RegisterGenerator("--python_out", &python_generator, "");
+ cli.RegisterGenerator("--test_out", &test_generator, "");
+
+ string proto_path = "-I" + TestTempDir();
+ string python_out = "--python_out=" + TestTempDir();
+ string test_out = "--test_out=" + TestTempDir();
+
+ const char* argv[] = {
+ "protoc",
+ proto_path.c_str(),
+ python_out.c_str(),
+ test_out.c_str(),
+ "test.proto"
+ };
+
+ EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+} // namespace
+} // namespace python
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc b/src/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc
new file mode 100644
index 0000000..5fb5d5c
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc
@@ -0,0 +1,460 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/subprocess.h>
+
+#include <algorithm>
+
+#ifndef _WIN32
+#include <errno.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <signal.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#ifdef _WIN32
+
+static void CloseHandleOrDie(HANDLE handle) {
+ if (!CloseHandle(handle)) {
+ GOOGLE_LOG(FATAL) << "CloseHandle: "
+ << Subprocess::Win32ErrorMessage(GetLastError());
+ }
+}
+
+Subprocess::Subprocess()
+ : process_start_error_(ERROR_SUCCESS),
+ child_handle_(NULL), child_stdin_(NULL), child_stdout_(NULL) {}
+
+Subprocess::~Subprocess() {
+ if (child_stdin_ != NULL) {
+ CloseHandleOrDie(child_stdin_);
+ }
+ if (child_stdout_ != NULL) {
+ CloseHandleOrDie(child_stdout_);
+ }
+}
+
+void Subprocess::Start(const string& program, SearchMode search_mode) {
+ // Create the pipes.
+ HANDLE stdin_pipe_read;
+ HANDLE stdin_pipe_write;
+ HANDLE stdout_pipe_read;
+ HANDLE stdout_pipe_write;
+
+ if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, NULL, 0)) {
+ GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError());
+ }
+ if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, NULL, 0)) {
+ GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError());
+ }
+
+ // Make child side of the pipes inheritable.
+ if (!SetHandleInformation(stdin_pipe_read,
+ HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+ GOOGLE_LOG(FATAL) << "SetHandleInformation: "
+ << Win32ErrorMessage(GetLastError());
+ }
+ if (!SetHandleInformation(stdout_pipe_write,
+ HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+ GOOGLE_LOG(FATAL) << "SetHandleInformation: "
+ << Win32ErrorMessage(GetLastError());
+ }
+
+ // Setup STARTUPINFO to redirect handles.
+ STARTUPINFOA startup_info;
+ ZeroMemory(&startup_info, sizeof(startup_info));
+ startup_info.cb = sizeof(startup_info);
+ startup_info.dwFlags = STARTF_USESTDHANDLES;
+ startup_info.hStdInput = stdin_pipe_read;
+ startup_info.hStdOutput = stdout_pipe_write;
+ startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+ if (startup_info.hStdError == INVALID_HANDLE_VALUE) {
+ GOOGLE_LOG(FATAL) << "GetStdHandle: "
+ << Win32ErrorMessage(GetLastError());
+ }
+
+ // CreateProcess() mutates its second parameter. WTF?
+ char* name_copy = strdup(program.c_str());
+
+ // Create the process.
+ PROCESS_INFORMATION process_info;
+
+ if (CreateProcessA((search_mode == SEARCH_PATH) ? NULL : program.c_str(),
+ (search_mode == SEARCH_PATH) ? name_copy : NULL,
+ NULL, // process security attributes
+ NULL, // thread security attributes
+ TRUE, // inherit handles?
+ 0, // obscure creation flags
+ NULL, // environment (inherit from parent)
+ NULL, // current directory (inherit from parent)
+ &startup_info,
+ &process_info)) {
+ child_handle_ = process_info.hProcess;
+ CloseHandleOrDie(process_info.hThread);
+ child_stdin_ = stdin_pipe_write;
+ child_stdout_ = stdout_pipe_read;
+ } else {
+ process_start_error_ = GetLastError();
+ CloseHandleOrDie(stdin_pipe_write);
+ CloseHandleOrDie(stdout_pipe_read);
+ }
+
+ CloseHandleOrDie(stdin_pipe_read);
+ CloseHandleOrDie(stdout_pipe_write);
+ free(name_copy);
+}
+
+bool Subprocess::Communicate(const Message& input, Message* output,
+ string* error) {
+ if (process_start_error_ != ERROR_SUCCESS) {
+ *error = Win32ErrorMessage(process_start_error_);
+ return false;
+ }
+
+ GOOGLE_CHECK(child_handle_ != NULL) << "Must call Start() first.";
+
+ string input_data = input.SerializeAsString();
+ string output_data;
+
+ int input_pos = 0;
+
+ while (child_stdout_ != NULL) {
+ HANDLE handles[2];
+ int handle_count = 0;
+
+ if (child_stdin_ != NULL) {
+ handles[handle_count++] = child_stdin_;
+ }
+ if (child_stdout_ != NULL) {
+ handles[handle_count++] = child_stdout_;
+ }
+
+ DWORD wait_result =
+ WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE);
+
+ HANDLE signaled_handle;
+ if (wait_result >= WAIT_OBJECT_0 &&
+ wait_result < WAIT_OBJECT_0 + handle_count) {
+ signaled_handle = handles[wait_result - WAIT_OBJECT_0];
+ } else if (wait_result == WAIT_FAILED) {
+ GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: "
+ << Win32ErrorMessage(GetLastError());
+ } else {
+ GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: Unexpected return code: "
+ << wait_result;
+ }
+
+ if (signaled_handle == child_stdin_) {
+ DWORD n;
+ if (!WriteFile(child_stdin_,
+ input_data.data() + input_pos,
+ input_data.size() - input_pos,
+ &n, NULL)) {
+ // Child closed pipe. Presumably it will report an error later.
+ // Pretend we're done for now.
+ input_pos = input_data.size();
+ } else {
+ input_pos += n;
+ }
+
+ if (input_pos == input_data.size()) {
+ // We're done writing. Close.
+ CloseHandleOrDie(child_stdin_);
+ child_stdin_ = NULL;
+ }
+ } else if (signaled_handle == child_stdout_) {
+ char buffer[4096];
+ DWORD n;
+
+ if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, NULL)) {
+ // We're done reading. Close.
+ CloseHandleOrDie(child_stdout_);
+ child_stdout_ = NULL;
+ } else {
+ output_data.append(buffer, n);
+ }
+ }
+ }
+
+ if (child_stdin_ != NULL) {
+ // Child did not finish reading input before it closed the output.
+ // Presumably it exited with an error.
+ CloseHandleOrDie(child_stdin_);
+ child_stdin_ = NULL;
+ }
+
+ DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE);
+
+ if (wait_result == WAIT_FAILED) {
+ GOOGLE_LOG(FATAL) << "WaitForSingleObject: "
+ << Win32ErrorMessage(GetLastError());
+ } else if (wait_result != WAIT_OBJECT_0) {
+ GOOGLE_LOG(FATAL) << "WaitForSingleObject: Unexpected return code: "
+ << wait_result;
+ }
+
+ DWORD exit_code;
+ if (!GetExitCodeProcess(child_handle_, &exit_code)) {
+ GOOGLE_LOG(FATAL) << "GetExitCodeProcess: "
+ << Win32ErrorMessage(GetLastError());
+ }
+
+ CloseHandleOrDie(child_handle_);
+ child_handle_ = NULL;
+
+ if (exit_code != 0) {
+ *error = strings::Substitute(
+ "Plugin failed with status code $0.", exit_code);
+ return false;
+ }
+
+ if (!output->ParseFromString(output_data)) {
+ *error = "Plugin output is unparseable: " + CEscape(output_data);
+ return false;
+ }
+
+ return true;
+}
+
+string Subprocess::Win32ErrorMessage(DWORD error_code) {
+ char* message;
+
+ // WTF?
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, error_code, 0,
+ (LPTSTR)&message, // NOT A BUG!
+ 0, NULL);
+
+ string result = message;
+ LocalFree(message);
+ return result;
+}
+
+// ===================================================================
+
+#else // _WIN32
+
+Subprocess::Subprocess()
+ : child_pid_(-1), child_stdin_(-1), child_stdout_(-1) {}
+
+Subprocess::~Subprocess() {
+ if (child_stdin_ != -1) {
+ close(child_stdin_);
+ }
+ if (child_stdout_ != -1) {
+ close(child_stdout_);
+ }
+}
+
+void Subprocess::Start(const string& program, SearchMode search_mode) {
+ // Note that we assume that there are no other threads, thus we don't have to
+ // do crazy stuff like using socket pairs or avoiding libc locks.
+
+ // [0] is read end, [1] is write end.
+ int stdin_pipe[2];
+ int stdout_pipe[2];
+
+ pipe(stdin_pipe);
+ pipe(stdout_pipe);
+
+ char* argv[2] = { strdup(program.c_str()), NULL };
+
+ child_pid_ = fork();
+ if (child_pid_ == -1) {
+ GOOGLE_LOG(FATAL) << "fork: " << strerror(errno);
+ } else if (child_pid_ == 0) {
+ // We are the child.
+ dup2(stdin_pipe[0], STDIN_FILENO);
+ dup2(stdout_pipe[1], STDOUT_FILENO);
+
+ close(stdin_pipe[0]);
+ close(stdin_pipe[1]);
+ close(stdout_pipe[0]);
+ close(stdout_pipe[1]);
+
+ switch (search_mode) {
+ case SEARCH_PATH:
+ execvp(argv[0], argv);
+ break;
+ case EXACT_NAME:
+ execv(argv[0], argv);
+ break;
+ }
+
+ // Write directly to STDERR_FILENO to avoid stdio code paths that may do
+ // stuff that is unsafe here.
+ write(STDERR_FILENO, argv[0], strlen(argv[0]));
+ const char* message = ": program not found or is not executable\n";
+ write(STDERR_FILENO, message, strlen(message));
+
+ // Must use _exit() rather than exit() to avoid flushing output buffers
+ // that will also be flushed by the parent.
+ _exit(1);
+ } else {
+ free(argv[0]);
+
+ close(stdin_pipe[0]);
+ close(stdout_pipe[1]);
+
+ child_stdin_ = stdin_pipe[1];
+ child_stdout_ = stdout_pipe[0];
+ }
+}
+
+bool Subprocess::Communicate(const Message& input, Message* output,
+ string* error) {
+
+ GOOGLE_CHECK_NE(child_stdin_, -1) << "Must call Start() first.";
+
+ // The "sighandler_t" typedef is GNU-specific, so define our own.
+ typedef void SignalHandler(int);
+
+ // Make sure SIGPIPE is disabled so that if the child dies it doesn't kill us.
+ SignalHandler* old_pipe_handler = signal(SIGPIPE, SIG_IGN);
+
+ string input_data = input.SerializeAsString();
+ string output_data;
+
+ int input_pos = 0;
+ int max_fd = max(child_stdin_, child_stdout_);
+
+ while (child_stdout_ != -1) {
+ fd_set read_fds;
+ fd_set write_fds;
+ FD_ZERO(&read_fds);
+ FD_ZERO(&write_fds);
+ if (child_stdout_ != -1) {
+ FD_SET(child_stdout_, &read_fds);
+ }
+ if (child_stdin_ != -1) {
+ FD_SET(child_stdin_, &write_fds);
+ }
+
+ if (select(max_fd + 1, &read_fds, &write_fds, NULL, NULL) < 0) {
+ if (errno == EINTR) {
+ // Interrupted by signal. Try again.
+ continue;
+ } else {
+ GOOGLE_LOG(FATAL) << "select: " << strerror(errno);
+ }
+ }
+
+ if (child_stdin_ != -1 && FD_ISSET(child_stdin_, &write_fds)) {
+ int n = write(child_stdin_, input_data.data() + input_pos,
+ input_data.size() - input_pos);
+ if (n < 0) {
+ // Child closed pipe. Presumably it will report an error later.
+ // Pretend we're done for now.
+ input_pos = input_data.size();
+ } else {
+ input_pos += n;
+ }
+
+ if (input_pos == input_data.size()) {
+ // We're done writing. Close.
+ close(child_stdin_);
+ child_stdin_ = -1;
+ }
+ }
+
+ if (child_stdout_ != -1 && FD_ISSET(child_stdout_, &read_fds)) {
+ char buffer[4096];
+ int n = read(child_stdout_, buffer, sizeof(buffer));
+
+ if (n > 0) {
+ output_data.append(buffer, n);
+ } else {
+ // We're done reading. Close.
+ close(child_stdout_);
+ child_stdout_ = -1;
+ }
+ }
+ }
+
+ if (child_stdin_ != -1) {
+ // Child did not finish reading input before it closed the output.
+ // Presumably it exited with an error.
+ close(child_stdin_);
+ child_stdin_ = -1;
+ }
+
+ int status;
+ while (waitpid(child_pid_, &status, 0) == -1) {
+ if (errno != EINTR) {
+ GOOGLE_LOG(FATAL) << "waitpid: " << strerror(errno);
+ }
+ }
+
+ // Restore SIGPIPE handling.
+ signal(SIGPIPE, old_pipe_handler);
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0) {
+ int error_code = WEXITSTATUS(status);
+ *error = strings::Substitute(
+ "Plugin failed with status code $0.", error_code);
+ return false;
+ }
+ } else if (WIFSIGNALED(status)) {
+ int signal = WTERMSIG(status);
+ *error = strings::Substitute(
+ "Plugin killed by signal $0.", signal);
+ return false;
+ } else {
+ *error = "Neither WEXITSTATUS nor WTERMSIG is true?";
+ return false;
+ }
+
+ if (!output->ParseFromString(output_data)) {
+ *error = "Plugin output is unparseable.";
+ return false;
+ }
+
+ return true;
+}
+
+#endif // !_WIN32
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/subprocess.h b/src/third_party/protobuf/src/google/protobuf/compiler/subprocess.h
new file mode 100644
index 0000000..0056496
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/subprocess.h
@@ -0,0 +1,108 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
+#define GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN // right...
+#include <windows.h>
+#else // _WIN32
+#include <sys/types.h>
+#include <unistd.h>
+#endif // !_WIN32
+#include <google/protobuf/stubs/common.h>
+
+#include <string>
+
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace compiler {
+
+// Utility class for launching sub-processes.
+class LIBPROTOC_EXPORT Subprocess {
+ public:
+ Subprocess();
+ ~Subprocess();
+
+ enum SearchMode {
+ SEARCH_PATH, // Use PATH environment variable.
+ EXACT_NAME // Program is an exact file name; don't use the PATH.
+ };
+
+ // Start the subprocess. Currently we don't provide a way to specify
+ // arguments as protoc plugins don't have any.
+ void Start(const string& program, SearchMode search_mode);
+
+ // Serialize the input message and pipe it to the subprocess's stdin, then
+ // close the pipe. Meanwhile, read from the subprocess's stdout and parse
+ // the data into *output. All this is done carefully to avoid deadlocks.
+ // Returns true if successful. On any sort of error, returns false and sets
+ // *error to a description of the problem.
+ bool Communicate(const Message& input, Message* output, string* error);
+
+#ifdef _WIN32
+ // Given an error code, returns a human-readable error message. This is
+ // defined here so that CommandLineInterface can share it.
+ static string Win32ErrorMessage(DWORD error_code);
+#endif
+
+ private:
+#ifdef _WIN32
+ DWORD process_start_error_;
+ HANDLE child_handle_;
+
+ // The file handles for our end of the child's pipes. We close each and
+ // set it to NULL when no longer needed.
+ HANDLE child_stdin_;
+ HANDLE child_stdout_;
+
+#else // _WIN32
+ pid_t child_pid_;
+
+ // The file descriptors for our end of the child's pipes. We close each and
+ // set it to -1 when no longer needed.
+ int child_stdin_;
+ int child_stdout_;
+
+#endif // !_WIN32
+};
+
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/test_plugin.cc b/src/third_party/protobuf/src/google/protobuf/compiler/test_plugin.cc
new file mode 100644
index 0000000..5cbbf3d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/test_plugin.cc
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is a dummy code generator plugin used by
+// command_line_interface_unittest.
+
+#include <string>
+#include <stdlib.h>
+#include <google/protobuf/compiler/plugin.h>
+#include <google/protobuf/compiler/mock_code_generator.h>
+#include <google/protobuf/stubs/strutil.h>
+
+int main(int argc, char* argv[]) {
+#ifdef _MSC_VER
+ // Don't print a silly message or stick a modal dialog box in my face,
+ // please.
+ _set_abort_behavior(0, ~0);
+#endif // !_MSC_VER
+
+ google::protobuf::compiler::MockCodeGenerator generator("test_plugin");
+ return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh b/src/third_party/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh
new file mode 100755
index 0000000..3a02436
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2009 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Author: kenton@google.com (Kenton Varda)
+#
+# Test protoc's zip output mode.
+
+fail() {
+ echo "$@" >&2
+ exit 1
+}
+
+TEST_TMPDIR=.
+PROTOC=./protoc
+
+echo '
+ syntax = "proto2";
+ option java_multiple_files = true;
+ option java_package = "test.jar";
+ option java_outer_classname = "Outer";
+ message Foo {}
+ message Bar {}
+' > $TEST_TMPDIR/testzip.proto
+
+$PROTOC \
+ --cpp_out=$TEST_TMPDIR/testzip.zip --python_out=$TEST_TMPDIR/testzip.zip \
+ --java_out=$TEST_TMPDIR/testzip.jar -I$TEST_TMPDIR testzip.proto \
+ || fail 'protoc failed.'
+
+echo "Testing output to zip..."
+if unzip -h > /dev/null; then
+ unzip -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list || fail 'unzip failed.'
+
+ grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'testzip.pb.cc not found in output zip.'
+ grep 'testing: testzip\.pb\.h *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'testzip.pb.h not found in output zip.'
+ grep 'testing: testzip_pb2\.py *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'testzip_pb2.py not found in output zip.'
+ grep -i 'manifest' $TEST_TMPDIR/testzip.list > /dev/null \
+ && fail 'Zip file contained manifest.'
+else
+ echo "Warning: 'unzip' command not available. Skipping test."
+fi
+
+echo "Testing output to jar..."
+if jar c $TEST_TMPDIR/testzip.proto > /dev/null; then
+ jar tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list || fail 'jar failed.'
+
+ grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Foo.java not found in output jar.'
+ grep '^test/jar/Bar\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Bar.java not found in output jar.'
+ grep '^test/jar/Outer\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Outer.java not found in output jar.'
+ grep '^META-INF/MANIFEST\.MF$' $TEST_TMPDIR/testzip.list > /dev/null \
+ || fail 'Manifest not found in output jar.'
+else
+ echo "Warning: 'jar' command not available. Skipping test."
+fi
+
+echo PASS
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/zip_writer.cc b/src/third_party/protobuf/src/google/protobuf/compiler/zip_writer.cc
new file mode 100644
index 0000000..65d7352
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/zip_writer.cc
@@ -0,0 +1,218 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: ambrose@google.com (Ambrose Feinstein),
+// kenton@google.com (Kenton Varda)
+//
+// Based on http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+
+#include <google/protobuf/compiler/zip_writer.h>
+#include <google/protobuf/io/coded_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+static const uint32 kCRC32Table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+static uint32 ComputeCRC32(const string &buf) {
+ uint32 x = ~0U;
+ for (int i = 0; i < buf.size(); ++i) {
+ unsigned char c = buf[i];
+ x = kCRC32Table[(x ^ c) & 0xff] ^ (x >> 8);
+ }
+ return ~x;
+}
+
+static void WriteShort(io::CodedOutputStream *out, uint16 val) {
+ uint8 p[2];
+ p[0] = static_cast<uint8>(val);
+ p[1] = static_cast<uint8>(val >> 8);
+ out->WriteRaw(p, 2);
+}
+
+ZipWriter::ZipWriter(io::ZeroCopyOutputStream* raw_output)
+ : raw_output_(raw_output) {}
+ZipWriter::~ZipWriter() {}
+
+bool ZipWriter::Write(const string& filename, const string& contents) {
+ FileInfo info;
+
+ info.name = filename;
+ uint16 filename_size = filename.size();
+ info.offset = raw_output_->ByteCount();
+ info.size = contents.size();
+ info.crc32 = ComputeCRC32(contents);
+
+ files_.push_back(info);
+
+ // write file header
+ io::CodedOutputStream output(raw_output_);
+ output.WriteLittleEndian32(0x04034b50); // magic
+ WriteShort(&output, 10); // version needed to extract
+ WriteShort(&output, 0); // flags
+ WriteShort(&output, 0); // compression method: stored
+ WriteShort(&output, 0); // last modified time
+ WriteShort(&output, 0); // last modified date
+ output.WriteLittleEndian32(info.crc32); // crc-32
+ output.WriteLittleEndian32(info.size); // compressed size
+ output.WriteLittleEndian32(info.size); // uncompressed size
+ WriteShort(&output, filename_size); // file name length
+ WriteShort(&output, 0); // extra field length
+ output.WriteString(filename); // file name
+ output.WriteString(contents); // file data
+
+ return !output.HadError();
+}
+
+bool ZipWriter::WriteDirectory() {
+ uint16 num_entries = files_.size();
+ uint32 dir_ofs = raw_output_->ByteCount();
+
+ // write central directory
+ io::CodedOutputStream output(raw_output_);
+ for (int i = 0; i < num_entries; ++i) {
+ const string &filename = files_[i].name;
+ uint16 filename_size = filename.size();
+ uint32 crc32 = files_[i].crc32;
+ uint32 size = files_[i].size;
+ uint32 offset = files_[i].offset;
+
+ output.WriteLittleEndian32(0x02014b50); // magic
+ WriteShort(&output, 10); // version made by
+ WriteShort(&output, 10); // version needed to extract
+ WriteShort(&output, 0); // flags
+ WriteShort(&output, 0); // compression method: stored
+ WriteShort(&output, 0); // last modified time
+ WriteShort(&output, 0); // last modified date
+ output.WriteLittleEndian32(crc32); // crc-32
+ output.WriteLittleEndian32(size); // compressed size
+ output.WriteLittleEndian32(size); // uncompressed size
+ WriteShort(&output, filename_size); // file name length
+ WriteShort(&output, 0); // extra field length
+ WriteShort(&output, 0); // file comment length
+ WriteShort(&output, 0); // starting disk number
+ WriteShort(&output, 0); // internal file attributes
+ output.WriteLittleEndian32(0); // external file attributes
+ output.WriteLittleEndian32(offset); // local header offset
+ output.WriteString(filename); // file name
+ }
+ uint32 dir_len = output.ByteCount();
+
+ // write end of central directory marker
+ output.WriteLittleEndian32(0x06054b50); // magic
+ WriteShort(&output, 0); // disk number
+ WriteShort(&output, 0); // disk with start of central directory
+ WriteShort(&output, num_entries); // central directory entries (this disk)
+ WriteShort(&output, num_entries); // central directory entries (total)
+ output.WriteLittleEndian32(dir_len); // central directory byte size
+ output.WriteLittleEndian32(dir_ofs); // central directory offset
+ WriteShort(&output, 0); // comment length
+
+ return output.HadError();
+}
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h b/src/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h
new file mode 100644
index 0000000..be73972
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h
@@ -0,0 +1,93 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+class ZipWriter {
+ public:
+ ZipWriter(io::ZeroCopyOutputStream* raw_output);
+ ~ZipWriter();
+
+ bool Write(const string& filename, const string& contents);
+ bool WriteDirectory();
+
+ private:
+ struct FileInfo {
+ string name;
+ uint32 offset;
+ uint32 size;
+ uint32 crc32;
+ };
+
+ io::ZeroCopyOutputStream* raw_output_;
+ vector<FileInfo> files_;
+};
+
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor.cc b/src/third_party/protobuf/src/google/protobuf/descriptor.cc
new file mode 100644
index 0000000..5bdd565
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor.cc
@@ -0,0 +1,4497 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/stubs/hash.h>
+#include <map>
+#include <set>
+#include <vector>
+#include <algorithm>
+#include <limits>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+#undef PACKAGE // autoheader #defines this. :(
+
+namespace google {
+namespace protobuf {
+
+const FieldDescriptor::CppType
+FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
+ static_cast<CppType>(0), // 0 is reserved for errors
+
+ CPPTYPE_DOUBLE, // TYPE_DOUBLE
+ CPPTYPE_FLOAT, // TYPE_FLOAT
+ CPPTYPE_INT64, // TYPE_INT64
+ CPPTYPE_UINT64, // TYPE_UINT64
+ CPPTYPE_INT32, // TYPE_INT32
+ CPPTYPE_UINT64, // TYPE_FIXED64
+ CPPTYPE_UINT32, // TYPE_FIXED32
+ CPPTYPE_BOOL, // TYPE_BOOL
+ CPPTYPE_STRING, // TYPE_STRING
+ CPPTYPE_MESSAGE, // TYPE_GROUP
+ CPPTYPE_MESSAGE, // TYPE_MESSAGE
+ CPPTYPE_STRING, // TYPE_BYTES
+ CPPTYPE_UINT32, // TYPE_UINT32
+ CPPTYPE_ENUM, // TYPE_ENUM
+ CPPTYPE_INT32, // TYPE_SFIXED32
+ CPPTYPE_INT64, // TYPE_SFIXED64
+ CPPTYPE_INT32, // TYPE_SINT32
+ CPPTYPE_INT64, // TYPE_SINT64
+};
+
+const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
+ "ERROR", // 0 is reserved for errors
+
+ "double", // TYPE_DOUBLE
+ "float", // TYPE_FLOAT
+ "int64", // TYPE_INT64
+ "uint64", // TYPE_UINT64
+ "int32", // TYPE_INT32
+ "fixed64", // TYPE_FIXED64
+ "fixed32", // TYPE_FIXED32
+ "bool", // TYPE_BOOL
+ "string", // TYPE_STRING
+ "group", // TYPE_GROUP
+ "message", // TYPE_MESSAGE
+ "bytes", // TYPE_BYTES
+ "uint32", // TYPE_UINT32
+ "enum", // TYPE_ENUM
+ "sfixed32", // TYPE_SFIXED32
+ "sfixed64", // TYPE_SFIXED64
+ "sint32", // TYPE_SINT32
+ "sint64", // TYPE_SINT64
+};
+
+const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
+ "ERROR", // 0 is reserved for errors
+
+ "optional", // LABEL_OPTIONAL
+ "required", // LABEL_REQUIRED
+ "repeated", // LABEL_REPEATED
+};
+
+#ifndef _MSC_VER // MSVC doesn't need these and won't even accept them.
+const int FieldDescriptor::kMaxNumber;
+const int FieldDescriptor::kFirstReservedNumber;
+const int FieldDescriptor::kLastReservedNumber;
+#endif
+
+namespace {
+
+const string kEmptyString;
+
+string ToCamelCase(const string& input) {
+ bool capitalize_next = false;
+ string result;
+ result.reserve(input.size());
+
+ for (int i = 0; i < input.size(); i++) {
+ if (input[i] == '_') {
+ capitalize_next = true;
+ } else if (capitalize_next) {
+ // Note: I distrust ctype.h due to locales.
+ if ('a' <= input[i] && input[i] <= 'z') {
+ result.push_back(input[i] - 'a' + 'A');
+ } else {
+ result.push_back(input[i]);
+ }
+ capitalize_next = false;
+ } else {
+ result.push_back(input[i]);
+ }
+ }
+
+ // Lower-case the first letter.
+ if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') {
+ result[0] = result[0] - 'A' + 'a';
+ }
+
+ return result;
+}
+
+// A DescriptorPool contains a bunch of hash_maps to implement the
+// various Find*By*() methods. Since hashtable lookups are O(1), it's
+// most efficient to construct a fixed set of large hash_maps used by
+// all objects in the pool rather than construct one or more small
+// hash_maps for each object.
+//
+// The keys to these hash_maps are (parent, name) or (parent, number)
+// pairs. Unfortunately STL doesn't provide hash functions for pair<>,
+// so we must invent our own.
+//
+// TODO(kenton): Use StringPiece rather than const char* in keys? It would
+// be a lot cleaner but we'd just have to convert it back to const char*
+// for the open source release.
+
+typedef pair<const void*, const char*> PointerStringPair;
+
+struct PointerStringPairEqual {
+ inline bool operator()(const PointerStringPair& a,
+ const PointerStringPair& b) const {
+ return a.first == b.first && strcmp(a.second, b.second) == 0;
+ }
+};
+
+template<typename PairType>
+struct PointerIntegerPairHash {
+ size_t operator()(const PairType& p) const {
+ // FIXME(kenton): What is the best way to compute this hash? I have
+ // no idea! This seems a bit better than an XOR.
+ return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second;
+ }
+
+ // Used only by MSVC and platforms where hash_map is not available.
+ static const size_t bucket_size = 4;
+ static const size_t min_buckets = 8;
+ inline bool operator()(const PairType& a, const PairType& b) const {
+ return a.first < b.first ||
+ (a.first == b.first && a.second < b.second);
+ }
+};
+
+typedef pair<const Descriptor*, int> DescriptorIntPair;
+typedef pair<const EnumDescriptor*, int> EnumIntPair;
+
+struct PointerStringPairHash {
+ size_t operator()(const PointerStringPair& p) const {
+ // FIXME(kenton): What is the best way to compute this hash? I have
+ // no idea! This seems a bit better than an XOR.
+ hash<const char*> cstring_hash;
+ return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) +
+ cstring_hash(p.second);
+ }
+
+ // Used only by MSVC and platforms where hash_map is not available.
+ static const size_t bucket_size = 4;
+ static const size_t min_buckets = 8;
+ inline bool operator()(const PointerStringPair& a,
+ const PointerStringPair& b) const {
+ if (a.first < b.first) return true;
+ if (a.first > b.first) return false;
+ return strcmp(a.second, b.second) < 0;
+ }
+};
+
+
+struct Symbol {
+ enum Type {
+ NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD, PACKAGE
+ };
+ Type type;
+ union {
+ const Descriptor* descriptor;
+ const FieldDescriptor* field_descriptor;
+ const EnumDescriptor* enum_descriptor;
+ const EnumValueDescriptor* enum_value_descriptor;
+ const ServiceDescriptor* service_descriptor;
+ const MethodDescriptor* method_descriptor;
+ const FileDescriptor* package_file_descriptor;
+ };
+
+ inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; }
+ inline bool IsNull() const { return type == NULL_SYMBOL; }
+ inline bool IsType() const {
+ return type == MESSAGE || type == ENUM;
+ }
+ inline bool IsAggregate() const {
+ return type == MESSAGE || type == PACKAGE
+ || type == ENUM || type == SERVICE;
+ }
+
+#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \
+ inline explicit Symbol(const TYPE* value) { \
+ type = TYPE_CONSTANT; \
+ this->FIELD = value; \
+ }
+
+ CONSTRUCTOR(Descriptor , MESSAGE , descriptor )
+ CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor )
+ CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor )
+ CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor )
+ CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor )
+ CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor )
+ CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor)
+#undef CONSTRUCTOR
+
+ const FileDescriptor* GetFile() const {
+ switch (type) {
+ case NULL_SYMBOL: return NULL;
+ case MESSAGE : return descriptor ->file();
+ case FIELD : return field_descriptor ->file();
+ case ENUM : return enum_descriptor ->file();
+ case ENUM_VALUE : return enum_value_descriptor->type()->file();
+ case SERVICE : return service_descriptor ->file();
+ case METHOD : return method_descriptor ->service()->file();
+ case PACKAGE : return package_file_descriptor;
+ }
+ return NULL;
+ }
+};
+
+const Symbol kNullSymbol;
+
+typedef hash_map<const char*, Symbol,
+ hash<const char*>, streq>
+ SymbolsByNameMap;
+typedef hash_map<PointerStringPair, Symbol,
+ PointerStringPairHash, PointerStringPairEqual>
+ SymbolsByParentMap;
+typedef hash_map<const char*, const FileDescriptor*,
+ hash<const char*>, streq>
+ FilesByNameMap;
+typedef hash_map<PointerStringPair, const FieldDescriptor*,
+ PointerStringPairHash, PointerStringPairEqual>
+ FieldsByNameMap;
+typedef hash_map<DescriptorIntPair, const FieldDescriptor*,
+ PointerIntegerPairHash<DescriptorIntPair> >
+ FieldsByNumberMap;
+typedef hash_map<EnumIntPair, const EnumValueDescriptor*,
+ PointerIntegerPairHash<EnumIntPair> >
+ EnumValuesByNumberMap;
+// This is a map rather than a hash_map, since we use it to iterate
+// through all the extensions that extend a given Descriptor, and an
+// ordered data structure that implements lower_bound is convenient
+// for that.
+typedef map<DescriptorIntPair, const FieldDescriptor*>
+ ExtensionsGroupedByDescriptorMap;
+
+} // anonymous namespace
+
+// ===================================================================
+// DescriptorPool::Tables
+
+class DescriptorPool::Tables {
+ public:
+ Tables();
+ ~Tables();
+
+ // Checkpoint the state of the tables. Future calls to Rollback() will
+ // return the Tables to this state. This is used when building files, since
+ // some kinds of validation errors cannot be detected until the file's
+ // descriptors have already been added to the tables. BuildFile() calls
+ // Checkpoint() before it starts building and Rollback() if it encounters
+ // an error.
+ void Checkpoint();
+
+ // Roll back the Tables to the state of the last Checkpoint(), removing
+ // everything that was added after that point.
+ void Rollback();
+
+ // The stack of files which are currently being built. Used to detect
+ // cyclic dependencies when loading files from a DescriptorDatabase. Not
+ // used when fallback_database_ == NULL.
+ vector<string> pending_files_;
+
+ // A set of files which we have tried to load from the fallback database
+ // and encountered errors. We will not attempt to load them again.
+ // Not used when fallback_database_ == NULL.
+ hash_set<string> known_bad_files_;
+
+ // The set of descriptors for which we've already loaded the full
+ // set of extensions numbers from fallback_database_.
+ hash_set<const Descriptor*> extensions_loaded_from_db_;
+
+ // -----------------------------------------------------------------
+ // Finding items.
+
+ // Find symbols. This returns a null Symbol (symbol.IsNull() is true)
+ // if not found.
+ inline Symbol FindSymbol(const string& key) const;
+
+ // This implements the body of DescriptorPool::Find*ByName(). It should
+ // really be a private method of DescriptorPool, but that would require
+ // declaring Symbol in descriptor.h, which would drag all kinds of other
+ // stuff into the header. Yay C++.
+ Symbol FindByNameHelper(
+ const DescriptorPool* pool, const string& name) const;
+
+ // These return NULL if not found.
+ inline const FileDescriptor* FindFile(const string& key) const;
+ inline const FieldDescriptor* FindExtension(const Descriptor* extendee,
+ int number);
+ inline void FindAllExtensions(const Descriptor* extendee,
+ vector<const FieldDescriptor*>* out) const;
+
+ // -----------------------------------------------------------------
+ // Adding items.
+
+ // These add items to the corresponding tables. They return false if
+ // the key already exists in the table. For AddSymbol(), the string passed
+ // in must be one that was constructed using AllocateString(), as it will
+ // be used as a key in the symbols_by_name_ map without copying.
+ bool AddSymbol(const string& full_name, Symbol symbol);
+ bool AddFile(const FileDescriptor* file);
+ bool AddExtension(const FieldDescriptor* field);
+
+ // -----------------------------------------------------------------
+ // Allocating memory.
+
+ // Allocate an object which will be reclaimed when the pool is
+ // destroyed. Note that the object's destructor will never be called,
+ // so its fields must be plain old data (primitive data types and
+ // pointers). All of the descriptor types are such objects.
+ template<typename Type> Type* Allocate();
+
+ // Allocate an array of objects which will be reclaimed when the
+ // pool in destroyed. Again, destructors are never called.
+ template<typename Type> Type* AllocateArray(int count);
+
+ // Allocate a string which will be destroyed when the pool is destroyed.
+ // The string is initialized to the given value for convenience.
+ string* AllocateString(const string& value);
+
+ // Allocate a protocol message object. Some older versions of GCC have
+ // trouble understanding explicit template instantiations in some cases, so
+ // in those cases we have to pass a dummy pointer of the right type as the
+ // parameter instead of specifying the type explicitly.
+ template<typename Type> Type* AllocateMessage(Type* dummy = NULL);
+
+ // Allocate a FileDescriptorTables object.
+ FileDescriptorTables* AllocateFileTables();
+
+ private:
+ vector<string*> strings_; // All strings in the pool.
+ vector<Message*> messages_; // All messages in the pool.
+ vector<FileDescriptorTables*> file_tables_; // All file tables in the pool.
+ vector<void*> allocations_; // All other memory allocated in the pool.
+
+ SymbolsByNameMap symbols_by_name_;
+ FilesByNameMap files_by_name_;
+ ExtensionsGroupedByDescriptorMap extensions_;
+
+ int strings_before_checkpoint_;
+ int messages_before_checkpoint_;
+ int file_tables_before_checkpoint_;
+ int allocations_before_checkpoint_;
+ vector<const char* > symbols_after_checkpoint_;
+ vector<const char* > files_after_checkpoint_;
+ vector<DescriptorIntPair> extensions_after_checkpoint_;
+
+ // Allocate some bytes which will be reclaimed when the pool is
+ // destroyed.
+ void* AllocateBytes(int size);
+};
+
+// Contains tables specific to a particular file. These tables are not
+// modified once the file has been constructed, so they need not be
+// protected by a mutex. This makes operations that depend only on the
+// contents of a single file -- e.g. Descriptor::FindFieldByName() --
+// lock-free.
+//
+// For historical reasons, the definitions of the methods of
+// FileDescriptorTables and DescriptorPool::Tables are interleaved below.
+// These used to be a single class.
+class FileDescriptorTables {
+ public:
+ FileDescriptorTables();
+ ~FileDescriptorTables();
+
+ // Empty table, used with placeholder files.
+ static const FileDescriptorTables kEmpty;
+
+ // -----------------------------------------------------------------
+ // Finding items.
+
+ // Find symbols. These return a null Symbol (symbol.IsNull() is true)
+ // if not found.
+ inline Symbol FindNestedSymbol(const void* parent,
+ const string& name) const;
+ inline Symbol FindNestedSymbolOfType(const void* parent,
+ const string& name,
+ const Symbol::Type type) const;
+
+ // These return NULL if not found.
+ inline const FieldDescriptor* FindFieldByNumber(
+ const Descriptor* parent, int number) const;
+ inline const FieldDescriptor* FindFieldByLowercaseName(
+ const void* parent, const string& lowercase_name) const;
+ inline const FieldDescriptor* FindFieldByCamelcaseName(
+ const void* parent, const string& camelcase_name) const;
+ inline const EnumValueDescriptor* FindEnumValueByNumber(
+ const EnumDescriptor* parent, int number) const;
+
+ // -----------------------------------------------------------------
+ // Adding items.
+
+ // These add items to the corresponding tables. They return false if
+ // the key already exists in the table. For AddAliasUnderParent(), the
+ // string passed in must be one that was constructed using AllocateString(),
+ // as it will be used as a key in the symbols_by_parent_ map without copying.
+ bool AddAliasUnderParent(const void* parent, const string& name,
+ Symbol symbol);
+ bool AddFieldByNumber(const FieldDescriptor* field);
+ bool AddEnumValueByNumber(const EnumValueDescriptor* value);
+
+ // Adds the field to the lowercase_name and camelcase_name maps. Never
+ // fails because we allow duplicates; the first field by the name wins.
+ void AddFieldByStylizedNames(const FieldDescriptor* field);
+
+ private:
+ SymbolsByParentMap symbols_by_parent_;
+ FieldsByNameMap fields_by_lowercase_name_;
+ FieldsByNameMap fields_by_camelcase_name_;
+ FieldsByNumberMap fields_by_number_; // Not including extensions.
+ EnumValuesByNumberMap enum_values_by_number_;
+};
+
+DescriptorPool::Tables::Tables()
+ : strings_before_checkpoint_(0),
+ messages_before_checkpoint_(0),
+ allocations_before_checkpoint_(0) {}
+
+DescriptorPool::Tables::~Tables() {
+ // Note that the deletion order is important, since the destructors of some
+ // messages may refer to objects in allocations_.
+ STLDeleteElements(&messages_);
+ for (int i = 0; i < allocations_.size(); i++) {
+ operator delete(allocations_[i]);
+ }
+ STLDeleteElements(&strings_);
+ STLDeleteElements(&file_tables_);
+}
+
+FileDescriptorTables::FileDescriptorTables() {}
+FileDescriptorTables::~FileDescriptorTables() {}
+
+const FileDescriptorTables FileDescriptorTables::kEmpty;
+
+void DescriptorPool::Tables::Checkpoint() {
+ strings_before_checkpoint_ = strings_.size();
+ messages_before_checkpoint_ = messages_.size();
+ file_tables_before_checkpoint_ = file_tables_.size();
+ allocations_before_checkpoint_ = allocations_.size();
+
+ symbols_after_checkpoint_.clear();
+ files_after_checkpoint_.clear();
+ extensions_after_checkpoint_.clear();
+}
+
+void DescriptorPool::Tables::Rollback() {
+ for (int i = 0; i < symbols_after_checkpoint_.size(); i++) {
+ symbols_by_name_.erase(symbols_after_checkpoint_[i]);
+ }
+ for (int i = 0; i < files_after_checkpoint_.size(); i++) {
+ files_by_name_.erase(files_after_checkpoint_[i]);
+ }
+ for (int i = 0; i < extensions_after_checkpoint_.size(); i++) {
+ extensions_.erase(extensions_after_checkpoint_[i]);
+ }
+
+ symbols_after_checkpoint_.clear();
+ files_after_checkpoint_.clear();
+ extensions_after_checkpoint_.clear();
+
+ STLDeleteContainerPointers(
+ strings_.begin() + strings_before_checkpoint_, strings_.end());
+ STLDeleteContainerPointers(
+ messages_.begin() + messages_before_checkpoint_, messages_.end());
+ STLDeleteContainerPointers(
+ file_tables_.begin() + file_tables_before_checkpoint_, file_tables_.end());
+ for (int i = allocations_before_checkpoint_; i < allocations_.size(); i++) {
+ operator delete(allocations_[i]);
+ }
+
+ strings_.resize(strings_before_checkpoint_);
+ messages_.resize(messages_before_checkpoint_);
+ file_tables_.resize(file_tables_before_checkpoint_);
+ allocations_.resize(allocations_before_checkpoint_);
+}
+
+// -------------------------------------------------------------------
+
+inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const {
+ const Symbol* result = FindOrNull(symbols_by_name_, key.c_str());
+ if (result == NULL) {
+ return kNullSymbol;
+ } else {
+ return *result;
+ }
+}
+
+inline Symbol FileDescriptorTables::FindNestedSymbol(
+ const void* parent, const string& name) const {
+ const Symbol* result =
+ FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str()));
+ if (result == NULL) {
+ return kNullSymbol;
+ } else {
+ return *result;
+ }
+}
+
+inline Symbol FileDescriptorTables::FindNestedSymbolOfType(
+ const void* parent, const string& name, const Symbol::Type type) const {
+ Symbol result = FindNestedSymbol(parent, name);
+ if (result.type != type) return kNullSymbol;
+ return result;
+}
+
+Symbol DescriptorPool::Tables::FindByNameHelper(
+ const DescriptorPool* pool, const string& name) const {
+ MutexLockMaybe lock(pool->mutex_);
+ Symbol result = FindSymbol(name);
+
+ if (result.IsNull() && pool->underlay_ != NULL) {
+ // Symbol not found; check the underlay.
+ result =
+ pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
+ }
+
+ if (result.IsNull()) {
+ // Symbol still not found, so check fallback database.
+ if (pool->TryFindSymbolInFallbackDatabase(name)) {
+ result = FindSymbol(name);
+ }
+ }
+
+ return result;
+}
+
+inline const FileDescriptor* DescriptorPool::Tables::FindFile(
+ const string& key) const {
+ return FindPtrOrNull(files_by_name_, key.c_str());
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
+ const Descriptor* parent, int number) const {
+ return FindPtrOrNull(fields_by_number_, make_pair(parent, number));
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
+ const void* parent, const string& lowercase_name) const {
+ return FindPtrOrNull(fields_by_lowercase_name_,
+ PointerStringPair(parent, lowercase_name.c_str()));
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName(
+ const void* parent, const string& camelcase_name) const {
+ return FindPtrOrNull(fields_by_camelcase_name_,
+ PointerStringPair(parent, camelcase_name.c_str()));
+}
+
+inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
+ const EnumDescriptor* parent, int number) const {
+ return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number));
+}
+
+inline const FieldDescriptor* DescriptorPool::Tables::FindExtension(
+ const Descriptor* extendee, int number) {
+ return FindPtrOrNull(extensions_, make_pair(extendee, number));
+}
+
+inline void DescriptorPool::Tables::FindAllExtensions(
+ const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
+ ExtensionsGroupedByDescriptorMap::const_iterator it =
+ extensions_.lower_bound(make_pair(extendee, 0));
+ for (; it != extensions_.end() && it->first.first == extendee; ++it) {
+ out->push_back(it->second);
+ }
+}
+
+// -------------------------------------------------------------------
+
+bool DescriptorPool::Tables::AddSymbol(
+ const string& full_name, Symbol symbol) {
+ if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) {
+ symbols_after_checkpoint_.push_back(full_name.c_str());
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool FileDescriptorTables::AddAliasUnderParent(
+ const void* parent, const string& name, Symbol symbol) {
+ PointerStringPair by_parent_key(parent, name.c_str());
+ return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol);
+}
+
+bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) {
+ if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) {
+ files_after_checkpoint_.push_back(file->name().c_str());
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void FileDescriptorTables::AddFieldByStylizedNames(
+ const FieldDescriptor* field) {
+ const void* parent;
+ if (field->is_extension()) {
+ if (field->extension_scope() == NULL) {
+ parent = field->file();
+ } else {
+ parent = field->extension_scope();
+ }
+ } else {
+ parent = field->containing_type();
+ }
+
+ PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
+ InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field);
+
+ PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
+ InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field);
+}
+
+bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) {
+ DescriptorIntPair key(field->containing_type(), field->number());
+ return InsertIfNotPresent(&fields_by_number_, key, field);
+}
+
+bool FileDescriptorTables::AddEnumValueByNumber(
+ const EnumValueDescriptor* value) {
+ EnumIntPair key(value->type(), value->number());
+ return InsertIfNotPresent(&enum_values_by_number_, key, value);
+}
+
+bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) {
+ DescriptorIntPair key(field->containing_type(), field->number());
+ if (InsertIfNotPresent(&extensions_, key, field)) {
+ extensions_after_checkpoint_.push_back(key);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// -------------------------------------------------------------------
+
+template<typename Type>
+Type* DescriptorPool::Tables::Allocate() {
+ return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type)));
+}
+
+template<typename Type>
+Type* DescriptorPool::Tables::AllocateArray(int count) {
+ return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count));
+}
+
+string* DescriptorPool::Tables::AllocateString(const string& value) {
+ string* result = new string(value);
+ strings_.push_back(result);
+ return result;
+}
+
+template<typename Type>
+Type* DescriptorPool::Tables::AllocateMessage(Type* dummy) {
+ Type* result = new Type;
+ messages_.push_back(result);
+ return result;
+}
+
+FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() {
+ FileDescriptorTables* result = new FileDescriptorTables;
+ file_tables_.push_back(result);
+ return result;
+}
+
+void* DescriptorPool::Tables::AllocateBytes(int size) {
+ // TODO(kenton): Would it be worthwhile to implement this in some more
+ // sophisticated way? Probably not for the open source release, but for
+ // internal use we could easily plug in one of our existing memory pool
+ // allocators...
+ if (size == 0) return NULL;
+
+ void* result = operator new(size);
+ allocations_.push_back(result);
+ return result;
+}
+
+// ===================================================================
+// DescriptorPool
+
+DescriptorPool::ErrorCollector::~ErrorCollector() {}
+
+DescriptorPool::DescriptorPool()
+ : mutex_(NULL),
+ fallback_database_(NULL),
+ default_error_collector_(NULL),
+ underlay_(NULL),
+ tables_(new Tables),
+ enforce_dependencies_(true),
+ allow_unknown_(false) {}
+
+DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
+ ErrorCollector* error_collector)
+ : mutex_(new Mutex),
+ fallback_database_(fallback_database),
+ default_error_collector_(error_collector),
+ underlay_(NULL),
+ tables_(new Tables),
+ enforce_dependencies_(true),
+ allow_unknown_(false) {
+}
+
+DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
+ : mutex_(NULL),
+ fallback_database_(NULL),
+ default_error_collector_(NULL),
+ underlay_(underlay),
+ tables_(new Tables),
+ enforce_dependencies_(true),
+ allow_unknown_(false) {}
+
+DescriptorPool::~DescriptorPool() {
+ if (mutex_ != NULL) delete mutex_;
+}
+
+// DescriptorPool::BuildFile() defined later.
+// DescriptorPool::BuildFileCollectingErrors() defined later.
+
+void DescriptorPool::InternalDontEnforceDependencies() {
+ enforce_dependencies_ = false;
+}
+
+bool DescriptorPool::InternalIsFileLoaded(const string& filename) const {
+ MutexLockMaybe lock(mutex_);
+ return tables_->FindFile(filename) != NULL;
+}
+
+// generated_pool ====================================================
+
+namespace {
+
+
+EncodedDescriptorDatabase* generated_database_ = NULL;
+DescriptorPool* generated_pool_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_);
+
+void DeleteGeneratedPool() {
+ delete generated_database_;
+ generated_database_ = NULL;
+ delete generated_pool_;
+ generated_pool_ = NULL;
+}
+
+void InitGeneratedPool() {
+ generated_database_ = new EncodedDescriptorDatabase;
+ generated_pool_ = new DescriptorPool(generated_database_);
+
+ internal::OnShutdown(&DeleteGeneratedPool);
+}
+
+inline void InitGeneratedPoolOnce() {
+ ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool);
+}
+
+} // anonymous namespace
+
+const DescriptorPool* DescriptorPool::generated_pool() {
+ InitGeneratedPoolOnce();
+ return generated_pool_;
+}
+
+DescriptorPool* DescriptorPool::internal_generated_pool() {
+ InitGeneratedPoolOnce();
+ return generated_pool_;
+}
+
+void DescriptorPool::InternalAddGeneratedFile(
+ const void* encoded_file_descriptor, int size) {
+ // So, this function is called in the process of initializing the
+ // descriptors for generated proto classes. Each generated .pb.cc file
+ // has an internal procedure called AddDescriptors() which is called at
+ // process startup, and that function calls this one in order to register
+ // the raw bytes of the FileDescriptorProto representing the file.
+ //
+ // We do not actually construct the descriptor objects right away. We just
+ // hang on to the bytes until they are actually needed. We actually construct
+ // the descriptor the first time one of the following things happens:
+ // * Someone calls a method like descriptor(), GetDescriptor(), or
+ // GetReflection() on the generated types, which requires returning the
+ // descriptor or an object based on it.
+ // * Someone looks up the descriptor in DescriptorPool::generated_pool().
+ //
+ // Once one of these happens, the DescriptorPool actually parses the
+ // FileDescriptorProto and generates a FileDescriptor (and all its children)
+ // based on it.
+ //
+ // Note that FileDescriptorProto is itself a generated protocol message.
+ // Therefore, when we parse one, we have to be very careful to avoid using
+ // any descriptor-based operations, since this might cause infinite recursion
+ // or deadlock.
+ InitGeneratedPoolOnce();
+ GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size));
+}
+
+
+// Find*By* methods ==================================================
+
+// TODO(kenton): There's a lot of repeated code here, but I'm not sure if
+// there's any good way to factor it out. Think about this some time when
+// there's nothing more important to do (read: never).
+
+const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const {
+ MutexLockMaybe lock(mutex_);
+ const FileDescriptor* result = tables_->FindFile(name);
+ if (result != NULL) return result;
+ if (underlay_ != NULL) {
+ const FileDescriptor* result = underlay_->FindFileByName(name);
+ if (result != NULL) return result;
+ }
+ if (TryFindFileInFallbackDatabase(name)) {
+ const FileDescriptor* result = tables_->FindFile(name);
+ if (result != NULL) return result;
+ }
+ return NULL;
+}
+
+const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
+ const string& symbol_name) const {
+ MutexLockMaybe lock(mutex_);
+ Symbol result = tables_->FindSymbol(symbol_name);
+ if (!result.IsNull()) return result.GetFile();
+ if (underlay_ != NULL) {
+ const FileDescriptor* result =
+ underlay_->FindFileContainingSymbol(symbol_name);
+ if (result != NULL) return result;
+ }
+ if (TryFindSymbolInFallbackDatabase(symbol_name)) {
+ Symbol result = tables_->FindSymbol(symbol_name);
+ if (!result.IsNull()) return result.GetFile();
+ }
+ return NULL;
+}
+
+const Descriptor* DescriptorPool::FindMessageTypeByName(
+ const string& name) const {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL;
+}
+
+const FieldDescriptor* DescriptorPool::FindFieldByName(
+ const string& name) const {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ if (result.type == Symbol::FIELD &&
+ !result.field_descriptor->is_extension()) {
+ return result.field_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const FieldDescriptor* DescriptorPool::FindExtensionByName(
+ const string& name) const {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ if (result.type == Symbol::FIELD &&
+ result.field_descriptor->is_extension()) {
+ return result.field_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
+ const string& name) const {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL;
+}
+
+const EnumValueDescriptor* DescriptorPool::FindEnumValueByName(
+ const string& name) const {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::ENUM_VALUE) ?
+ result.enum_value_descriptor : NULL;
+}
+
+const ServiceDescriptor* DescriptorPool::FindServiceByName(
+ const string& name) const {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL;
+}
+
+const MethodDescriptor* DescriptorPool::FindMethodByName(
+ const string& name) const {
+ Symbol result = tables_->FindByNameHelper(this, name);
+ return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL;
+}
+
+const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
+ const Descriptor* extendee, int number) const {
+ MutexLockMaybe lock(mutex_);
+ const FieldDescriptor* result = tables_->FindExtension(extendee, number);
+ if (result != NULL) {
+ return result;
+ }
+ if (underlay_ != NULL) {
+ const FieldDescriptor* result =
+ underlay_->FindExtensionByNumber(extendee, number);
+ if (result != NULL) return result;
+ }
+ if (TryFindExtensionInFallbackDatabase(extendee, number)) {
+ const FieldDescriptor* result = tables_->FindExtension(extendee, number);
+ if (result != NULL) {
+ return result;
+ }
+ }
+ return NULL;
+}
+
+void DescriptorPool::FindAllExtensions(
+ const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
+ MutexLockMaybe lock(mutex_);
+
+ // Initialize tables_->extensions_ from the fallback database first
+ // (but do this only once per descriptor).
+ if (fallback_database_ != NULL &&
+ tables_->extensions_loaded_from_db_.count(extendee) == 0) {
+ vector<int> numbers;
+ if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(),
+ &numbers)) {
+ for (int i = 0; i < numbers.size(); ++i) {
+ int number = numbers[i];
+ if (tables_->FindExtension(extendee, number) == NULL) {
+ TryFindExtensionInFallbackDatabase(extendee, number);
+ }
+ }
+ tables_->extensions_loaded_from_db_.insert(extendee);
+ }
+ }
+
+ tables_->FindAllExtensions(extendee, out);
+ if (underlay_ != NULL) {
+ underlay_->FindAllExtensions(extendee, out);
+ }
+}
+
+// -------------------------------------------------------------------
+
+const FieldDescriptor*
+Descriptor::FindFieldByNumber(int key) const {
+ const FieldDescriptor* result =
+ file()->tables_->FindFieldByNumber(this, key);
+ if (result == NULL || result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
+Descriptor::FindFieldByLowercaseName(const string& key) const {
+ const FieldDescriptor* result =
+ file()->tables_->FindFieldByLowercaseName(this, key);
+ if (result == NULL || result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
+Descriptor::FindFieldByCamelcaseName(const string& key) const {
+ const FieldDescriptor* result =
+ file()->tables_->FindFieldByCamelcaseName(this, key);
+ if (result == NULL || result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
+Descriptor::FindFieldByName(const string& key) const {
+ Symbol result =
+ file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+ if (!result.IsNull() && !result.field_descriptor->is_extension()) {
+ return result.field_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const FieldDescriptor*
+Descriptor::FindExtensionByName(const string& key) const {
+ Symbol result =
+ file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+ if (!result.IsNull() && result.field_descriptor->is_extension()) {
+ return result.field_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const FieldDescriptor*
+Descriptor::FindExtensionByLowercaseName(const string& key) const {
+ const FieldDescriptor* result =
+ file()->tables_->FindFieldByLowercaseName(this, key);
+ if (result == NULL || !result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
+Descriptor::FindExtensionByCamelcaseName(const string& key) const {
+ const FieldDescriptor* result =
+ file()->tables_->FindFieldByCamelcaseName(this, key);
+ if (result == NULL || !result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const Descriptor*
+Descriptor::FindNestedTypeByName(const string& key) const {
+ Symbol result =
+ file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
+ if (!result.IsNull()) {
+ return result.descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const EnumDescriptor*
+Descriptor::FindEnumTypeByName(const string& key) const {
+ Symbol result =
+ file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
+ if (!result.IsNull()) {
+ return result.enum_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const EnumValueDescriptor*
+Descriptor::FindEnumValueByName(const string& key) const {
+ Symbol result =
+ file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
+ if (!result.IsNull()) {
+ return result.enum_value_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const EnumValueDescriptor*
+EnumDescriptor::FindValueByName(const string& key) const {
+ Symbol result =
+ file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
+ if (!result.IsNull()) {
+ return result.enum_value_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const EnumValueDescriptor*
+EnumDescriptor::FindValueByNumber(int key) const {
+ return file()->tables_->FindEnumValueByNumber(this, key);
+}
+
+const MethodDescriptor*
+ServiceDescriptor::FindMethodByName(const string& key) const {
+ Symbol result =
+ file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD);
+ if (!result.IsNull()) {
+ return result.method_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const Descriptor*
+FileDescriptor::FindMessageTypeByName(const string& key) const {
+ Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
+ if (!result.IsNull()) {
+ return result.descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const EnumDescriptor*
+FileDescriptor::FindEnumTypeByName(const string& key) const {
+ Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
+ if (!result.IsNull()) {
+ return result.enum_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const EnumValueDescriptor*
+FileDescriptor::FindEnumValueByName(const string& key) const {
+ Symbol result =
+ tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE);
+ if (!result.IsNull()) {
+ return result.enum_value_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const ServiceDescriptor*
+FileDescriptor::FindServiceByName(const string& key) const {
+ Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE);
+ if (!result.IsNull()) {
+ return result.service_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const FieldDescriptor*
+FileDescriptor::FindExtensionByName(const string& key) const {
+ Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+ if (!result.IsNull() && result.field_descriptor->is_extension()) {
+ return result.field_descriptor;
+ } else {
+ return NULL;
+ }
+}
+
+const FieldDescriptor*
+FileDescriptor::FindExtensionByLowercaseName(const string& key) const {
+ const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key);
+ if (result == NULL || !result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+const FieldDescriptor*
+FileDescriptor::FindExtensionByCamelcaseName(const string& key) const {
+ const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key);
+ if (result == NULL || !result->is_extension()) {
+ return NULL;
+ } else {
+ return result;
+ }
+}
+
+bool Descriptor::IsExtensionNumber(int number) const {
+ // Linear search should be fine because we don't expect a message to have
+ // more than a couple extension ranges.
+ for (int i = 0; i < extension_range_count(); i++) {
+ if (number >= extension_range(i)->start &&
+ number < extension_range(i)->end) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// -------------------------------------------------------------------
+
+bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const {
+ if (fallback_database_ == NULL) return false;
+
+ if (tables_->known_bad_files_.count(name) > 0) return false;
+
+ FileDescriptorProto file_proto;
+ if (!fallback_database_->FindFileByName(name, &file_proto) ||
+ BuildFileFromDatabase(file_proto) == NULL) {
+ tables_->known_bad_files_.insert(name);
+ return false;
+ }
+
+ return true;
+}
+
+bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const {
+ if (fallback_database_ == NULL) return false;
+
+ FileDescriptorProto file_proto;
+ if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) {
+ return false;
+ }
+
+ if (tables_->FindFile(file_proto.name()) != NULL) {
+ // We've already loaded this file, and it apparently doesn't contain the
+ // symbol we're looking for. Some DescriptorDatabases return false
+ // positives.
+ return false;
+ }
+
+ if (BuildFileFromDatabase(file_proto) == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+bool DescriptorPool::TryFindExtensionInFallbackDatabase(
+ const Descriptor* containing_type, int field_number) const {
+ if (fallback_database_ == NULL) return false;
+
+ FileDescriptorProto file_proto;
+ if (!fallback_database_->FindFileContainingExtension(
+ containing_type->full_name(), field_number, &file_proto)) {
+ return false;
+ }
+
+ if (tables_->FindFile(file_proto.name()) != NULL) {
+ // We've already loaded this file, and it apparently doesn't contain the
+ // extension we're looking for. Some DescriptorDatabases return false
+ // positives.
+ return false;
+ }
+
+ if (BuildFileFromDatabase(file_proto) == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+// ===================================================================
+
+string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const {
+ GOOGLE_CHECK(has_default_value()) << "No default value";
+ switch (cpp_type()) {
+ case CPPTYPE_INT32:
+ return SimpleItoa(default_value_int32());
+ break;
+ case CPPTYPE_INT64:
+ return SimpleItoa(default_value_int64());
+ break;
+ case CPPTYPE_UINT32:
+ return SimpleItoa(default_value_uint32());
+ break;
+ case CPPTYPE_UINT64:
+ return SimpleItoa(default_value_uint64());
+ break;
+ case CPPTYPE_FLOAT:
+ return SimpleFtoa(default_value_float());
+ break;
+ case CPPTYPE_DOUBLE:
+ return SimpleDtoa(default_value_double());
+ break;
+ case CPPTYPE_BOOL:
+ return default_value_bool() ? "true" : "false";
+ break;
+ case CPPTYPE_STRING:
+ if (quote_string_type) {
+ return "\"" + CEscape(default_value_string()) + "\"";
+ } else {
+ if (type() == TYPE_BYTES) {
+ return CEscape(default_value_string());
+ } else {
+ return default_value_string();
+ }
+ }
+ break;
+ case CPPTYPE_ENUM:
+ return default_value_enum()->name();
+ break;
+ case CPPTYPE_MESSAGE:
+ GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
+ break;
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string";
+ return "";
+}
+
+// CopyTo methods ====================================================
+
+void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
+ proto->set_name(name());
+ if (!package().empty()) proto->set_package(package());
+
+ for (int i = 0; i < dependency_count(); i++) {
+ proto->add_dependency(dependency(i)->name());
+ }
+
+ for (int i = 0; i < message_type_count(); i++) {
+ message_type(i)->CopyTo(proto->add_message_type());
+ }
+ for (int i = 0; i < enum_type_count(); i++) {
+ enum_type(i)->CopyTo(proto->add_enum_type());
+ }
+ for (int i = 0; i < service_count(); i++) {
+ service(i)->CopyTo(proto->add_service());
+ }
+ for (int i = 0; i < extension_count(); i++) {
+ extension(i)->CopyTo(proto->add_extension());
+ }
+
+ if (&options() != &FileOptions::default_instance()) {
+ proto->mutable_options()->CopyFrom(options());
+ }
+}
+
+void Descriptor::CopyTo(DescriptorProto* proto) const {
+ proto->set_name(name());
+
+ for (int i = 0; i < field_count(); i++) {
+ field(i)->CopyTo(proto->add_field());
+ }
+ for (int i = 0; i < nested_type_count(); i++) {
+ nested_type(i)->CopyTo(proto->add_nested_type());
+ }
+ for (int i = 0; i < enum_type_count(); i++) {
+ enum_type(i)->CopyTo(proto->add_enum_type());
+ }
+ for (int i = 0; i < extension_range_count(); i++) {
+ DescriptorProto::ExtensionRange* range = proto->add_extension_range();
+ range->set_start(extension_range(i)->start);
+ range->set_end(extension_range(i)->end);
+ }
+ for (int i = 0; i < extension_count(); i++) {
+ extension(i)->CopyTo(proto->add_extension());
+ }
+
+ if (&options() != &MessageOptions::default_instance()) {
+ proto->mutable_options()->CopyFrom(options());
+ }
+}
+
+void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
+ proto->set_name(name());
+ proto->set_number(number());
+
+ // Some compilers do not allow static_cast directly between two enum types,
+ // so we must cast to int first.
+ proto->set_label(static_cast<FieldDescriptorProto::Label>(
+ implicit_cast<int>(label())));
+ proto->set_type(static_cast<FieldDescriptorProto::Type>(
+ implicit_cast<int>(type())));
+
+ if (is_extension()) {
+ if (!containing_type()->is_unqualified_placeholder_) {
+ proto->set_extendee(".");
+ }
+ proto->mutable_extendee()->append(containing_type()->full_name());
+ }
+
+ if (cpp_type() == CPPTYPE_MESSAGE) {
+ if (message_type()->is_placeholder_) {
+ // We don't actually know if the type is a message type. It could be
+ // an enum.
+ proto->clear_type();
+ }
+
+ if (!message_type()->is_unqualified_placeholder_) {
+ proto->set_type_name(".");
+ }
+ proto->mutable_type_name()->append(message_type()->full_name());
+ } else if (cpp_type() == CPPTYPE_ENUM) {
+ if (!enum_type()->is_unqualified_placeholder_) {
+ proto->set_type_name(".");
+ }
+ proto->mutable_type_name()->append(enum_type()->full_name());
+ }
+
+ if (has_default_value()) {
+ proto->set_default_value(DefaultValueAsString(false));
+ }
+
+ if (&options() != &FieldOptions::default_instance()) {
+ proto->mutable_options()->CopyFrom(options());
+ }
+}
+
+void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
+ proto->set_name(name());
+
+ for (int i = 0; i < value_count(); i++) {
+ value(i)->CopyTo(proto->add_value());
+ }
+
+ if (&options() != &EnumOptions::default_instance()) {
+ proto->mutable_options()->CopyFrom(options());
+ }
+}
+
+void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const {
+ proto->set_name(name());
+ proto->set_number(number());
+
+ if (&options() != &EnumValueOptions::default_instance()) {
+ proto->mutable_options()->CopyFrom(options());
+ }
+}
+
+void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const {
+ proto->set_name(name());
+
+ for (int i = 0; i < method_count(); i++) {
+ method(i)->CopyTo(proto->add_method());
+ }
+
+ if (&options() != &ServiceOptions::default_instance()) {
+ proto->mutable_options()->CopyFrom(options());
+ }
+}
+
+void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const {
+ proto->set_name(name());
+
+ if (!input_type()->is_unqualified_placeholder_) {
+ proto->set_input_type(".");
+ }
+ proto->mutable_input_type()->append(input_type()->full_name());
+
+ if (!output_type()->is_unqualified_placeholder_) {
+ proto->set_output_type(".");
+ }
+ proto->mutable_output_type()->append(output_type()->full_name());
+
+ if (&options() != &MethodOptions::default_instance()) {
+ proto->mutable_options()->CopyFrom(options());
+ }
+}
+
+// DebugString methods ===============================================
+
+namespace {
+
+// Used by each of the option formatters.
+bool RetrieveOptions(const Message &options, vector<string> *option_entries) {
+ option_entries->clear();
+ const Reflection* reflection = options.GetReflection();
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(options, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ // Doesn't make sense to have message type fields here
+ if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ continue;
+ }
+ int count = 1;
+ bool repeated = false;
+ if (fields[i]->is_repeated()) {
+ count = reflection->FieldSize(options, fields[i]);
+ repeated = true;
+ }
+ for (int j = 0; j < count; j++) {
+ string fieldval;
+ TextFormat::PrintFieldValueToString(options, fields[i],
+ repeated ? count : -1, &fieldval);
+ option_entries->push_back(fields[i]->name() + " = " + fieldval);
+ }
+ }
+ return !option_entries->empty();
+}
+
+// Formats options that all appear together in brackets. Does not include
+// brackets.
+bool FormatBracketedOptions(const Message &options, string *output) {
+ vector<string> all_options;
+ if (RetrieveOptions(options, &all_options)) {
+ output->append(JoinStrings(all_options, ", "));
+ }
+ return !all_options.empty();
+}
+
+// Formats options one per line
+bool FormatLineOptions(int depth, const Message &options, string *output) {
+ string prefix(depth * 2, ' ');
+ vector<string> all_options;
+ if (RetrieveOptions(options, &all_options)) {
+ for (int i = 0; i < all_options.size(); i++) {
+ strings::SubstituteAndAppend(output, "$0option $1;\n",
+ prefix, all_options[i]);
+ }
+ }
+ return !all_options.empty();
+}
+
+} // anonymous namespace
+
+string FileDescriptor::DebugString() const {
+ string contents = "syntax = \"proto2\";\n\n";
+
+ for (int i = 0; i < dependency_count(); i++) {
+ strings::SubstituteAndAppend(&contents, "import \"$0\";\n",
+ dependency(i)->name());
+ }
+
+ if (!package().empty()) {
+ strings::SubstituteAndAppend(&contents, "package $0;\n\n", package());
+ }
+
+ if (FormatLineOptions(0, options(), &contents)) {
+ contents.append("\n"); // add some space if we had options
+ }
+
+ for (int i = 0; i < enum_type_count(); i++) {
+ enum_type(i)->DebugString(0, &contents);
+ contents.append("\n");
+ }
+
+ // Find all the 'group' type extensions; we will not output their nested
+ // definitions (those will be done with their group field descriptor).
+ set<const Descriptor*> groups;
+ for (int i = 0; i < extension_count(); i++) {
+ if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) {
+ groups.insert(extension(i)->message_type());
+ }
+ }
+
+ for (int i = 0; i < message_type_count(); i++) {
+ if (groups.count(message_type(i)) == 0) {
+ strings::SubstituteAndAppend(&contents, "message $0",
+ message_type(i)->name());
+ message_type(i)->DebugString(0, &contents);
+ contents.append("\n");
+ }
+ }
+
+ for (int i = 0; i < service_count(); i++) {
+ service(i)->DebugString(&contents);
+ contents.append("\n");
+ }
+
+ const Descriptor* containing_type = NULL;
+ for (int i = 0; i < extension_count(); i++) {
+ if (extension(i)->containing_type() != containing_type) {
+ if (i > 0) contents.append("}\n\n");
+ containing_type = extension(i)->containing_type();
+ strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
+ containing_type->full_name());
+ }
+ extension(i)->DebugString(1, &contents);
+ }
+ if (extension_count() > 0) contents.append("}\n\n");
+
+ return contents;
+}
+
+string Descriptor::DebugString() const {
+ string contents;
+ strings::SubstituteAndAppend(&contents, "message $0", name());
+ DebugString(0, &contents);
+ return contents;
+}
+
+void Descriptor::DebugString(int depth, string *contents) const {
+ string prefix(depth * 2, ' ');
+ ++depth;
+ contents->append(" {\n");
+
+ FormatLineOptions(depth, options(), contents);
+
+ // Find all the 'group' types for fields and extensions; we will not output
+ // their nested definitions (those will be done with their group field
+ // descriptor).
+ set<const Descriptor*> groups;
+ for (int i = 0; i < field_count(); i++) {
+ if (field(i)->type() == FieldDescriptor::TYPE_GROUP) {
+ groups.insert(field(i)->message_type());
+ }
+ }
+ for (int i = 0; i < extension_count(); i++) {
+ if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) {
+ groups.insert(extension(i)->message_type());
+ }
+ }
+
+ for (int i = 0; i < nested_type_count(); i++) {
+ if (groups.count(nested_type(i)) == 0) {
+ strings::SubstituteAndAppend(contents, "$0 message $1",
+ prefix, nested_type(i)->name());
+ nested_type(i)->DebugString(depth, contents);
+ }
+ }
+ for (int i = 0; i < enum_type_count(); i++) {
+ enum_type(i)->DebugString(depth, contents);
+ }
+ for (int i = 0; i < field_count(); i++) {
+ field(i)->DebugString(depth, contents);
+ }
+
+ for (int i = 0; i < extension_range_count(); i++) {
+ strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n",
+ prefix,
+ extension_range(i)->start,
+ extension_range(i)->end - 1);
+ }
+
+ // Group extensions by what they extend, so they can be printed out together.
+ const Descriptor* containing_type = NULL;
+ for (int i = 0; i < extension_count(); i++) {
+ if (extension(i)->containing_type() != containing_type) {
+ if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
+ containing_type = extension(i)->containing_type();
+ strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n",
+ prefix, containing_type->full_name());
+ }
+ extension(i)->DebugString(depth + 1, contents);
+ }
+ if (extension_count() > 0)
+ strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
+
+ strings::SubstituteAndAppend(contents, "$0}\n", prefix);
+}
+
+string FieldDescriptor::DebugString() const {
+ string contents;
+ int depth = 0;
+ if (is_extension()) {
+ strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
+ containing_type()->full_name());
+ depth = 1;
+ }
+ DebugString(depth, &contents);
+ if (is_extension()) {
+ contents.append("}\n");
+ }
+ return contents;
+}
+
+void FieldDescriptor::DebugString(int depth, string *contents) const {
+ string prefix(depth * 2, ' ');
+ string field_type;
+ switch (type()) {
+ case TYPE_MESSAGE:
+ field_type = "." + message_type()->full_name();
+ break;
+ case TYPE_ENUM:
+ field_type = "." + enum_type()->full_name();
+ break;
+ default:
+ field_type = kTypeToName[type()];
+ }
+
+ strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4",
+ prefix,
+ kLabelToName[label()],
+ field_type,
+ type() == TYPE_GROUP ? message_type()->name() :
+ name(),
+ number());
+
+ bool bracketed = false;
+ if (has_default_value()) {
+ bracketed = true;
+ strings::SubstituteAndAppend(contents, " [default = $0",
+ DefaultValueAsString(true));
+ }
+
+ string formatted_options;
+ if (FormatBracketedOptions(options(), &formatted_options)) {
+ contents->append(bracketed ? ", " : " [");
+ bracketed = true;
+ contents->append(formatted_options);
+ }
+
+ if (bracketed) {
+ contents->append("]");
+ }
+
+ if (type() == TYPE_GROUP) {
+ message_type()->DebugString(depth, contents);
+ } else {
+ contents->append(";\n");
+ }
+}
+
+string EnumDescriptor::DebugString() const {
+ string contents;
+ DebugString(0, &contents);
+ return contents;
+}
+
+void EnumDescriptor::DebugString(int depth, string *contents) const {
+ string prefix(depth * 2, ' ');
+ ++depth;
+ strings::SubstituteAndAppend(contents, "$0enum $1 {\n",
+ prefix, name());
+
+ FormatLineOptions(depth, options(), contents);
+
+ for (int i = 0; i < value_count(); i++) {
+ value(i)->DebugString(depth, contents);
+ }
+ strings::SubstituteAndAppend(contents, "$0}\n", prefix);
+}
+
+string EnumValueDescriptor::DebugString() const {
+ string contents;
+ DebugString(0, &contents);
+ return contents;
+}
+
+void EnumValueDescriptor::DebugString(int depth, string *contents) const {
+ string prefix(depth * 2, ' ');
+ strings::SubstituteAndAppend(contents, "$0$1 = $2",
+ prefix, name(), number());
+
+ string formatted_options;
+ if (FormatBracketedOptions(options(), &formatted_options)) {
+ strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
+ }
+ contents->append(";\n");
+}
+
+string ServiceDescriptor::DebugString() const {
+ string contents;
+ DebugString(&contents);
+ return contents;
+}
+
+void ServiceDescriptor::DebugString(string *contents) const {
+ strings::SubstituteAndAppend(contents, "service $0 {\n", name());
+
+ FormatLineOptions(1, options(), contents);
+
+ for (int i = 0; i < method_count(); i++) {
+ method(i)->DebugString(1, contents);
+ }
+
+ contents->append("}\n");
+}
+
+string MethodDescriptor::DebugString() const {
+ string contents;
+ DebugString(0, &contents);
+ return contents;
+}
+
+void MethodDescriptor::DebugString(int depth, string *contents) const {
+ string prefix(depth * 2, ' ');
+ ++depth;
+ strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)",
+ prefix, name(),
+ input_type()->full_name(),
+ output_type()->full_name());
+
+ string formatted_options;
+ if (FormatLineOptions(depth, options(), &formatted_options)) {
+ strings::SubstituteAndAppend(contents, " {\n$0$1}\n",
+ formatted_options, prefix);
+ } else {
+ contents->append(";\n");
+ }
+}
+// ===================================================================
+
+namespace {
+
+// Represents an options message to interpret. Extension names in the option
+// name are respolved relative to name_scope. element_name and orig_opt are
+// used only for error reporting (since the parser records locations against
+// pointers in the original options, not the mutable copy). The Message must be
+// one of the Options messages in descriptor.proto.
+struct OptionsToInterpret {
+ OptionsToInterpret(const string& ns,
+ const string& el,
+ const Message* orig_opt,
+ Message* opt)
+ : name_scope(ns),
+ element_name(el),
+ original_options(orig_opt),
+ options(opt) {
+ }
+ string name_scope;
+ string element_name;
+ const Message* original_options;
+ Message* options;
+};
+
+} // namespace
+
+class DescriptorBuilder {
+ public:
+ DescriptorBuilder(const DescriptorPool* pool,
+ DescriptorPool::Tables* tables,
+ DescriptorPool::ErrorCollector* error_collector);
+ ~DescriptorBuilder();
+
+ const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
+
+ private:
+ friend class OptionInterpreter;
+
+ const DescriptorPool* pool_;
+ DescriptorPool::Tables* tables_; // for convenience
+ DescriptorPool::ErrorCollector* error_collector_;
+
+ // As we build descriptors we store copies of the options messages in
+ // them. We put pointers to those copies in this vector, as we build, so we
+ // can later (after cross-linking) interpret those options.
+ vector<OptionsToInterpret> options_to_interpret_;
+
+ bool had_errors_;
+ string filename_;
+ FileDescriptor* file_;
+ FileDescriptorTables* file_tables_;
+
+ // If LookupSymbol() finds a symbol that is in a file which is not a declared
+ // dependency of this file, it will fail, but will set
+ // possible_undeclared_dependency_ to point at that file. This is only used
+ // by AddNotDefinedError() to report a more useful error message.
+ // possible_undeclared_dependency_name_ is the name of the symbol that was
+ // actually found in possible_undeclared_dependency_, which may be a parent
+ // of the symbol actually looked for.
+ const FileDescriptor* possible_undeclared_dependency_;
+ string possible_undeclared_dependency_name_;
+
+ void AddError(const string& element_name,
+ const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const string& error);
+
+ // Adds an error indicating that undefined_symbol was not defined. Must
+ // only be called after LookupSymbol() fails.
+ void AddNotDefinedError(
+ const string& element_name,
+ const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const string& undefined_symbol);
+
+ // Silly helper which determines if the given file is in the given package.
+ // I.e., either file->package() == package_name or file->package() is a
+ // nested package within package_name.
+ bool IsInPackage(const FileDescriptor* file, const string& package_name);
+
+ // Like tables_->FindSymbol(), but additionally:
+ // - Search the pool's underlay if not found in tables_.
+ // - Insure that the resulting Symbol is from one of the file's declared
+ // dependencies.
+ Symbol FindSymbol(const string& name);
+
+ // Like FindSymbol() but does not require that the symbol is in one of the
+ // file's declared dependencies.
+ Symbol FindSymbolNotEnforcingDeps(const string& name);
+
+ // Like FindSymbol(), but looks up the name relative to some other symbol
+ // name. This first searches siblings of relative_to, then siblings of its
+ // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes
+ // the following calls, returning the first non-null result:
+ // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"),
+ // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called
+ // on the DescriptorPool, this will generate a placeholder type if
+ // the name is not found (unless the name itself is malformed). The
+ // placeholder_type parameter indicates what kind of placeholder should be
+ // constructed in this case. The resolve_mode parameter determines whether
+ // any symbol is returned, or only symbols that are types. Note, however,
+ // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
+ // if it believes that's all it could refer to. The caller should always
+ // check that it receives the type of symbol it was expecting.
+ enum PlaceholderType {
+ PLACEHOLDER_MESSAGE,
+ PLACEHOLDER_ENUM,
+ PLACEHOLDER_EXTENDABLE_MESSAGE
+ };
+ enum ResolveMode {
+ LOOKUP_ALL, LOOKUP_TYPES
+ };
+ Symbol LookupSymbol(const string& name, const string& relative_to,
+ PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE,
+ ResolveMode resolve_mode = LOOKUP_ALL);
+
+ // Like LookupSymbol() but will not return a placeholder even if
+ // AllowUnknownDependencies() has been used.
+ Symbol LookupSymbolNoPlaceholder(const string& name,
+ const string& relative_to,
+ ResolveMode resolve_mode = LOOKUP_ALL);
+
+ // Creates a placeholder type suitable for return from LookupSymbol(). May
+ // return kNullSymbol if the name is not a valid type name.
+ Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type);
+
+ // Creates a placeholder file. Never returns NULL. This is used when an
+ // import is not found and AllowUnknownDependencies() is enabled.
+ const FileDescriptor* NewPlaceholderFile(const string& name);
+
+ // Calls tables_->AddSymbol() and records an error if it fails. Returns
+ // true if successful or false if failed, though most callers can ignore
+ // the return value since an error has already been recorded.
+ bool AddSymbol(const string& full_name,
+ const void* parent, const string& name,
+ const Message& proto, Symbol symbol);
+
+ // Like AddSymbol(), but succeeds if the symbol is already defined as long
+ // as the existing definition is also a package (because it's OK to define
+ // the same package in two different files). Also adds all parents of the
+ // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add
+ // "foo.bar" and "foo" to the table).
+ void AddPackage(const string& name, const Message& proto,
+ const FileDescriptor* file);
+
+ // Checks that the symbol name contains only alphanumeric characters and
+ // underscores. Records an error otherwise.
+ void ValidateSymbolName(const string& name, const string& full_name,
+ const Message& proto);
+
+ // Like ValidateSymbolName(), but the name is allowed to contain periods and
+ // an error is indicated by returning false (not recording the error).
+ bool ValidateQualifiedName(const string& name);
+
+ // Used by BUILD_ARRAY macro (below) to avoid having to have the type
+ // specified as a macro parameter.
+ template <typename Type>
+ inline void AllocateArray(int size, Type** output) {
+ *output = tables_->AllocateArray<Type>(size);
+ }
+
+ // Allocates a copy of orig_options in tables_ and stores it in the
+ // descriptor. Remembers its uninterpreted options, to be interpreted
+ // later. DescriptorT must be one of the Descriptor messages from
+ // descriptor.proto.
+ template<class DescriptorT> void AllocateOptions(
+ const typename DescriptorT::OptionsType& orig_options,
+ DescriptorT* descriptor);
+ // Specialization for FileOptions.
+ void AllocateOptions(const FileOptions& orig_options,
+ FileDescriptor* descriptor);
+
+ // Implementation for AllocateOptions(). Don't call this directly.
+ template<class DescriptorT> void AllocateOptionsImpl(
+ const string& name_scope,
+ const string& element_name,
+ const typename DescriptorT::OptionsType& orig_options,
+ DescriptorT* descriptor);
+
+ // These methods all have the same signature for the sake of the BUILD_ARRAY
+ // macro, below.
+ void BuildMessage(const DescriptorProto& proto,
+ const Descriptor* parent,
+ Descriptor* result);
+ void BuildFieldOrExtension(const FieldDescriptorProto& proto,
+ const Descriptor* parent,
+ FieldDescriptor* result,
+ bool is_extension);
+ void BuildField(const FieldDescriptorProto& proto,
+ const Descriptor* parent,
+ FieldDescriptor* result) {
+ BuildFieldOrExtension(proto, parent, result, false);
+ }
+ void BuildExtension(const FieldDescriptorProto& proto,
+ const Descriptor* parent,
+ FieldDescriptor* result) {
+ BuildFieldOrExtension(proto, parent, result, true);
+ }
+ void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
+ const Descriptor* parent,
+ Descriptor::ExtensionRange* result);
+ void BuildEnum(const EnumDescriptorProto& proto,
+ const Descriptor* parent,
+ EnumDescriptor* result);
+ void BuildEnumValue(const EnumValueDescriptorProto& proto,
+ const EnumDescriptor* parent,
+ EnumValueDescriptor* result);
+ void BuildService(const ServiceDescriptorProto& proto,
+ const void* dummy,
+ ServiceDescriptor* result);
+ void BuildMethod(const MethodDescriptorProto& proto,
+ const ServiceDescriptor* parent,
+ MethodDescriptor* result);
+
+ // Must be run only after building.
+ //
+ // NOTE: Options will not be available during cross-linking, as they
+ // have not yet been interpreted. Defer any handling of options to the
+ // Validate*Options methods.
+ void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto);
+ void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto);
+ void CrossLinkField(FieldDescriptor* field,
+ const FieldDescriptorProto& proto);
+ void CrossLinkEnum(EnumDescriptor* enum_type,
+ const EnumDescriptorProto& proto);
+ void CrossLinkEnumValue(EnumValueDescriptor* enum_value,
+ const EnumValueDescriptorProto& proto);
+ void CrossLinkService(ServiceDescriptor* service,
+ const ServiceDescriptorProto& proto);
+ void CrossLinkMethod(MethodDescriptor* method,
+ const MethodDescriptorProto& proto);
+
+ // Must be run only after cross-linking.
+ void InterpretOptions();
+
+ // A helper class for interpreting options.
+ class OptionInterpreter {
+ public:
+ // Creates an interpreter that operates in the context of the pool of the
+ // specified builder, which must not be NULL. We don't take ownership of the
+ // builder.
+ explicit OptionInterpreter(DescriptorBuilder* builder);
+
+ ~OptionInterpreter();
+
+ // Interprets the uninterpreted options in the specified Options message.
+ // On error, calls AddError() on the underlying builder and returns false.
+ // Otherwise returns true.
+ bool InterpretOptions(OptionsToInterpret* options_to_interpret);
+
+ class AggregateOptionFinder;
+
+ private:
+ // Interprets uninterpreted_option_ on the specified message, which
+ // must be the mutable copy of the original options message to which
+ // uninterpreted_option_ belongs.
+ bool InterpretSingleOption(Message* options);
+
+ // Adds the uninterpreted_option to the given options message verbatim.
+ // Used when AllowUnknownDependencies() is in effect and we can't find
+ // the option's definition.
+ void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option,
+ Message* options);
+
+ // A recursive helper function that drills into the intermediate fields
+ // in unknown_fields to check if field innermost_field is set on the
+ // innermost message. Returns false and sets an error if so.
+ bool ExamineIfOptionIsSet(
+ vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter,
+ vector<const FieldDescriptor*>::const_iterator intermediate_fields_end,
+ const FieldDescriptor* innermost_field, const string& debug_msg_name,
+ const UnknownFieldSet& unknown_fields);
+
+ // Validates the value for the option field of the currently interpreted
+ // option and then sets it on the unknown_field.
+ bool SetOptionValue(const FieldDescriptor* option_field,
+ UnknownFieldSet* unknown_fields);
+
+ // Parses an aggregate value for a CPPTYPE_MESSAGE option and
+ // saves it into *unknown_fields.
+ bool SetAggregateOption(const FieldDescriptor* option_field,
+ UnknownFieldSet* unknown_fields);
+
+ // Convenience functions to set an int field the right way, depending on
+ // its wire type (a single int CppType can represent multiple wire types).
+ void SetInt32(int number, int32 value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields);
+ void SetInt64(int number, int64 value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields);
+ void SetUInt32(int number, uint32 value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields);
+ void SetUInt64(int number, uint64 value, FieldDescriptor::Type type,
+ UnknownFieldSet* unknown_fields);
+
+ // A helper function that adds an error at the specified location of the
+ // option we're currently interpreting, and returns false.
+ bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location,
+ const string& msg) {
+ builder_->AddError(options_to_interpret_->element_name,
+ *uninterpreted_option_, location, msg);
+ return false;
+ }
+
+ // A helper function that adds an error at the location of the option name
+ // and returns false.
+ bool AddNameError(const string& msg) {
+ return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg);
+ }
+
+ // A helper function that adds an error at the location of the option name
+ // and returns false.
+ bool AddValueError(const string& msg) {
+ return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg);
+ }
+
+ // We interpret against this builder's pool. Is never NULL. We don't own
+ // this pointer.
+ DescriptorBuilder* builder_;
+
+ // The options we're currently interpreting, or NULL if we're not in a call
+ // to InterpretOptions.
+ const OptionsToInterpret* options_to_interpret_;
+
+ // The option we're currently interpreting within options_to_interpret_, or
+ // NULL if we're not in a call to InterpretOptions(). This points to a
+ // submessage of the original option, not the mutable copy. Therefore we
+ // can use it to find locations recorded by the parser.
+ const UninterpretedOption* uninterpreted_option_;
+
+ // Factory used to create the dynamic messages we need to parse
+ // any aggregate option values we encounter.
+ DynamicMessageFactory dynamic_factory_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter);
+ };
+
+ // Work-around for broken compilers: According to the C++ standard,
+ // OptionInterpreter should have access to the private members of any class
+ // which has declared DescriptorBuilder as a friend. Unfortunately some old
+ // versions of GCC and other compilers do not implement this correctly. So,
+ // we have to have these intermediate methods to provide access. We also
+ // redundantly declare OptionInterpreter a friend just to make things extra
+ // clear for these bad compilers.
+ friend class OptionInterpreter;
+ friend class OptionInterpreter::AggregateOptionFinder;
+
+ static inline bool get_allow_unknown(const DescriptorPool* pool) {
+ return pool->allow_unknown_;
+ }
+ static inline bool get_is_placeholder(const Descriptor* descriptor) {
+ return descriptor->is_placeholder_;
+ }
+ static inline void assert_mutex_held(const DescriptorPool* pool) {
+ if (pool->mutex_ != NULL) {
+ pool->mutex_->AssertHeld();
+ }
+ }
+
+ // Must be run only after options have been interpreted.
+ //
+ // NOTE: Validation code must only reference the options in the mutable
+ // descriptors, which are the ones that have been interpreted. The const
+ // proto references are passed in only so they can be provided to calls to
+ // AddError(). Do not look at their options, which have not been interpreted.
+ void ValidateFileOptions(FileDescriptor* file,
+ const FileDescriptorProto& proto);
+ void ValidateMessageOptions(Descriptor* message,
+ const DescriptorProto& proto);
+ void ValidateFieldOptions(FieldDescriptor* field,
+ const FieldDescriptorProto& proto);
+ void ValidateEnumOptions(EnumDescriptor* enm,
+ const EnumDescriptorProto& proto);
+ void ValidateEnumValueOptions(EnumValueDescriptor* enum_value,
+ const EnumValueDescriptorProto& proto);
+ void ValidateServiceOptions(ServiceDescriptor* service,
+ const ServiceDescriptorProto& proto);
+ void ValidateMethodOptions(MethodDescriptor* method,
+ const MethodDescriptorProto& proto);
+
+ void ValidateMapKey(FieldDescriptor* field,
+ const FieldDescriptorProto& proto);
+};
+
+const FileDescriptor* DescriptorPool::BuildFile(
+ const FileDescriptorProto& proto) {
+ GOOGLE_CHECK(fallback_database_ == NULL)
+ << "Cannot call BuildFile on a DescriptorPool that uses a "
+ "DescriptorDatabase. You must instead find a way to get your file "
+ "into the underlying database.";
+ GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK.
+ return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto);
+}
+
+const FileDescriptor* DescriptorPool::BuildFileCollectingErrors(
+ const FileDescriptorProto& proto,
+ ErrorCollector* error_collector) {
+ GOOGLE_CHECK(fallback_database_ == NULL)
+ << "Cannot call BuildFile on a DescriptorPool that uses a "
+ "DescriptorDatabase. You must instead find a way to get your file "
+ "into the underlying database.";
+ GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK.
+ return DescriptorBuilder(this, tables_.get(),
+ error_collector).BuildFile(proto);
+}
+
+const FileDescriptor* DescriptorPool::BuildFileFromDatabase(
+ const FileDescriptorProto& proto) const {
+ mutex_->AssertHeld();
+ return DescriptorBuilder(this, tables_.get(),
+ default_error_collector_).BuildFile(proto);
+}
+
+DescriptorBuilder::DescriptorBuilder(
+ const DescriptorPool* pool,
+ DescriptorPool::Tables* tables,
+ DescriptorPool::ErrorCollector* error_collector)
+ : pool_(pool),
+ tables_(tables),
+ error_collector_(error_collector),
+ had_errors_(false),
+ possible_undeclared_dependency_(NULL) {}
+
+DescriptorBuilder::~DescriptorBuilder() {}
+
+void DescriptorBuilder::AddError(
+ const string& element_name,
+ const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const string& error) {
+ if (error_collector_ == NULL) {
+ if (!had_errors_) {
+ GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_
+ << "\":";
+ }
+ GOOGLE_LOG(ERROR) << " " << element_name << ": " << error;
+ } else {
+ error_collector_->AddError(filename_, element_name,
+ &descriptor, location, error);
+ }
+ had_errors_ = true;
+}
+
+void DescriptorBuilder::AddNotDefinedError(
+ const string& element_name,
+ const Message& descriptor,
+ DescriptorPool::ErrorCollector::ErrorLocation location,
+ const string& undefined_symbol) {
+ if (possible_undeclared_dependency_ == NULL) {
+ AddError(element_name, descriptor, location,
+ "\"" + undefined_symbol + "\" is not defined.");
+ } else {
+ AddError(element_name, descriptor, location,
+ "\"" + possible_undeclared_dependency_name_ +
+ "\" seems to be defined in \"" +
+ possible_undeclared_dependency_->name() + "\", which is not "
+ "imported by \"" + filename_ + "\". To use it here, please "
+ "add the necessary import.");
+ }
+}
+
+bool DescriptorBuilder::IsInPackage(const FileDescriptor* file,
+ const string& package_name) {
+ return HasPrefixString(file->package(), package_name) &&
+ (file->package().size() == package_name.size() ||
+ file->package()[package_name.size()] == '.');
+}
+
+Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) {
+ Symbol result;
+
+ // We need to search our pool and all its underlays.
+ const DescriptorPool* pool = pool_;
+ while (true) {
+ // If we are looking at an underlay, we must lock its mutex_, since we are
+ // accessing the underlay's tables_ dircetly.
+ MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_);
+
+ // Note that we don't have to check fallback_database_ here because the
+ // symbol has to be in one of its file's direct dependencies, and we have
+ // already loaded those by the time we get here.
+ result = pool->tables_->FindSymbol(name);
+ if (!result.IsNull()) break;
+ if (pool->underlay_ == NULL) return kNullSymbol;
+ pool = pool->underlay_;
+ }
+
+ return result;
+}
+
+Symbol DescriptorBuilder::FindSymbol(const string& name) {
+ Symbol result = FindSymbolNotEnforcingDeps(name);
+
+ if (!pool_->enforce_dependencies_) {
+ // Hack for CompilerUpgrader.
+ return result;
+ }
+
+ // Only find symbols which were defined in this file or one of its
+ // dependencies.
+ const FileDescriptor* file = result.GetFile();
+ if (file == file_) return result;
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ if (file == file_->dependency(i)) return result;
+ }
+
+ if (result.type == Symbol::PACKAGE) {
+ // Arg, this is overcomplicated. The symbol is a package name. It could
+ // be that the package was defined in multiple files. result.GetFile()
+ // returns the first file we saw that used this package. We've determined
+ // that that file is not a direct dependency of the file we are currently
+ // building, but it could be that some other file which *is* a direct
+ // dependency also defines the same package. We can't really rule out this
+ // symbol unless none of the dependencies define it.
+ if (IsInPackage(file_, name)) return result;
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ // Note: A dependency may be NULL if it was not found or had errors.
+ if (file_->dependency(i) != NULL &&
+ IsInPackage(file_->dependency(i), name)) {
+ return result;
+ }
+ }
+ }
+
+ possible_undeclared_dependency_ = file;
+ possible_undeclared_dependency_name_ = name;
+ return kNullSymbol;
+}
+
+Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
+ const string& name, const string& relative_to, ResolveMode resolve_mode) {
+ possible_undeclared_dependency_ = NULL;
+
+ if (name.size() > 0 && name[0] == '.') {
+ // Fully-qualified name.
+ return FindSymbol(name.substr(1));
+ }
+
+ // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
+ // defined in multiple parent scopes, we only want to find "Bar.baz" in the
+ // innermost one. E.g., the following should produce an error:
+ // message Bar { message Baz {} }
+ // message Foo {
+ // message Bar {
+ // }
+ // optional Bar.Baz baz = 1;
+ // }
+ // So, we look for just "Foo" first, then look for "Bar.baz" within it if
+ // found.
+ string::size_type name_dot_pos = name.find_first_of('.');
+ string first_part_of_name;
+ if (name_dot_pos == string::npos) {
+ first_part_of_name = name;
+ } else {
+ first_part_of_name = name.substr(0, name_dot_pos);
+ }
+
+ string scope_to_try(relative_to);
+
+ while (true) {
+ // Chop off the last component of the scope.
+ string::size_type dot_pos = scope_to_try.find_last_of('.');
+ if (dot_pos == string::npos) {
+ return FindSymbol(name);
+ } else {
+ scope_to_try.erase(dot_pos);
+ }
+
+ // Append ".first_part_of_name" and try to find.
+ string::size_type old_size = scope_to_try.size();
+ scope_to_try.append(1, '.');
+ scope_to_try.append(first_part_of_name);
+ Symbol result = FindSymbol(scope_to_try);
+ if (!result.IsNull()) {
+ if (first_part_of_name.size() < name.size()) {
+ // name is a compound symbol, of which we only found the first part.
+ // Now try to look up the rest of it.
+ if (result.IsAggregate()) {
+ scope_to_try.append(name, first_part_of_name.size(),
+ name.size() - first_part_of_name.size());
+ return FindSymbol(scope_to_try);
+ } else {
+ // We found a symbol but it's not an aggregate. Continue the loop.
+ }
+ } else {
+ if (resolve_mode == LOOKUP_TYPES && !result.IsType()) {
+ // We found a symbol but it's not a type. Continue the loop.
+ } else {
+ return result;
+ }
+ }
+ }
+
+ // Not found. Remove the name so we can try again.
+ scope_to_try.erase(old_size);
+ }
+}
+
+Symbol DescriptorBuilder::LookupSymbol(
+ const string& name, const string& relative_to,
+ PlaceholderType placeholder_type, ResolveMode resolve_mode) {
+ Symbol result = LookupSymbolNoPlaceholder(
+ name, relative_to, resolve_mode);
+ if (result.IsNull() && pool_->allow_unknown_) {
+ // Not found, but AllowUnknownDependencies() is enabled. Return a
+ // placeholder instead.
+ result = NewPlaceholder(name, placeholder_type);
+ }
+ return result;
+}
+
+Symbol DescriptorBuilder::NewPlaceholder(const string& name,
+ PlaceholderType placeholder_type) {
+ // Compute names.
+ const string* placeholder_full_name;
+ const string* placeholder_name;
+ const string* placeholder_package;
+
+ if (!ValidateQualifiedName(name)) return kNullSymbol;
+ if (name[0] == '.') {
+ // Fully-qualified.
+ placeholder_full_name = tables_->AllocateString(name.substr(1));
+ } else {
+ placeholder_full_name = tables_->AllocateString(name);
+ }
+
+ string::size_type dotpos = placeholder_full_name->find_last_of('.');
+ if (dotpos != string::npos) {
+ placeholder_package = tables_->AllocateString(
+ placeholder_full_name->substr(0, dotpos));
+ placeholder_name = tables_->AllocateString(
+ placeholder_full_name->substr(dotpos + 1));
+ } else {
+ placeholder_package = &kEmptyString;
+ placeholder_name = placeholder_full_name;
+ }
+
+ // Create the placeholders.
+ FileDescriptor* placeholder_file = tables_->Allocate<FileDescriptor>();
+ memset(placeholder_file, 0, sizeof(*placeholder_file));
+
+ placeholder_file->name_ =
+ tables_->AllocateString(*placeholder_full_name + ".placeholder.proto");
+ placeholder_file->package_ = placeholder_package;
+ placeholder_file->pool_ = pool_;
+ placeholder_file->options_ = &FileOptions::default_instance();
+ placeholder_file->tables_ = &FileDescriptorTables::kEmpty;
+ // All other fields are zero or NULL.
+
+ if (placeholder_type == PLACEHOLDER_ENUM) {
+ placeholder_file->enum_type_count_ = 1;
+ placeholder_file->enum_types_ =
+ tables_->AllocateArray<EnumDescriptor>(1);
+
+ EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0];
+ memset(placeholder_enum, 0, sizeof(*placeholder_enum));
+
+ placeholder_enum->full_name_ = placeholder_full_name;
+ placeholder_enum->name_ = placeholder_name;
+ placeholder_enum->file_ = placeholder_file;
+ placeholder_enum->options_ = &EnumOptions::default_instance();
+ placeholder_enum->is_placeholder_ = true;
+ placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.');
+
+ // Enums must have at least one value.
+ placeholder_enum->value_count_ = 1;
+ placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1);
+
+ EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0];
+ memset(placeholder_value, 0, sizeof(*placeholder_value));
+
+ placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE");
+ // Note that enum value names are siblings of their type, not children.
+ placeholder_value->full_name_ =
+ placeholder_package->empty() ? placeholder_value->name_ :
+ tables_->AllocateString(*placeholder_package + ".PLACEHOLDER_VALUE");
+
+ placeholder_value->number_ = 0;
+ placeholder_value->type_ = placeholder_enum;
+ placeholder_value->options_ = &EnumValueOptions::default_instance();
+
+ return Symbol(placeholder_enum);
+ } else {
+ placeholder_file->message_type_count_ = 1;
+ placeholder_file->message_types_ =
+ tables_->AllocateArray<Descriptor>(1);
+
+ Descriptor* placeholder_message = &placeholder_file->message_types_[0];
+ memset(placeholder_message, 0, sizeof(*placeholder_message));
+
+ placeholder_message->full_name_ = placeholder_full_name;
+ placeholder_message->name_ = placeholder_name;
+ placeholder_message->file_ = placeholder_file;
+ placeholder_message->options_ = &MessageOptions::default_instance();
+ placeholder_message->is_placeholder_ = true;
+ placeholder_message->is_unqualified_placeholder_ = (name[0] != '.');
+
+ if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
+ placeholder_message->extension_range_count_ = 1;
+ placeholder_message->extension_ranges_ =
+ tables_->AllocateArray<Descriptor::ExtensionRange>(1);
+ placeholder_message->extension_ranges_->start = 1;
+ // kMaxNumber + 1 because ExtensionRange::end is exclusive.
+ placeholder_message->extension_ranges_->end =
+ FieldDescriptor::kMaxNumber + 1;
+ }
+
+ return Symbol(placeholder_message);
+ }
+}
+
+const FileDescriptor* DescriptorBuilder::NewPlaceholderFile(
+ const string& name) {
+ FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>();
+ memset(placeholder, 0, sizeof(*placeholder));
+
+ placeholder->name_ = tables_->AllocateString(name);
+ placeholder->package_ = &kEmptyString;
+ placeholder->pool_ = pool_;
+ placeholder->options_ = &FileOptions::default_instance();
+ placeholder->tables_ = &FileDescriptorTables::kEmpty;
+ // All other fields are zero or NULL.
+
+ return placeholder;
+}
+
+bool DescriptorBuilder::AddSymbol(
+ const string& full_name, const void* parent, const string& name,
+ const Message& proto, Symbol symbol) {
+ // If the caller passed NULL for the parent, the symbol is at file scope.
+ // Use its file as the parent instead.
+ if (parent == NULL) parent = file_;
+
+ if (tables_->AddSymbol(full_name, symbol)) {
+ if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) {
+ GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in "
+ "symbols_by_name_, but was defined in symbols_by_parent_; "
+ "this shouldn't be possible.";
+ return false;
+ }
+ return true;
+ } else {
+ const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile();
+ if (other_file == file_) {
+ string::size_type dot_pos = full_name.find_last_of('.');
+ if (dot_pos == string::npos) {
+ AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + full_name + "\" is already defined.");
+ } else {
+ AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + full_name.substr(dot_pos + 1) +
+ "\" is already defined in \"" +
+ full_name.substr(0, dot_pos) + "\".");
+ }
+ } else {
+ // Symbol seems to have been defined in a different file.
+ AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + full_name + "\" is already defined in file \"" +
+ other_file->name() + "\".");
+ }
+ return false;
+ }
+}
+
+void DescriptorBuilder::AddPackage(
+ const string& name, const Message& proto, const FileDescriptor* file) {
+ if (tables_->AddSymbol(name, Symbol(file))) {
+ // Success. Also add parent package, if any.
+ string::size_type dot_pos = name.find_last_of('.');
+ if (dot_pos == string::npos) {
+ // No parents.
+ ValidateSymbolName(name, name, proto);
+ } else {
+ // Has parent.
+ string* parent_name = tables_->AllocateString(name.substr(0, dot_pos));
+ AddPackage(*parent_name, proto, file);
+ ValidateSymbolName(name.substr(dot_pos + 1), name, proto);
+ }
+ } else {
+ Symbol existing_symbol = tables_->FindSymbol(name);
+ // It's OK to redefine a package.
+ if (existing_symbol.type != Symbol::PACKAGE) {
+ // Symbol seems to have been defined in a different file.
+ AddError(name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + name + "\" is already defined (as something other than "
+ "a package) in file \"" + existing_symbol.GetFile()->name() +
+ "\".");
+ }
+ }
+}
+
+void DescriptorBuilder::ValidateSymbolName(
+ const string& name, const string& full_name, const Message& proto) {
+ if (name.empty()) {
+ AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+ "Missing name.");
+ } else {
+ for (int i = 0; i < name.size(); i++) {
+ // I don't trust isalnum() due to locales. :(
+ if ((name[i] < 'a' || 'z' < name[i]) &&
+ (name[i] < 'A' || 'Z' < name[i]) &&
+ (name[i] < '0' || '9' < name[i]) &&
+ (name[i] != '_')) {
+ AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
+ "\"" + name + "\" is not a valid identifier.");
+ }
+ }
+ }
+}
+
+bool DescriptorBuilder::ValidateQualifiedName(const string& name) {
+ bool last_was_period = false;
+
+ for (int i = 0; i < name.size(); i++) {
+ // I don't trust isalnum() due to locales. :(
+ if (('a' <= name[i] && name[i] <= 'z') ||
+ ('A' <= name[i] && name[i] <= 'Z') ||
+ ('0' <= name[i] && name[i] <= '9') ||
+ (name[i] == '_')) {
+ last_was_period = false;
+ } else if (name[i] == '.') {
+ if (last_was_period) return false;
+ last_was_period = true;
+ } else {
+ return false;
+ }
+ }
+
+ return !name.empty() && !last_was_period;
+}
+
+// -------------------------------------------------------------------
+
+// This generic implementation is good for all descriptors except
+// FileDescriptor.
+template<class DescriptorT> void DescriptorBuilder::AllocateOptions(
+ const typename DescriptorT::OptionsType& orig_options,
+ DescriptorT* descriptor) {
+ AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(),
+ orig_options, descriptor);
+}
+
+// We specialize for FileDescriptor.
+void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options,
+ FileDescriptor* descriptor) {
+ // We add the dummy token so that LookupSymbol does the right thing.
+ AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(),
+ orig_options, descriptor);
+}
+
+template<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl(
+ const string& name_scope,
+ const string& element_name,
+ const typename DescriptorT::OptionsType& orig_options,
+ DescriptorT* descriptor) {
+ // We need to use a dummy pointer to work around a bug in older versions of
+ // GCC. Otherwise, the following two lines could be replaced with:
+ // typename DescriptorT::OptionsType* options =
+ // tables_->AllocateMessage<typename DescriptorT::OptionsType>();
+ typename DescriptorT::OptionsType* const dummy = NULL;
+ typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy);
+ options->CopyFrom(orig_options);
+ descriptor->options_ = options;
+
+ // Don't add to options_to_interpret_ unless there were uninterpreted
+ // options. This not only avoids unnecessary work, but prevents a
+ // bootstrapping problem when building descriptors for descriptor.proto.
+ // descriptor.proto does not contain any uninterpreted options, but
+ // attempting to interpret options anyway will cause
+ // OptionsType::GetDescriptor() to be called which may then deadlock since
+ // we're still trying to build it.
+ if (options->uninterpreted_option_size() > 0) {
+ options_to_interpret_.push_back(
+ OptionsToInterpret(name_scope, element_name, &orig_options, options));
+ }
+}
+
+
+// A common pattern: We want to convert a repeated field in the descriptor
+// to an array of values, calling some method to build each value.
+#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \
+ OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \
+ AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \
+ for (int i = 0; i < INPUT.NAME##_size(); i++) { \
+ METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \
+ }
+
+const FileDescriptor* DescriptorBuilder::BuildFile(
+ const FileDescriptorProto& proto) {
+ filename_ = proto.name();
+
+ // Check if the file already exists and is identical to the one being built.
+ // Note: This only works if the input is canonical -- that is, it
+ // fully-qualifies all type names, has no UninterpretedOptions, etc.
+ // This is fine, because this idempotency "feature" really only exists to
+ // accomodate one hack in the proto1->proto2 migration layer.
+ const FileDescriptor* existing_file = tables_->FindFile(filename_);
+ if (existing_file != NULL) {
+ // File already in pool. Compare the existing one to the input.
+ FileDescriptorProto existing_proto;
+ existing_file->CopyTo(&existing_proto);
+ if (existing_proto.SerializeAsString() == proto.SerializeAsString()) {
+ // They're identical. Return the existing descriptor.
+ return existing_file;
+ }
+
+ // Not a match. The error will be detected and handled later.
+ }
+
+ // Check to see if this file is already on the pending files list.
+ // TODO(kenton): Allow recursive imports? It may not work with some
+ // (most?) programming languages. E.g., in C++, a forward declaration
+ // of a type is not sufficient to allow it to be used even in a
+ // generated header file due to inlining. This could perhaps be
+ // worked around using tricks involving inserting #include statements
+ // mid-file, but that's pretty ugly, and I'm pretty sure there are
+ // some languages out there that do not allow recursive dependencies
+ // at all.
+ for (int i = 0; i < tables_->pending_files_.size(); i++) {
+ if (tables_->pending_files_[i] == proto.name()) {
+ string error_message("File recursively imports itself: ");
+ for (; i < tables_->pending_files_.size(); i++) {
+ error_message.append(tables_->pending_files_[i]);
+ error_message.append(" -> ");
+ }
+ error_message.append(proto.name());
+
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ error_message);
+ return NULL;
+ }
+ }
+
+ // If we have a fallback_database_, attempt to load all dependencies now,
+ // before checkpointing tables_. This avoids confusion with recursive
+ // checkpoints.
+ if (pool_->fallback_database_ != NULL) {
+ tables_->pending_files_.push_back(proto.name());
+ for (int i = 0; i < proto.dependency_size(); i++) {
+ if (tables_->FindFile(proto.dependency(i)) == NULL &&
+ (pool_->underlay_ == NULL ||
+ pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) {
+ // We don't care what this returns since we'll find out below anyway.
+ pool_->TryFindFileInFallbackDatabase(proto.dependency(i));
+ }
+ }
+ tables_->pending_files_.pop_back();
+ }
+
+ // Checkpoint the tables so that we can roll back if something goes wrong.
+ tables_->Checkpoint();
+
+ FileDescriptor* result = tables_->Allocate<FileDescriptor>();
+ file_ = result;
+
+ file_tables_ = tables_->AllocateFileTables();
+ file_->tables_ = file_tables_;
+
+ if (!proto.has_name()) {
+ AddError("", proto, DescriptorPool::ErrorCollector::OTHER,
+ "Missing field: FileDescriptorProto.name.");
+ }
+
+ result->name_ = tables_->AllocateString(proto.name());
+ if (proto.has_package()) {
+ result->package_ = tables_->AllocateString(proto.package());
+ } else {
+ // We cannot rely on proto.package() returning a valid string if
+ // proto.has_package() is false, because we might be running at static
+ // initialization time, in which case default values have not yet been
+ // initialized.
+ result->package_ = tables_->AllocateString("");
+ }
+ result->pool_ = pool_;
+
+ // Add to tables.
+ if (!tables_->AddFile(result)) {
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ "A file with this name is already in the pool.");
+ // Bail out early so that if this is actually the exact same file, we
+ // don't end up reporting that every single symbol is already defined.
+ tables_->Rollback();
+ return NULL;
+ }
+ if (!result->package().empty()) {
+ AddPackage(result->package(), proto, result);
+ }
+
+ // Make sure all dependencies are loaded.
+ set<string> seen_dependencies;
+ result->dependency_count_ = proto.dependency_size();
+ result->dependencies_ =
+ tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
+ for (int i = 0; i < proto.dependency_size(); i++) {
+ if (!seen_dependencies.insert(proto.dependency(i)).second) {
+ AddError(proto.name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ "Import \"" + proto.dependency(i) + "\" was listed twice.");
+ }
+
+ const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
+ if (dependency == NULL && pool_->underlay_ != NULL) {
+ dependency = pool_->underlay_->FindFileByName(proto.dependency(i));
+ }
+
+ if (dependency == NULL) {
+ if (pool_->allow_unknown_) {
+ dependency = NewPlaceholderFile(proto.dependency(i));
+ } else {
+ string message;
+ if (pool_->fallback_database_ == NULL) {
+ message = "Import \"" + proto.dependency(i) +
+ "\" has not been loaded.";
+ } else {
+ message = "Import \"" + proto.dependency(i) +
+ "\" was not found or had errors.";
+ }
+ AddError(proto.name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ message);
+ }
+ }
+
+ result->dependencies_[i] = dependency;
+ }
+
+ // Convert children.
+ BUILD_ARRAY(proto, result, message_type, BuildMessage , NULL);
+ BUILD_ARRAY(proto, result, enum_type , BuildEnum , NULL);
+ BUILD_ARRAY(proto, result, service , BuildService , NULL);
+ BUILD_ARRAY(proto, result, extension , BuildExtension, NULL);
+
+ // Copy options.
+ if (!proto.has_options()) {
+ result->options_ = NULL; // Will set to default_instance later.
+ } else {
+ AllocateOptions(proto.options(), result);
+ }
+
+ // Note that the following steps must occur in exactly the specified order.
+
+ // Cross-link.
+ CrossLinkFile(result, proto);
+
+ // Interpret any remaining uninterpreted options gathered into
+ // options_to_interpret_ during descriptor building. Cross-linking has made
+ // extension options known, so all interpretations should now succeed.
+ if (!had_errors_) {
+ OptionInterpreter option_interpreter(this);
+ for (vector<OptionsToInterpret>::iterator iter =
+ options_to_interpret_.begin();
+ iter != options_to_interpret_.end(); ++iter) {
+ option_interpreter.InterpretOptions(&(*iter));
+ }
+ options_to_interpret_.clear();
+ }
+
+ // Validate options.
+ if (!had_errors_) {
+ ValidateFileOptions(result, proto);
+ }
+
+ if (had_errors_) {
+ tables_->Rollback();
+ return NULL;
+ } else {
+ tables_->Checkpoint();
+ return result;
+ }
+}
+
+void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
+ const Descriptor* parent,
+ Descriptor* result) {
+ const string& scope = (parent == NULL) ?
+ file_->package() : parent->full_name();
+ string* full_name = tables_->AllocateString(scope);
+ if (!full_name->empty()) full_name->append(1, '.');
+ full_name->append(proto.name());
+
+ ValidateSymbolName(proto.name(), *full_name, proto);
+
+ result->name_ = tables_->AllocateString(proto.name());
+ result->full_name_ = full_name;
+ result->file_ = file_;
+ result->containing_type_ = parent;
+ result->is_placeholder_ = false;
+ result->is_unqualified_placeholder_ = false;
+
+ BUILD_ARRAY(proto, result, field , BuildField , result);
+ BUILD_ARRAY(proto, result, nested_type , BuildMessage , result);
+ BUILD_ARRAY(proto, result, enum_type , BuildEnum , result);
+ BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result);
+ BUILD_ARRAY(proto, result, extension , BuildExtension , result);
+
+ // Copy options.
+ if (!proto.has_options()) {
+ result->options_ = NULL; // Will set to default_instance later.
+ } else {
+ AllocateOptions(proto.options(), result);
+ }
+
+ AddSymbol(result->full_name(), parent, result->name(),
+ proto, Symbol(result));
+
+ // Check that no fields have numbers in extension ranges.
+ for (int i = 0; i < result->field_count(); i++) {
+ const FieldDescriptor* field = result->field(i);
+ for (int j = 0; j < result->extension_range_count(); j++) {
+ const Descriptor::ExtensionRange* range = result->extension_range(j);
+ if (range->start <= field->number() && field->number() < range->end) {
+ AddError(field->full_name(), proto.extension_range(j),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute(
+ "Extension range $0 to $1 includes field \"$2\" ($3).",
+ range->start, range->end - 1,
+ field->name(), field->number()));
+ }
+ }
+ }
+
+ // Check that extension ranges don't overlap.
+ for (int i = 0; i < result->extension_range_count(); i++) {
+ const Descriptor::ExtensionRange* range1 = result->extension_range(i);
+ for (int j = i + 1; j < result->extension_range_count(); j++) {
+ const Descriptor::ExtensionRange* range2 = result->extension_range(j);
+ if (range1->end > range2->start && range2->end > range1->start) {
+ AddError(result->full_name(), proto.extension_range(j),
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Extension range $0 to $1 overlaps with "
+ "already-defined range $2 to $3.",
+ range2->start, range2->end - 1,
+ range1->start, range1->end - 1));
+ }
+ }
+ }
+}
+
+void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
+ const Descriptor* parent,
+ FieldDescriptor* result,
+ bool is_extension) {
+ const string& scope = (parent == NULL) ?
+ file_->package() : parent->full_name();
+ string* full_name = tables_->AllocateString(scope);
+ if (!full_name->empty()) full_name->append(1, '.');
+ full_name->append(proto.name());
+
+ ValidateSymbolName(proto.name(), *full_name, proto);
+
+ result->name_ = tables_->AllocateString(proto.name());
+ result->full_name_ = full_name;
+ result->file_ = file_;
+ result->number_ = proto.number();
+ result->is_extension_ = is_extension;
+
+ // If .proto files follow the style guide then the name should already be
+ // lower-cased. If that's the case we can just reuse the string we already
+ // allocated rather than allocate a new one.
+ string lowercase_name(proto.name());
+ LowerString(&lowercase_name);
+ if (lowercase_name == proto.name()) {
+ result->lowercase_name_ = result->name_;
+ } else {
+ result->lowercase_name_ = tables_->AllocateString(lowercase_name);
+ }
+
+ // Don't bother with the above optimization for camel-case names since
+ // .proto files that follow the guide shouldn't be using names in this
+ // format, so the optimization wouldn't help much.
+ result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name()));
+
+ // Some compilers do not allow static_cast directly between two enum types,
+ // so we must cast to int first.
+ result->type_ = static_cast<FieldDescriptor::Type>(
+ implicit_cast<int>(proto.type()));
+ result->label_ = static_cast<FieldDescriptor::Label>(
+ implicit_cast<int>(proto.label()));
+
+ // Some of these may be filled in when cross-linking.
+ result->containing_type_ = NULL;
+ result->extension_scope_ = NULL;
+ result->experimental_map_key_ = NULL;
+ result->message_type_ = NULL;
+ result->enum_type_ = NULL;
+
+ result->has_default_value_ = proto.has_default_value();
+ if (proto.has_default_value() && result->is_repeated()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Repeated fields can't have default values.");
+ }
+
+ if (proto.has_type()) {
+ if (proto.has_default_value()) {
+ char* end_pos = NULL;
+ switch (result->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ result->default_value_int32_ =
+ strtol(proto.default_value().c_str(), &end_pos, 0);
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ result->default_value_int64_ =
+ strto64(proto.default_value().c_str(), &end_pos, 0);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ result->default_value_uint32_ =
+ strtoul(proto.default_value().c_str(), &end_pos, 0);
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ result->default_value_uint64_ =
+ strtou64(proto.default_value().c_str(), &end_pos, 0);
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ if (proto.default_value() == "inf") {
+ result->default_value_float_ = numeric_limits<float>::infinity();
+ } else if (proto.default_value() == "-inf") {
+ result->default_value_float_ = -numeric_limits<float>::infinity();
+ } else if (proto.default_value() == "nan") {
+ result->default_value_float_ = numeric_limits<float>::quiet_NaN();
+ } else {
+ result->default_value_float_ =
+ NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ if (proto.default_value() == "inf") {
+ result->default_value_double_ = numeric_limits<double>::infinity();
+ } else if (proto.default_value() == "-inf") {
+ result->default_value_double_ = -numeric_limits<double>::infinity();
+ } else if (proto.default_value() == "nan") {
+ result->default_value_double_ = numeric_limits<double>::quiet_NaN();
+ } else {
+ result->default_value_double_ =
+ NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ if (proto.default_value() == "true") {
+ result->default_value_bool_ = true;
+ } else if (proto.default_value() == "false") {
+ result->default_value_bool_ = false;
+ } else {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Boolean default must be true or false.");
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ // This will be filled in when cross-linking.
+ result->default_value_enum_ = NULL;
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (result->type() == FieldDescriptor::TYPE_BYTES) {
+ result->default_value_string_ = tables_->AllocateString(
+ UnescapeCEscapeString(proto.default_value()));
+ } else {
+ result->default_value_string_ =
+ tables_->AllocateString(proto.default_value());
+ }
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Messages can't have default values.");
+ result->has_default_value_ = false;
+ break;
+ }
+
+ if (end_pos != NULL) {
+ // end_pos is only set non-NULL by the parsers for numeric types, above.
+ // This checks that the default was non-empty and had no extra junk
+ // after the end of the number.
+ if (proto.default_value().empty() || *end_pos != '\0') {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Couldn't parse default value.");
+ }
+ }
+ } else {
+ // No explicit default value
+ switch (result->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ result->default_value_int32_ = 0;
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ result->default_value_int64_ = 0;
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ result->default_value_uint32_ = 0;
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ result->default_value_uint64_ = 0;
+ break;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ result->default_value_float_ = 0.0f;
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ result->default_value_double_ = 0.0;
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ result->default_value_bool_ = false;
+ break;
+ case FieldDescriptor::CPPTYPE_ENUM:
+ // This will be filled in when cross-linking.
+ result->default_value_enum_ = NULL;
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ result->default_value_string_ = &kEmptyString;
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ break;
+ }
+ }
+ }
+
+ if (result->number() <= 0) {
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ "Field numbers must be positive integers.");
+ } else if (result->number() > FieldDescriptor::kMaxNumber) {
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Field numbers cannot be greater than $0.",
+ FieldDescriptor::kMaxNumber));
+ } else if (result->number() >= FieldDescriptor::kFirstReservedNumber &&
+ result->number() <= FieldDescriptor::kLastReservedNumber) {
+ AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute(
+ "Field numbers $0 through $1 are reserved for the protocol "
+ "buffer library implementation.",
+ FieldDescriptor::kFirstReservedNumber,
+ FieldDescriptor::kLastReservedNumber));
+ }
+
+ if (is_extension) {
+ if (!proto.has_extendee()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ "FieldDescriptorProto.extendee not set for extension field.");
+ }
+
+ result->extension_scope_ = parent;
+ } else {
+ if (proto.has_extendee()) {
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ "FieldDescriptorProto.extendee set for non-extension field.");
+ }
+
+ result->containing_type_ = parent;
+ }
+
+ // Copy options.
+ if (!proto.has_options()) {
+ result->options_ = NULL; // Will set to default_instance later.
+ } else {
+ AllocateOptions(proto.options(), result);
+ }
+
+ AddSymbol(result->full_name(), parent, result->name(),
+ proto, Symbol(result));
+}
+
+void DescriptorBuilder::BuildExtensionRange(
+ const DescriptorProto::ExtensionRange& proto,
+ const Descriptor* parent,
+ Descriptor::ExtensionRange* result) {
+ result->start = proto.start();
+ result->end = proto.end();
+ if (result->start <= 0) {
+ AddError(parent->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER,
+ "Extension numbers must be positive integers.");
+ }
+
+ if (result->end > FieldDescriptor::kMaxNumber + 1) {
+ AddError(parent->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Extension numbers cannot be greater than $0.",
+ FieldDescriptor::kMaxNumber));
+ }
+
+ if (result->start >= result->end) {
+ AddError(parent->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER,
+ "Extension range end number must be greater than start number.");
+ }
+}
+
+void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto,
+ const Descriptor* parent,
+ EnumDescriptor* result) {
+ const string& scope = (parent == NULL) ?
+ file_->package() : parent->full_name();
+ string* full_name = tables_->AllocateString(scope);
+ if (!full_name->empty()) full_name->append(1, '.');
+ full_name->append(proto.name());
+
+ ValidateSymbolName(proto.name(), *full_name, proto);
+
+ result->name_ = tables_->AllocateString(proto.name());
+ result->full_name_ = full_name;
+ result->file_ = file_;
+ result->containing_type_ = parent;
+ result->is_placeholder_ = false;
+ result->is_unqualified_placeholder_ = false;
+
+ if (proto.value_size() == 0) {
+ // We cannot allow enums with no values because this would mean there
+ // would be no valid default value for fields of this type.
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::NAME,
+ "Enums must contain at least one value.");
+ }
+
+ BUILD_ARRAY(proto, result, value, BuildEnumValue, result);
+
+ // Copy options.
+ if (!proto.has_options()) {
+ result->options_ = NULL; // Will set to default_instance later.
+ } else {
+ AllocateOptions(proto.options(), result);
+ }
+
+ AddSymbol(result->full_name(), parent, result->name(),
+ proto, Symbol(result));
+}
+
+void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto,
+ const EnumDescriptor* parent,
+ EnumValueDescriptor* result) {
+ result->name_ = tables_->AllocateString(proto.name());
+ result->number_ = proto.number();
+ result->type_ = parent;
+
+ // Note: full_name for enum values is a sibling to the parent's name, not a
+ // child of it.
+ string* full_name = tables_->AllocateString(*parent->full_name_);
+ full_name->resize(full_name->size() - parent->name_->size());
+ full_name->append(*result->name_);
+ result->full_name_ = full_name;
+
+ ValidateSymbolName(proto.name(), *full_name, proto);
+
+ // Copy options.
+ if (!proto.has_options()) {
+ result->options_ = NULL; // Will set to default_instance later.
+ } else {
+ AllocateOptions(proto.options(), result);
+ }
+
+ // Again, enum values are weird because we makes them appear as siblings
+ // of the enum type instead of children of it. So, we use
+ // parent->containing_type() as the value's parent.
+ bool added_to_outer_scope =
+ AddSymbol(result->full_name(), parent->containing_type(), result->name(),
+ proto, Symbol(result));
+
+ // However, we also want to be able to search for values within a single
+ // enum type, so we add it as a child of the enum type itself, too.
+ // Note: This could fail, but if it does, the error has already been
+ // reported by the above AddSymbol() call, so we ignore the return code.
+ bool added_to_inner_scope =
+ file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result));
+
+ if (added_to_inner_scope && !added_to_outer_scope) {
+ // This value did not conflict with any values defined in the same enum,
+ // but it did conflict with some other symbol defined in the enum type's
+ // scope. Let's print an additional error to explain this.
+ string outer_scope;
+ if (parent->containing_type() == NULL) {
+ outer_scope = file_->package();
+ } else {
+ outer_scope = parent->containing_type()->full_name();
+ }
+
+ if (outer_scope.empty()) {
+ outer_scope = "the global scope";
+ } else {
+ outer_scope = "\"" + outer_scope + "\"";
+ }
+
+ AddError(result->full_name(), proto,
+ DescriptorPool::ErrorCollector::NAME,
+ "Note that enum values use C++ scoping rules, meaning that "
+ "enum values are siblings of their type, not children of it. "
+ "Therefore, \"" + result->name() + "\" must be unique within "
+ + outer_scope + ", not just within \"" + parent->name() + "\".");
+ }
+
+ // An enum is allowed to define two numbers that refer to the same value.
+ // FindValueByNumber() should return the first such value, so we simply
+ // ignore AddEnumValueByNumber()'s return code.
+ file_tables_->AddEnumValueByNumber(result);
+}
+
+void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto,
+ const void* dummy,
+ ServiceDescriptor* result) {
+ string* full_name = tables_->AllocateString(file_->package());
+ if (!full_name->empty()) full_name->append(1, '.');
+ full_name->append(proto.name());
+
+ ValidateSymbolName(proto.name(), *full_name, proto);
+
+ result->name_ = tables_->AllocateString(proto.name());
+ result->full_name_ = full_name;
+ result->file_ = file_;
+
+ BUILD_ARRAY(proto, result, method, BuildMethod, result);
+
+ // Copy options.
+ if (!proto.has_options()) {
+ result->options_ = NULL; // Will set to default_instance later.
+ } else {
+ AllocateOptions(proto.options(), result);
+ }
+
+ AddSymbol(result->full_name(), NULL, result->name(),
+ proto, Symbol(result));
+}
+
+void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto,
+ const ServiceDescriptor* parent,
+ MethodDescriptor* result) {
+ result->name_ = tables_->AllocateString(proto.name());
+ result->service_ = parent;
+
+ string* full_name = tables_->AllocateString(parent->full_name());
+ full_name->append(1, '.');
+ full_name->append(*result->name_);
+ result->full_name_ = full_name;
+
+ ValidateSymbolName(proto.name(), *full_name, proto);
+
+ // These will be filled in when cross-linking.
+ result->input_type_ = NULL;
+ result->output_type_ = NULL;
+
+ // Copy options.
+ if (!proto.has_options()) {
+ result->options_ = NULL; // Will set to default_instance later.
+ } else {
+ AllocateOptions(proto.options(), result);
+ }
+
+ AddSymbol(result->full_name(), parent, result->name(),
+ proto, Symbol(result));
+}
+
+#undef BUILD_ARRAY
+
+// -------------------------------------------------------------------
+
+void DescriptorBuilder::CrossLinkFile(
+ FileDescriptor* file, const FileDescriptorProto& proto) {
+ if (file->options_ == NULL) {
+ file->options_ = &FileOptions::default_instance();
+ }
+
+ for (int i = 0; i < file->message_type_count(); i++) {
+ CrossLinkMessage(&file->message_types_[i], proto.message_type(i));
+ }
+
+ for (int i = 0; i < file->extension_count(); i++) {
+ CrossLinkField(&file->extensions_[i], proto.extension(i));
+ }
+
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i));
+ }
+
+ for (int i = 0; i < file->service_count(); i++) {
+ CrossLinkService(&file->services_[i], proto.service(i));
+ }
+}
+
+void DescriptorBuilder::CrossLinkMessage(
+ Descriptor* message, const DescriptorProto& proto) {
+ if (message->options_ == NULL) {
+ message->options_ = &MessageOptions::default_instance();
+ }
+
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i));
+ }
+
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i));
+ }
+
+ for (int i = 0; i < message->field_count(); i++) {
+ CrossLinkField(&message->fields_[i], proto.field(i));
+ }
+
+ for (int i = 0; i < message->extension_count(); i++) {
+ CrossLinkField(&message->extensions_[i], proto.extension(i));
+ }
+}
+
+void DescriptorBuilder::CrossLinkField(
+ FieldDescriptor* field, const FieldDescriptorProto& proto) {
+ if (field->options_ == NULL) {
+ field->options_ = &FieldOptions::default_instance();
+ }
+
+ if (proto.has_extendee()) {
+ Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(),
+ PLACEHOLDER_EXTENDABLE_MESSAGE);
+ if (extendee.IsNull()) {
+ AddNotDefinedError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ proto.extendee());
+ return;
+ } else if (extendee.type != Symbol::MESSAGE) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ "\"" + proto.extendee() + "\" is not a message type.");
+ return;
+ }
+ field->containing_type_ = extendee.descriptor;
+
+ if (!field->containing_type()->IsExtensionNumber(field->number())) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("\"$0\" does not declare $1 as an "
+ "extension number.",
+ field->containing_type()->full_name(),
+ field->number()));
+ }
+ }
+
+ if (proto.has_type_name()) {
+ // Assume we are expecting a message type unless the proto contains some
+ // evidence that it expects an enum type. This only makes a difference if
+ // we end up creating a placeholder.
+ bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) ||
+ proto.has_default_value();
+
+ Symbol type =
+ LookupSymbol(proto.type_name(), field->full_name(),
+ expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE,
+ LOOKUP_TYPES);
+
+ if (type.IsNull()) {
+ AddNotDefinedError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ proto.type_name());
+ return;
+ }
+
+ if (!proto.has_type()) {
+ // Choose field type based on symbol.
+ if (type.type == Symbol::MESSAGE) {
+ field->type_ = FieldDescriptor::TYPE_MESSAGE;
+ } else if (type.type == Symbol::ENUM) {
+ field->type_ = FieldDescriptor::TYPE_ENUM;
+ } else {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "\"" + proto.type_name() + "\" is not a type.");
+ return;
+ }
+ }
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (type.type != Symbol::MESSAGE) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "\"" + proto.type_name() + "\" is not a message type.");
+ return;
+ }
+ field->message_type_ = type.descriptor;
+
+ if (field->has_default_value()) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Messages can't have default values.");
+ }
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ if (type.type != Symbol::ENUM) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "\"" + proto.type_name() + "\" is not an enum type.");
+ return;
+ }
+ field->enum_type_ = type.enum_descriptor;
+
+ if (field->enum_type()->is_placeholder_) {
+ // We can't look up default values for placeholder types. We'll have
+ // to just drop them.
+ field->has_default_value_ = false;
+ }
+
+ if (field->has_default_value()) {
+ // We can't just use field->enum_type()->FindValueByName() here
+ // because that locks the pool's mutex, which we have already locked
+ // at this point.
+ Symbol default_value =
+ LookupSymbolNoPlaceholder(proto.default_value(),
+ field->enum_type()->full_name());
+
+ if (default_value.type == Symbol::ENUM_VALUE &&
+ default_value.enum_value_descriptor->type() == field->enum_type()) {
+ field->default_value_enum_ = default_value.enum_value_descriptor;
+ } else {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+ "Enum type \"" + field->enum_type()->full_name() +
+ "\" has no value named \"" + proto.default_value() + "\".");
+ }
+ } else if (field->enum_type()->value_count() > 0) {
+ // All enums must have at least one value, or we would have reported
+ // an error elsewhere. We use the first defined value as the default
+ // if a default is not explicitly defined.
+ field->default_value_enum_ = field->enum_type()->value(0);
+ }
+ } else {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Field with primitive type has type_name.");
+ }
+ } else {
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Field with message or enum type missing type_name.");
+ }
+ }
+
+ // Add the field to the fields-by-number table.
+ // Note: We have to do this *after* cross-linking because extensions do not
+ // know their containing type until now.
+ if (!file_tables_->AddFieldByNumber(field)) {
+ const FieldDescriptor* conflicting_field =
+ file_tables_->FindFieldByNumber(field->containing_type(),
+ field->number());
+ if (field->is_extension()) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Extension number $0 has already been used "
+ "in \"$1\" by extension \"$2\".",
+ field->number(),
+ field->containing_type()->full_name(),
+ conflicting_field->full_name()));
+ } else {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::NUMBER,
+ strings::Substitute("Field number $0 has already been used in "
+ "\"$1\" by field \"$2\".",
+ field->number(),
+ field->containing_type()->full_name(),
+ conflicting_field->name()));
+ }
+ }
+
+ if (field->is_extension()) {
+ // No need for error checking: if the extension number collided,
+ // we've already been informed of it by the if() above.
+ tables_->AddExtension(field);
+ }
+
+ // Add the field to the lowercase-name and camelcase-name tables.
+ file_tables_->AddFieldByStylizedNames(field);
+}
+
+void DescriptorBuilder::CrossLinkEnum(
+ EnumDescriptor* enum_type, const EnumDescriptorProto& proto) {
+ if (enum_type->options_ == NULL) {
+ enum_type->options_ = &EnumOptions::default_instance();
+ }
+
+ for (int i = 0; i < enum_type->value_count(); i++) {
+ CrossLinkEnumValue(&enum_type->values_[i], proto.value(i));
+ }
+}
+
+void DescriptorBuilder::CrossLinkEnumValue(
+ EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) {
+ if (enum_value->options_ == NULL) {
+ enum_value->options_ = &EnumValueOptions::default_instance();
+ }
+}
+
+void DescriptorBuilder::CrossLinkService(
+ ServiceDescriptor* service, const ServiceDescriptorProto& proto) {
+ if (service->options_ == NULL) {
+ service->options_ = &ServiceOptions::default_instance();
+ }
+
+ for (int i = 0; i < service->method_count(); i++) {
+ CrossLinkMethod(&service->methods_[i], proto.method(i));
+ }
+}
+
+void DescriptorBuilder::CrossLinkMethod(
+ MethodDescriptor* method, const MethodDescriptorProto& proto) {
+ if (method->options_ == NULL) {
+ method->options_ = &MethodOptions::default_instance();
+ }
+
+ Symbol input_type = LookupSymbol(proto.input_type(), method->full_name());
+ if (input_type.IsNull()) {
+ AddNotDefinedError(method->full_name(), proto,
+ DescriptorPool::ErrorCollector::INPUT_TYPE,
+ proto.input_type());
+ } else if (input_type.type != Symbol::MESSAGE) {
+ AddError(method->full_name(), proto,
+ DescriptorPool::ErrorCollector::INPUT_TYPE,
+ "\"" + proto.input_type() + "\" is not a message type.");
+ } else {
+ method->input_type_ = input_type.descriptor;
+ }
+
+ Symbol output_type = LookupSymbol(proto.output_type(), method->full_name());
+ if (output_type.IsNull()) {
+ AddNotDefinedError(method->full_name(), proto,
+ DescriptorPool::ErrorCollector::OUTPUT_TYPE,
+ proto.output_type());
+ } else if (output_type.type != Symbol::MESSAGE) {
+ AddError(method->full_name(), proto,
+ DescriptorPool::ErrorCollector::OUTPUT_TYPE,
+ "\"" + proto.output_type() + "\" is not a message type.");
+ } else {
+ method->output_type_ = output_type.descriptor;
+ }
+}
+
+// -------------------------------------------------------------------
+
+#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \
+ for (int i = 0; i < descriptor->array_name##_count(); ++i) { \
+ Validate##type##Options(descriptor->array_name##s_ + i, \
+ proto.array_name(i)); \
+ }
+
+// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to
+// avoid problems that exist at init time.
+static bool IsLite(const FileDescriptor* file) {
+ // TODO(kenton): I don't even remember how many of these conditions are
+ // actually possible. I'm just being super-safe.
+ return file != NULL &&
+ &file->options() != NULL &&
+ &file->options() != &FileOptions::default_instance() &&
+ file->options().optimize_for() == FileOptions::LITE_RUNTIME;
+}
+
+void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file,
+ const FileDescriptorProto& proto) {
+ VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message);
+ VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum);
+ VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service);
+ VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field);
+
+ // Lite files can only be imported by other Lite files.
+ if (!IsLite(file)) {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ if (IsLite(file->dependency(i))) {
+ AddError(
+ file->name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ "Files that do not use optimize_for = LITE_RUNTIME cannot import "
+ "files which do use this option. This file is not lite, but it "
+ "imports \"" + file->dependency(i)->name() + "\" which is.");
+ break;
+ }
+ }
+ }
+}
+
+void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
+ const DescriptorProto& proto) {
+ VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field);
+ VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message);
+ VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum);
+ VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field);
+}
+
+void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
+ const FieldDescriptorProto& proto) {
+ if (field->options().has_experimental_map_key()) {
+ ValidateMapKey(field, proto);
+ }
+
+ // Only repeated primitive fields may be packed.
+ if (field->options().packed() && !field->is_packable()) {
+ AddError(
+ field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "[packed = true] can only be specified for repeated primitive fields.");
+ }
+
+ // Note: Default instance may not yet be initialized here, so we have to
+ // avoid reading from it.
+ if (field->containing_type_ != NULL &&
+ &field->containing_type()->options() !=
+ &MessageOptions::default_instance() &&
+ field->containing_type()->options().message_set_wire_format()) {
+ if (field->is_extension()) {
+ if (!field->is_optional() ||
+ field->type() != FieldDescriptor::TYPE_MESSAGE) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::TYPE,
+ "Extensions of MessageSets must be optional messages.");
+ }
+ } else {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::NAME,
+ "MessageSets cannot have fields, only extensions.");
+ }
+ }
+
+ // Lite extensions can only be of Lite types.
+ if (IsLite(field->file()) &&
+ field->containing_type_ != NULL &&
+ !IsLite(field->containing_type()->file())) {
+ AddError(field->full_name(), proto,
+ DescriptorPool::ErrorCollector::EXTENDEE,
+ "Extensions to non-lite types can only be declared in non-lite "
+ "files. Note that you cannot extend a non-lite type to contain "
+ "a lite type, but the reverse is allowed.");
+ }
+}
+
+void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
+ const EnumDescriptorProto& proto) {
+ VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue);
+}
+
+void DescriptorBuilder::ValidateEnumValueOptions(
+ EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) {
+ // Nothing to do so far.
+}
+void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service,
+ const ServiceDescriptorProto& proto) {
+ if (IsLite(service->file()) &&
+ (service->file()->options().cc_generic_services() ||
+ service->file()->options().java_generic_services())) {
+ AddError(service->full_name(), proto,
+ DescriptorPool::ErrorCollector::NAME,
+ "Files with optimize_for = LITE_RUNTIME cannot define services "
+ "unless you set both options cc_generic_services and "
+ "java_generic_sevices to false.");
+ }
+
+ VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method);
+}
+
+void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* method,
+ const MethodDescriptorProto& proto) {
+ // Nothing to do so far.
+}
+
+void DescriptorBuilder::ValidateMapKey(FieldDescriptor* field,
+ const FieldDescriptorProto& proto) {
+ if (!field->is_repeated()) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "map type is only allowed for repeated fields.");
+ return;
+ }
+
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "map type is only allowed for fields with a message type.");
+ return;
+ }
+
+ const Descriptor* item_type = field->message_type();
+ if (item_type == NULL) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Could not find field type.");
+ return;
+ }
+
+ // Find the field in item_type named by "experimental_map_key"
+ const string& key_name = field->options().experimental_map_key();
+ const Symbol key_symbol = LookupSymbol(
+ key_name,
+ // We append ".key_name" to the containing type's name since
+ // LookupSymbol() searches for peers of the supplied name, not
+ // children of the supplied name.
+ item_type->full_name() + "." + key_name);
+
+ if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Could not find field named \"" + key_name + "\" in type \"" +
+ item_type->full_name() + "\".");
+ return;
+ }
+ const FieldDescriptor* key_field = key_symbol.field_descriptor;
+
+ if (key_field->is_repeated()) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "map_key must not name a repeated field.");
+ return;
+ }
+
+ if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "map key must name a scalar or string field.");
+ return;
+ }
+
+ field->experimental_map_key_ = key_field;
+}
+
+#undef VALIDATE_OPTIONS_FROM_ARRAY
+
+// -------------------------------------------------------------------
+
+DescriptorBuilder::OptionInterpreter::OptionInterpreter(
+ DescriptorBuilder* builder) : builder_(builder) {
+ GOOGLE_CHECK(builder_);
+}
+
+DescriptorBuilder::OptionInterpreter::~OptionInterpreter() {
+}
+
+bool DescriptorBuilder::OptionInterpreter::InterpretOptions(
+ OptionsToInterpret* options_to_interpret) {
+ // Note that these may be in different pools, so we can't use the same
+ // descriptor and reflection objects on both.
+ Message* options = options_to_interpret->options;
+ const Message* original_options = options_to_interpret->original_options;
+
+ bool failed = false;
+ options_to_interpret_ = options_to_interpret;
+
+ // Find the uninterpreted_option field in the mutable copy of the options
+ // and clear them, since we're about to interpret them.
+ const FieldDescriptor* uninterpreted_options_field =
+ options->GetDescriptor()->FindFieldByName("uninterpreted_option");
+ GOOGLE_CHECK(uninterpreted_options_field != NULL)
+ << "No field named \"uninterpreted_option\" in the Options proto.";
+ options->GetReflection()->ClearField(options, uninterpreted_options_field);
+
+ // Find the uninterpreted_option field in the original options.
+ const FieldDescriptor* original_uninterpreted_options_field =
+ original_options->GetDescriptor()->
+ FindFieldByName("uninterpreted_option");
+ GOOGLE_CHECK(original_uninterpreted_options_field != NULL)
+ << "No field named \"uninterpreted_option\" in the Options proto.";
+
+ const int num_uninterpreted_options = original_options->GetReflection()->
+ FieldSize(*original_options, original_uninterpreted_options_field);
+ for (int i = 0; i < num_uninterpreted_options; ++i) {
+ uninterpreted_option_ = down_cast<const UninterpretedOption*>(
+ &original_options->GetReflection()->GetRepeatedMessage(
+ *original_options, original_uninterpreted_options_field, i));
+ if (!InterpretSingleOption(options)) {
+ // Error already added by InterpretSingleOption().
+ failed = true;
+ break;
+ }
+ }
+ // Reset these, so we don't have any dangling pointers.
+ uninterpreted_option_ = NULL;
+ options_to_interpret_ = NULL;
+
+ if (!failed) {
+ // InterpretSingleOption() added the interpreted options in the
+ // UnknownFieldSet, in case the option isn't yet known to us. Now we
+ // serialize the options message and deserialize it back. That way, any
+ // option fields that we do happen to know about will get moved from the
+ // UnknownFieldSet into the real fields, and thus be available right away.
+ // If they are not known, that's OK too. They will get reparsed into the
+ // UnknownFieldSet and wait there until the message is parsed by something
+ // that does know about the options.
+ string buf;
+ options->AppendToString(&buf);
+ GOOGLE_CHECK(options->ParseFromString(buf))
+ << "Protocol message serialized itself in invalid fashion.";
+ }
+
+ return !failed;
+}
+
+bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
+ Message* options) {
+ // First do some basic validation.
+ if (uninterpreted_option_->name_size() == 0) {
+ // This should never happen unless the parser has gone seriously awry or
+ // someone has manually created the uninterpreted option badly.
+ return AddNameError("Option must have a name.");
+ }
+ if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") {
+ return AddNameError("Option must not use reserved name "
+ "\"uninterpreted_option\".");
+ }
+
+ const Descriptor* options_descriptor = NULL;
+ // Get the options message's descriptor from the builder's pool, so that we
+ // get the version that knows about any extension options declared in the
+ // file we're currently building. The descriptor should be there as long as
+ // the file we're building imported "google/protobuf/descriptors.proto".
+
+ // Note that we use DescriptorBuilder::FindSymbol(), not
+ // DescriptorPool::FindMessageTypeByName() because we're already holding the
+ // pool's mutex, and the latter method locks it again.
+ Symbol symbol = builder_->FindSymbolNotEnforcingDeps(
+ options->GetDescriptor()->full_name());
+ if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) {
+ options_descriptor = symbol.descriptor;
+ } else {
+ // The options message's descriptor was not in the builder's pool, so use
+ // the standard version from the generated pool. We're not holding the
+ // generated pool's mutex, so we can search it the straightforward way.
+ options_descriptor = options->GetDescriptor();
+ }
+ GOOGLE_CHECK(options_descriptor);
+
+ // We iterate over the name parts to drill into the submessages until we find
+ // the leaf field for the option. As we drill down we remember the current
+ // submessage's descriptor in |descriptor| and the next field in that
+ // submessage in |field|. We also track the fields we're drilling down
+ // through in |intermediate_fields|. As we go, we reconstruct the full option
+ // name in |debug_msg_name|, for use in error messages.
+ const Descriptor* descriptor = options_descriptor;
+ const FieldDescriptor* field = NULL;
+ vector<const FieldDescriptor*> intermediate_fields;
+ string debug_msg_name = "";
+
+ for (int i = 0; i < uninterpreted_option_->name_size(); ++i) {
+ const string& name_part = uninterpreted_option_->name(i).name_part();
+ if (debug_msg_name.size() > 0) {
+ debug_msg_name += ".";
+ }
+ if (uninterpreted_option_->name(i).is_extension()) {
+ debug_msg_name += "(" + name_part + ")";
+ // Search for the extension's descriptor as an extension in the builder's
+ // pool. Note that we use DescriptorBuilder::LookupSymbol(), not
+ // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows
+ // relative lookups, and 2) because we're already holding the pool's
+ // mutex, and the latter method locks it again.
+ Symbol symbol = builder_->LookupSymbol(name_part,
+ options_to_interpret_->name_scope);
+ if (!symbol.IsNull() && symbol.type == Symbol::FIELD) {
+ field = symbol.field_descriptor;
+ }
+ // If we don't find the field then the field's descriptor was not in the
+ // builder's pool, but there's no point in looking in the generated
+ // pool. We require that you import the file that defines any extensions
+ // you use, so they must be present in the builder's pool.
+ } else {
+ debug_msg_name += name_part;
+ // Search for the field's descriptor as a regular field.
+ field = descriptor->FindFieldByName(name_part);
+ }
+
+ if (field == NULL) {
+ if (get_allow_unknown(builder_->pool_)) {
+ // We can't find the option, but AllowUnknownDependencies() is enabled,
+ // so we will just leave it as uninterpreted.
+ AddWithoutInterpreting(*uninterpreted_option_, options);
+ return true;
+ } else {
+ return AddNameError("Option \"" + debug_msg_name + "\" unknown.");
+ }
+ } else if (field->containing_type() != descriptor) {
+ if (get_is_placeholder(field->containing_type())) {
+ // The field is an extension of a placeholder type, so we can't
+ // reliably verify whether it is a valid extension to use here (e.g.
+ // we don't know if it is an extension of the correct *Options message,
+ // or if it has a valid field number, etc.). Just leave it as
+ // uninterpreted instead.
+ AddWithoutInterpreting(*uninterpreted_option_, options);
+ return true;
+ } else {
+ // This can only happen if, due to some insane misconfiguration of the
+ // pools, we find the options message in one pool but the field in
+ // another. This would probably imply a hefty bug somewhere.
+ return AddNameError("Option field \"" + debug_msg_name +
+ "\" is not a field or extension of message \"" +
+ descriptor->name() + "\".");
+ }
+ } else if (field->is_repeated()) {
+ return AddNameError("Option field \"" + debug_msg_name +
+ "\" is repeated. Repeated options are not "
+ "supported.");
+ } else if (i < uninterpreted_option_->name_size() - 1) {
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ return AddNameError("Option \"" + debug_msg_name +
+ "\" is an atomic type, not a message.");
+ } else {
+ // Drill down into the submessage.
+ intermediate_fields.push_back(field);
+ descriptor = field->message_type();
+ }
+ }
+ }
+
+ // We've found the leaf field. Now we use UnknownFieldSets to set its value
+ // on the options message. We do so because the message may not yet know
+ // about its extension fields, so we may not be able to set the fields
+ // directly. But the UnknownFieldSets will serialize to the same wire-format
+ // message, so reading that message back in once the extension fields are
+ // known will populate them correctly.
+
+ // First see if the option is already set.
+ if (!ExamineIfOptionIsSet(
+ intermediate_fields.begin(),
+ intermediate_fields.end(),
+ field, debug_msg_name,
+ options->GetReflection()->GetUnknownFields(*options))) {
+ return false; // ExamineIfOptionIsSet() already added the error.
+ }
+
+
+ // First set the value on the UnknownFieldSet corresponding to the
+ // innermost message.
+ scoped_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet());
+ if (!SetOptionValue(field, unknown_fields.get())) {
+ return false; // SetOptionValue() already added the error.
+ }
+
+ // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all
+ // the intermediate messages.
+ for (vector<const FieldDescriptor*>::reverse_iterator iter =
+ intermediate_fields.rbegin();
+ iter != intermediate_fields.rend(); ++iter) {
+ scoped_ptr<UnknownFieldSet> parent_unknown_fields(new UnknownFieldSet());
+ switch ((*iter)->type()) {
+ case FieldDescriptor::TYPE_MESSAGE: {
+ io::StringOutputStream outstr(
+ parent_unknown_fields->AddLengthDelimited((*iter)->number()));
+ io::CodedOutputStream out(&outstr);
+ internal::WireFormatLite::SerializeUnknownFields(*unknown_fields, &out);
+ GOOGLE_CHECK(!out.HadError())
+ << "Unexpected failure while serializing option submessage "
+ << debug_msg_name << "\".";
+ break;
+ }
+
+ case FieldDescriptor::TYPE_GROUP: {
+ parent_unknown_fields->AddGroup((*iter)->number())
+ ->MergeFrom(*unknown_fields);
+ break;
+ }
+
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: "
+ << (*iter)->type();
+ return false;
+ }
+ unknown_fields.reset(parent_unknown_fields.release());
+ }
+
+ // Now merge the UnknownFieldSet corresponding to the top-level message into
+ // the options message.
+ options->GetReflection()->MutableUnknownFields(options)->MergeFrom(
+ *unknown_fields);
+
+ return true;
+}
+
+void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting(
+ const UninterpretedOption& uninterpreted_option, Message* options) {
+ const FieldDescriptor* field =
+ options->GetDescriptor()->FindFieldByName("uninterpreted_option");
+ GOOGLE_CHECK(field != NULL);
+
+ options->GetReflection()->AddMessage(options, field)
+ ->CopyFrom(uninterpreted_option);
+}
+
+bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet(
+ vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter,
+ vector<const FieldDescriptor*>::const_iterator intermediate_fields_end,
+ const FieldDescriptor* innermost_field, const string& debug_msg_name,
+ const UnknownFieldSet& unknown_fields) {
+ // We do linear searches of the UnknownFieldSet and its sub-groups. This
+ // should be fine since it's unlikely that any one options structure will
+ // contain more than a handful of options.
+
+ if (intermediate_fields_iter == intermediate_fields_end) {
+ // We're at the innermost submessage.
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ if (unknown_fields.field(i).number() == innermost_field->number()) {
+ return AddNameError("Option \"" + debug_msg_name +
+ "\" was already set.");
+ }
+ }
+ return true;
+ }
+
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ if (unknown_fields.field(i).number() ==
+ (*intermediate_fields_iter)->number()) {
+ const UnknownField* unknown_field = &unknown_fields.field(i);
+ FieldDescriptor::Type type = (*intermediate_fields_iter)->type();
+ // Recurse into the next submessage.
+ switch (type) {
+ case FieldDescriptor::TYPE_MESSAGE:
+ if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) {
+ UnknownFieldSet intermediate_unknown_fields;
+ if (intermediate_unknown_fields.ParseFromString(
+ unknown_field->length_delimited()) &&
+ !ExamineIfOptionIsSet(intermediate_fields_iter + 1,
+ intermediate_fields_end,
+ innermost_field, debug_msg_name,
+ intermediate_unknown_fields)) {
+ return false; // Error already added.
+ }
+ }
+ break;
+
+ case FieldDescriptor::TYPE_GROUP:
+ if (unknown_field->type() == UnknownField::TYPE_GROUP) {
+ if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1,
+ intermediate_fields_end,
+ innermost_field, debug_msg_name,
+ unknown_field->group())) {
+ return false; // Error already added.
+ }
+ }
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
+ const FieldDescriptor* option_field,
+ UnknownFieldSet* unknown_fields) {
+ // We switch on the CppType to validate.
+ switch (option_field->cpp_type()) {
+
+ case FieldDescriptor::CPPTYPE_INT32:
+ if (uninterpreted_option_->has_positive_int_value()) {
+ if (uninterpreted_option_->positive_int_value() >
+ static_cast<uint64>(kint32max)) {
+ return AddValueError("Value out of range for int32 option \"" +
+ option_field->full_name() + "\".");
+ } else {
+ SetInt32(option_field->number(),
+ uninterpreted_option_->positive_int_value(),
+ option_field->type(), unknown_fields);
+ }
+ } else if (uninterpreted_option_->has_negative_int_value()) {
+ if (uninterpreted_option_->negative_int_value() <
+ static_cast<int64>(kint32min)) {
+ return AddValueError("Value out of range for int32 option \"" +
+ option_field->full_name() + "\".");
+ } else {
+ SetInt32(option_field->number(),
+ uninterpreted_option_->negative_int_value(),
+ option_field->type(), unknown_fields);
+ }
+ } else {
+ return AddValueError("Value must be integer for int32 option \"" +
+ option_field->full_name() + "\".");
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_INT64:
+ if (uninterpreted_option_->has_positive_int_value()) {
+ if (uninterpreted_option_->positive_int_value() >
+ static_cast<uint64>(kint64max)) {
+ return AddValueError("Value out of range for int64 option \"" +
+ option_field->full_name() + "\".");
+ } else {
+ SetInt64(option_field->number(),
+ uninterpreted_option_->positive_int_value(),
+ option_field->type(), unknown_fields);
+ }
+ } else if (uninterpreted_option_->has_negative_int_value()) {
+ SetInt64(option_field->number(),
+ uninterpreted_option_->negative_int_value(),
+ option_field->type(), unknown_fields);
+ } else {
+ return AddValueError("Value must be integer for int64 option \"" +
+ option_field->full_name() + "\".");
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_UINT32:
+ if (uninterpreted_option_->has_positive_int_value()) {
+ if (uninterpreted_option_->positive_int_value() > kuint32max) {
+ return AddValueError("Value out of range for uint32 option \"" +
+ option_field->name() + "\".");
+ } else {
+ SetUInt32(option_field->number(),
+ uninterpreted_option_->positive_int_value(),
+ option_field->type(), unknown_fields);
+ }
+ } else {
+ return AddValueError("Value must be non-negative integer for uint32 "
+ "option \"" + option_field->full_name() + "\".");
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_UINT64:
+ if (uninterpreted_option_->has_positive_int_value()) {
+ SetUInt64(option_field->number(),
+ uninterpreted_option_->positive_int_value(),
+ option_field->type(), unknown_fields);
+ } else {
+ return AddValueError("Value must be non-negative integer for uint64 "
+ "option \"" + option_field->full_name() + "\".");
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ float value;
+ if (uninterpreted_option_->has_double_value()) {
+ value = uninterpreted_option_->double_value();
+ } else if (uninterpreted_option_->has_positive_int_value()) {
+ value = uninterpreted_option_->positive_int_value();
+ } else if (uninterpreted_option_->has_negative_int_value()) {
+ value = uninterpreted_option_->negative_int_value();
+ } else {
+ return AddValueError("Value must be number for float option \"" +
+ option_field->full_name() + "\".");
+ }
+ unknown_fields->AddFixed32(option_field->number(),
+ google::protobuf::internal::WireFormatLite::EncodeFloat(value));
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value;
+ if (uninterpreted_option_->has_double_value()) {
+ value = uninterpreted_option_->double_value();
+ } else if (uninterpreted_option_->has_positive_int_value()) {
+ value = uninterpreted_option_->positive_int_value();
+ } else if (uninterpreted_option_->has_negative_int_value()) {
+ value = uninterpreted_option_->negative_int_value();
+ } else {
+ return AddValueError("Value must be number for double option \"" +
+ option_field->full_name() + "\".");
+ }
+ unknown_fields->AddFixed64(option_field->number(),
+ google::protobuf::internal::WireFormatLite::EncodeDouble(value));
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_BOOL:
+ uint64 value;
+ if (!uninterpreted_option_->has_identifier_value()) {
+ return AddValueError("Value must be identifier for boolean option "
+ "\"" + option_field->full_name() + "\".");
+ }
+ if (uninterpreted_option_->identifier_value() == "true") {
+ value = 1;
+ } else if (uninterpreted_option_->identifier_value() == "false") {
+ value = 0;
+ } else {
+ return AddValueError("Value must be \"true\" or \"false\" for boolean "
+ "option \"" + option_field->full_name() + "\".");
+ }
+ unknown_fields->AddVarint(option_field->number(), value);
+ break;
+
+ case FieldDescriptor::CPPTYPE_ENUM: {
+ if (!uninterpreted_option_->has_identifier_value()) {
+ return AddValueError("Value must be identifier for enum-valued option "
+ "\"" + option_field->full_name() + "\".");
+ }
+ const EnumDescriptor* enum_type = option_field->enum_type();
+ const string& value_name = uninterpreted_option_->identifier_value();
+ const EnumValueDescriptor* enum_value = NULL;
+
+ if (enum_type->file()->pool() != DescriptorPool::generated_pool()) {
+ // Note that the enum value's fully-qualified name is a sibling of the
+ // enum's name, not a child of it.
+ string fully_qualified_name = enum_type->full_name();
+ fully_qualified_name.resize(fully_qualified_name.size() -
+ enum_type->name().size());
+ fully_qualified_name += value_name;
+
+ // Search for the enum value's descriptor in the builder's pool. Note
+ // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
+ // DescriptorPool::FindEnumValueByName() because we're already holding
+ // the pool's mutex, and the latter method locks it again.
+ Symbol symbol =
+ builder_->FindSymbolNotEnforcingDeps(fully_qualified_name);
+ if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) {
+ if (symbol.enum_value_descriptor->type() != enum_type) {
+ return AddValueError("Enum type \"" + enum_type->full_name() +
+ "\" has no value named \"" + value_name + "\" for option \"" +
+ option_field->full_name() +
+ "\". This appears to be a value from a sibling type.");
+ } else {
+ enum_value = symbol.enum_value_descriptor;
+ }
+ }
+ } else {
+ // The enum type is in the generated pool, so we can search for the
+ // value there.
+ enum_value = enum_type->FindValueByName(value_name);
+ }
+
+ if (enum_value == NULL) {
+ return AddValueError("Enum type \"" +
+ option_field->enum_type()->full_name() +
+ "\" has no value named \"" + value_name + "\" for "
+ "option \"" + option_field->full_name() + "\".");
+ } else {
+ // Sign-extension is not a problem, since we cast directly from int32 to
+ // uint64, without first going through uint32.
+ unknown_fields->AddVarint(option_field->number(),
+ static_cast<uint64>(static_cast<int64>(enum_value->number())));
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ if (!uninterpreted_option_->has_string_value()) {
+ return AddValueError("Value must be quoted string for string option "
+ "\"" + option_field->full_name() + "\".");
+ }
+ // The string has already been unquoted and unescaped by the parser.
+ unknown_fields->AddLengthDelimited(option_field->number(),
+ uninterpreted_option_->string_value());
+ break;
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ if (!SetAggregateOption(option_field, unknown_fields)) {
+ return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
+class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
+ : public TextFormat::Finder {
+ public:
+ DescriptorBuilder* builder_;
+
+ virtual const FieldDescriptor* FindExtension(
+ Message* message, const string& name) const {
+ assert_mutex_held(builder_->pool_);
+ Symbol result = builder_->LookupSymbolNoPlaceholder(
+ name, message->GetDescriptor()->full_name());
+ if (result.type == Symbol::FIELD &&
+ result.field_descriptor->is_extension()) {
+ return result.field_descriptor;
+ } else {
+ return NULL;
+ }
+ }
+};
+
+// A custom error collector to record any text-format parsing errors
+namespace {
+class AggregateErrorCollector : public io::ErrorCollector {
+ public:
+ string error_;
+
+ virtual void AddError(int line, int column, const string& message) {
+ if (!error_.empty()) {
+ error_ += "; ";
+ }
+ error_ += message;
+ }
+
+ virtual void AddWarning(int line, int column, const string& message) {
+ // Ignore warnings
+ }
+};
+}
+
+// We construct a dynamic message of the type corresponding to
+// option_field, parse the supplied text-format string into this
+// message, and serialize the resulting message to produce the value.
+bool DescriptorBuilder::OptionInterpreter::SetAggregateOption(
+ const FieldDescriptor* option_field,
+ UnknownFieldSet* unknown_fields) {
+ if (!uninterpreted_option_->has_aggregate_value()) {
+ return AddValueError("Option \"" + option_field->full_name() +
+ "\" is a message. To set the entire message, use "
+ "syntax like \"" + option_field->name() +
+ " = { <proto text format> }\". "
+ "To set fields within it, use "
+ "syntax like \"" + option_field->name() +
+ ".foo = value\".");
+ }
+
+ const Descriptor* type = option_field->message_type();
+ scoped_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New());
+ GOOGLE_CHECK(dynamic.get() != NULL)
+ << "Could not create an instance of " << option_field->DebugString();
+
+ AggregateErrorCollector collector;
+ AggregateOptionFinder finder;
+ finder.builder_ = builder_;
+ TextFormat::Parser parser;
+ parser.RecordErrorsTo(&collector);
+ parser.SetFinder(&finder);
+ if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(),
+ dynamic.get())) {
+ AddValueError("Error while parsing option value for \"" +
+ option_field->name() + "\": " + collector.error_);
+ return false;
+ } else {
+ string serial;
+ dynamic->SerializeToString(&serial); // Never fails
+ unknown_fields->AddLengthDelimited(option_field->number(), serial);
+ return true;
+ }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value,
+ FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32:
+ unknown_fields->AddVarint(number,
+ static_cast<uint64>(static_cast<int64>(value)));
+ break;
+
+ case FieldDescriptor::TYPE_SFIXED32:
+ unknown_fields->AddFixed32(number, static_cast<uint32>(value));
+ break;
+
+ case FieldDescriptor::TYPE_SINT32:
+ unknown_fields->AddVarint(number,
+ google::protobuf::internal::WireFormatLite::ZigZagEncode32(value));
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type;
+ break;
+ }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value,
+ FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT64:
+ unknown_fields->AddVarint(number, static_cast<uint64>(value));
+ break;
+
+ case FieldDescriptor::TYPE_SFIXED64:
+ unknown_fields->AddFixed64(number, static_cast<uint64>(value));
+ break;
+
+ case FieldDescriptor::TYPE_SINT64:
+ unknown_fields->AddVarint(number,
+ google::protobuf::internal::WireFormatLite::ZigZagEncode64(value));
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type;
+ break;
+ }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetUInt32(int number, uint32 value,
+ FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
+ switch (type) {
+ case FieldDescriptor::TYPE_UINT32:
+ unknown_fields->AddVarint(number, static_cast<uint64>(value));
+ break;
+
+ case FieldDescriptor::TYPE_FIXED32:
+ unknown_fields->AddFixed32(number, static_cast<uint32>(value));
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type;
+ break;
+ }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value,
+ FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
+ switch (type) {
+ case FieldDescriptor::TYPE_UINT64:
+ unknown_fields->AddVarint(number, value);
+ break;
+
+ case FieldDescriptor::TYPE_FIXED64:
+ unknown_fields->AddFixed64(number, value);
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type;
+ break;
+ }
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor.h b/src/third_party/protobuf/src/google/protobuf/descriptor.h
new file mode 100644
index 0000000..7f87dd8
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor.h
@@ -0,0 +1,1367 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains classes which describe a type of protocol message.
+// You can use a message's descriptor to learn at runtime what fields
+// it contains and what the types of those fields are. The Message
+// interface also allows you to dynamically access and modify individual
+// fields by passing the FieldDescriptor of the field you are interested
+// in.
+//
+// Most users will not care about descriptors, because they will write
+// code specific to certain protocol types and will simply use the classes
+// generated by the protocol compiler directly. Advanced users who want
+// to operate on arbitrary types (not known at compile time) may want to
+// read descriptors in order to learn about the contents of a message.
+// A very small number of users will want to construct their own
+// Descriptors, either because they are implementing Message manually or
+// because they are writing something like the protocol compiler.
+//
+// For an example of how you might use descriptors, see the code example
+// at the top of message.h.
+
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__
+#define GOOGLE_PROTOBUF_DESCRIPTOR_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class Descriptor;
+class FieldDescriptor;
+class EnumDescriptor;
+class EnumValueDescriptor;
+class ServiceDescriptor;
+class MethodDescriptor;
+class FileDescriptor;
+class DescriptorDatabase;
+class DescriptorPool;
+
+// Defined in descriptor.proto
+class DescriptorProto;
+class FieldDescriptorProto;
+class EnumDescriptorProto;
+class EnumValueDescriptorProto;
+class ServiceDescriptorProto;
+class MethodDescriptorProto;
+class FileDescriptorProto;
+class MessageOptions;
+class FieldOptions;
+class EnumOptions;
+class EnumValueOptions;
+class ServiceOptions;
+class MethodOptions;
+class FileOptions;
+class UninterpretedOption;
+
+// Defined in message.h
+class Message;
+
+// Defined in descriptor.cc
+class DescriptorBuilder;
+class FileDescriptorTables;
+
+// Defined in unknown_field_set.h.
+class UnknownField;
+
+// Describes a type of protocol message, or a particular group within a
+// message. To obtain the Descriptor for a given message object, call
+// Message::GetDescriptor(). Generated message classes also have a
+// static method called descriptor() which returns the type's descriptor.
+// Use DescriptorPool to construct your own descriptors.
+class LIBPROTOBUF_EXPORT Descriptor {
+ public:
+ // The name of the message type, not including its scope.
+ const string& name() const;
+
+ // The fully-qualified name of the message type, scope delimited by
+ // periods. For example, message type "Foo" which is declared in package
+ // "bar" has full name "bar.Foo". If a type "Baz" is nested within
+ // Foo, Baz's full_name is "bar.Foo.Baz". To get only the part that
+ // comes after the last '.', use name().
+ const string& full_name() const;
+
+ // Index of this descriptor within the file or containing type's message
+ // type array.
+ int index() const;
+
+ // The .proto file in which this message type was defined. Never NULL.
+ const FileDescriptor* file() const;
+
+ // If this Descriptor describes a nested type, this returns the type
+ // in which it is nested. Otherwise, returns NULL.
+ const Descriptor* containing_type() const;
+
+ // Get options for this message type. These are specified in the .proto file
+ // by placing lines like "option foo = 1234;" in the message definition.
+ // Allowed options are defined by MessageOptions in
+ // google/protobuf/descriptor.proto, and any available extensions of that
+ // message.
+ const MessageOptions& options() const;
+
+ // Write the contents of this Descriptor into the given DescriptorProto.
+ // The target DescriptorProto must be clear before calling this; if it
+ // isn't, the result may be garbage.
+ void CopyTo(DescriptorProto* proto) const;
+
+ // Write the contents of this decriptor in a human-readable form. Output
+ // will be suitable for re-parsing.
+ string DebugString() const;
+
+ // Field stuff -----------------------------------------------------
+
+ // The number of fields in this message type.
+ int field_count() const;
+ // Gets a field by index, where 0 <= index < field_count().
+ // These are returned in the order they were defined in the .proto file.
+ const FieldDescriptor* field(int index) const;
+
+ // Looks up a field by declared tag number. Returns NULL if no such field
+ // exists.
+ const FieldDescriptor* FindFieldByNumber(int number) const;
+ // Looks up a field by name. Returns NULL if no such field exists.
+ const FieldDescriptor* FindFieldByName(const string& name) const;
+
+ // Looks up a field by lowercased name (as returned by lowercase_name()).
+ // This lookup may be ambiguous if multiple field names differ only by case,
+ // in which case the field returned is chosen arbitrarily from the matches.
+ const FieldDescriptor* FindFieldByLowercaseName(
+ const string& lowercase_name) const;
+
+ // Looks up a field by camel-case name (as returned by camelcase_name()).
+ // This lookup may be ambiguous if multiple field names differ in a way that
+ // leads them to have identical camel-case names, in which case the field
+ // returned is chosen arbitrarily from the matches.
+ const FieldDescriptor* FindFieldByCamelcaseName(
+ const string& camelcase_name) const;
+
+ // Nested type stuff -----------------------------------------------
+
+ // The number of nested types in this message type.
+ int nested_type_count() const;
+ // Gets a nested type by index, where 0 <= index < nested_type_count().
+ // These are returned in the order they were defined in the .proto file.
+ const Descriptor* nested_type(int index) const;
+
+ // Looks up a nested type by name. Returns NULL if no such nested type
+ // exists.
+ const Descriptor* FindNestedTypeByName(const string& name) const;
+
+ // Enum stuff ------------------------------------------------------
+
+ // The number of enum types in this message type.
+ int enum_type_count() const;
+ // Gets an enum type by index, where 0 <= index < enum_type_count().
+ // These are returned in the order they were defined in the .proto file.
+ const EnumDescriptor* enum_type(int index) const;
+
+ // Looks up an enum type by name. Returns NULL if no such enum type exists.
+ const EnumDescriptor* FindEnumTypeByName(const string& name) const;
+
+ // Looks up an enum value by name, among all enum types in this message.
+ // Returns NULL if no such value exists.
+ const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
+
+ // Extensions ------------------------------------------------------
+
+ // A range of field numbers which are designated for third-party
+ // extensions.
+ struct ExtensionRange {
+ int start; // inclusive
+ int end; // exclusive
+ };
+
+ // The number of extension ranges in this message type.
+ int extension_range_count() const;
+ // Gets an extension range by index, where 0 <= index <
+ // extension_range_count(). These are returned in the order they were defined
+ // in the .proto file.
+ const ExtensionRange* extension_range(int index) const;
+
+ // Returns true if the number is in one of the extension ranges.
+ bool IsExtensionNumber(int number) const;
+
+ // The number of extensions -- extending *other* messages -- that were
+ // defined nested within this message type's scope.
+ int extension_count() const;
+ // Get an extension by index, where 0 <= index < extension_count().
+ // These are returned in the order they were defined in the .proto file.
+ const FieldDescriptor* extension(int index) const;
+
+ // Looks up a named extension (which extends some *other* message type)
+ // defined within this message type's scope.
+ const FieldDescriptor* FindExtensionByName(const string& name) const;
+
+ // Similar to FindFieldByLowercaseName(), but finds extensions defined within
+ // this message type's scope.
+ const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const;
+
+ // Similar to FindFieldByCamelcaseName(), but finds extensions defined within
+ // this message type's scope.
+ const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
+
+ private:
+ typedef MessageOptions OptionsType;
+
+ // Internal version of DebugString; controls the level of indenting for
+ // correct depth
+ void DebugString(int depth, string *contents) const;
+
+ const string* name_;
+ const string* full_name_;
+ const FileDescriptor* file_;
+ const Descriptor* containing_type_;
+ const MessageOptions* options_;
+
+ // True if this is a placeholder for an unknown type.
+ bool is_placeholder_;
+ // True if this is a placeholder and the type name wasn't fully-qualified.
+ bool is_unqualified_placeholder_;
+
+ int field_count_;
+ FieldDescriptor* fields_;
+ int nested_type_count_;
+ Descriptor* nested_types_;
+ int enum_type_count_;
+ EnumDescriptor* enum_types_;
+ int extension_range_count_;
+ ExtensionRange* extension_ranges_;
+ int extension_count_;
+ FieldDescriptor* extensions_;
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<Descriptor>() and AllocateArray<Descriptor>() in descriptor.cc
+ // and update them to initialize the field.
+
+ // Must be constructed using DescriptorPool.
+ Descriptor() {}
+ friend class DescriptorBuilder;
+ friend class EnumDescriptor;
+ friend class FieldDescriptor;
+ friend class MethodDescriptor;
+ friend class FileDescriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor);
+};
+
+// Describes a single field of a message. To get the descriptor for a given
+// field, first get the Descriptor for the message in which it is defined,
+// then call Descriptor::FindFieldByName(). To get a FieldDescriptor for
+// an extension, do one of the following:
+// - Get the Descriptor or FileDescriptor for its containing scope, then
+// call Descriptor::FindExtensionByName() or
+// FileDescriptor::FindExtensionByName().
+// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber().
+// - Given a Reflection for a message object, call
+// Reflection::FindKnownExtensionByName() or
+// Reflection::FindKnownExtensionByNumber().
+// Use DescriptorPool to construct your own descriptors.
+class LIBPROTOBUF_EXPORT FieldDescriptor {
+ public:
+ // Identifies a field type. 0 is reserved for errors. The order is weird
+ // for historical reasons. Types 12 and up are new in proto2.
+ enum Type {
+ TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire.
+ TYPE_FLOAT = 2, // float, exactly four bytes on the wire.
+ TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers
+ // take 10 bytes. Use TYPE_SINT64 if negative
+ // values are likely.
+ TYPE_UINT64 = 4, // uint64, varint on the wire.
+ TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers
+ // take 10 bytes. Use TYPE_SINT32 if negative
+ // values are likely.
+ TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire.
+ TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire.
+ TYPE_BOOL = 8, // bool, varint on the wire.
+ TYPE_STRING = 9, // UTF-8 text.
+ TYPE_GROUP = 10, // Tag-delimited message. Deprecated.
+ TYPE_MESSAGE = 11, // Length-delimited message.
+
+ TYPE_BYTES = 12, // Arbitrary byte array.
+ TYPE_UINT32 = 13, // uint32, varint on the wire
+ TYPE_ENUM = 14, // Enum, varint on the wire
+ TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire
+ TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire
+ TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire
+ TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire
+
+ MAX_TYPE = 18, // Constant useful for defining lookup tables
+ // indexed by Type.
+ };
+
+ // Specifies the C++ data type used to represent the field. There is a
+ // fixed mapping from Type to CppType where each Type maps to exactly one
+ // CppType. 0 is reserved for errors.
+ enum CppType {
+ CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32
+ CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64
+ CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32
+ CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64
+ CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE
+ CPPTYPE_FLOAT = 6, // TYPE_FLOAT
+ CPPTYPE_BOOL = 7, // TYPE_BOOL
+ CPPTYPE_ENUM = 8, // TYPE_ENUM
+ CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES
+ CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP
+
+ MAX_CPPTYPE = 10, // Constant useful for defining lookup tables
+ // indexed by CppType.
+ };
+
+ // Identifies whether the field is optional, required, or repeated. 0 is
+ // reserved for errors.
+ enum Label {
+ LABEL_OPTIONAL = 1, // optional
+ LABEL_REQUIRED = 2, // required
+ LABEL_REPEATED = 3, // repeated
+
+ MAX_LABEL = 3, // Constant useful for defining lookup tables
+ // indexed by Label.
+ };
+
+ // Valid field numbers are positive integers up to kMaxNumber.
+ static const int kMaxNumber = (1 << 29) - 1;
+
+ // First field number reserved for the protocol buffer library implementation.
+ // Users may not declare fields that use reserved numbers.
+ static const int kFirstReservedNumber = 19000;
+ // Last field number reserved for the protocol buffer library implementation.
+ // Users may not declare fields that use reserved numbers.
+ static const int kLastReservedNumber = 19999;
+
+ const string& name() const; // Name of this field within the message.
+ const string& full_name() const; // Fully-qualified name of the field.
+ const FileDescriptor* file() const;// File in which this field was defined.
+ bool is_extension() const; // Is this an extension field?
+ int number() const; // Declared tag number.
+
+ // Same as name() except converted to lower-case. This (and especially the
+ // FindFieldByLowercaseName() method) can be useful when parsing formats
+ // which prefer to use lowercase naming style. (Although, technically
+ // field names should be lowercased anyway according to the protobuf style
+ // guide, so this only makes a difference when dealing with old .proto files
+ // which do not follow the guide.)
+ const string& lowercase_name() const;
+
+ // Same as name() except converted to camel-case. In this conversion, any
+ // time an underscore appears in the name, it is removed and the next
+ // letter is capitalized. Furthermore, the first letter of the name is
+ // lower-cased. Examples:
+ // FooBar -> fooBar
+ // foo_bar -> fooBar
+ // fooBar -> fooBar
+ // This (and especially the FindFieldByCamelcaseName() method) can be useful
+ // when parsing formats which prefer to use camel-case naming style.
+ const string& camelcase_name() const;
+
+ Type type() const; // Declared type of this field.
+ CppType cpp_type() const; // C++ type of this field.
+ Label label() const; // optional/required/repeated
+
+ bool is_required() const; // shorthand for label() == LABEL_REQUIRED
+ bool is_optional() const; // shorthand for label() == LABEL_OPTIONAL
+ bool is_repeated() const; // shorthand for label() == LABEL_REPEATED
+ bool is_packable() const; // shorthand for is_repeated() &&
+ // IsTypePackable(type())
+
+ // Index of this field within the message's field array, or the file or
+ // extension scope's extensions array.
+ int index() const;
+
+ // Does this field have an explicitly-declared default value?
+ bool has_default_value() const;
+
+ // Get the field default value if cpp_type() == CPPTYPE_INT32. If no
+ // explicit default was defined, the default is 0.
+ int32 default_value_int32() const;
+ // Get the field default value if cpp_type() == CPPTYPE_INT64. If no
+ // explicit default was defined, the default is 0.
+ int64 default_value_int64() const;
+ // Get the field default value if cpp_type() == CPPTYPE_UINT32. If no
+ // explicit default was defined, the default is 0.
+ uint32 default_value_uint32() const;
+ // Get the field default value if cpp_type() == CPPTYPE_UINT64. If no
+ // explicit default was defined, the default is 0.
+ uint64 default_value_uint64() const;
+ // Get the field default value if cpp_type() == CPPTYPE_FLOAT. If no
+ // explicit default was defined, the default is 0.0.
+ float default_value_float() const;
+ // Get the field default value if cpp_type() == CPPTYPE_DOUBLE. If no
+ // explicit default was defined, the default is 0.0.
+ double default_value_double() const;
+ // Get the field default value if cpp_type() == CPPTYPE_BOOL. If no
+ // explicit default was defined, the default is false.
+ bool default_value_bool() const;
+ // Get the field default value if cpp_type() == CPPTYPE_ENUM. If no
+ // explicit default was defined, the default is the first value defined
+ // in the enum type (all enum types are required to have at least one value).
+ // This never returns NULL.
+ const EnumValueDescriptor* default_value_enum() const;
+ // Get the field default value if cpp_type() == CPPTYPE_STRING. If no
+ // explicit default was defined, the default is the empty string.
+ const string& default_value_string() const;
+
+ // The Descriptor for the message of which this is a field. For extensions,
+ // this is the extended type. Never NULL.
+ const Descriptor* containing_type() const;
+
+ // An extension may be declared within the scope of another message. If this
+ // field is an extension (is_extension() is true), then extension_scope()
+ // returns that message, or NULL if the extension was declared at global
+ // scope. If this is not an extension, extension_scope() is undefined (may
+ // assert-fail).
+ const Descriptor* extension_scope() const;
+
+ // If type is TYPE_MESSAGE or TYPE_GROUP, returns a descriptor for the
+ // message or the group type. Otherwise, undefined.
+ const Descriptor* message_type() const;
+ // If type is TYPE_ENUM, returns a descriptor for the enum. Otherwise,
+ // undefined.
+ const EnumDescriptor* enum_type() const;
+
+ // EXPERIMENTAL; DO NOT USE.
+ // If this field is a map field, experimental_map_key() is the field
+ // that is the key for this map.
+ // experimental_map_key()->containing_type() is the same as message_type().
+ const FieldDescriptor* experimental_map_key() const;
+
+ // Get the FieldOptions for this field. This includes things listed in
+ // square brackets after the field definition. E.g., the field:
+ // optional string text = 1 [ctype=CORD];
+ // has the "ctype" option set. Allowed options are defined by FieldOptions
+ // in google/protobuf/descriptor.proto, and any available extensions of that
+ // message.
+ const FieldOptions& options() const;
+
+ // See Descriptor::CopyTo().
+ void CopyTo(FieldDescriptorProto* proto) const;
+
+ // See Descriptor::DebugString().
+ string DebugString() const;
+
+ // Helper method to get the CppType for a particular Type.
+ static CppType TypeToCppType(Type type);
+
+ // Return true iff [packed = true] is valid for fields of this type.
+ static inline bool IsTypePackable(Type field_type);
+
+ private:
+ typedef FieldOptions OptionsType;
+
+ // See Descriptor::DebugString().
+ void DebugString(int depth, string *contents) const;
+
+ // formats the default value appropriately and returns it as a string.
+ // Must have a default value to call this. If quote_string_type is true, then
+ // types of CPPTYPE_STRING whill be surrounded by quotes and CEscaped.
+ string DefaultValueAsString(bool quote_string_type) const;
+
+ const string* name_;
+ const string* full_name_;
+ const string* lowercase_name_;
+ const string* camelcase_name_;
+ const FileDescriptor* file_;
+ int number_;
+ Type type_;
+ Label label_;
+ bool is_extension_;
+ const Descriptor* containing_type_;
+ const Descriptor* extension_scope_;
+ const Descriptor* message_type_;
+ const EnumDescriptor* enum_type_;
+ const FieldDescriptor* experimental_map_key_;
+ const FieldOptions* options_;
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in
+ // descriptor.cc and update them to initialize the field.
+
+ bool has_default_value_;
+ union {
+ int32 default_value_int32_;
+ int64 default_value_int64_;
+ uint32 default_value_uint32_;
+ uint64 default_value_uint64_;
+ float default_value_float_;
+ double default_value_double_;
+ bool default_value_bool_;
+
+ const EnumValueDescriptor* default_value_enum_;
+ const string* default_value_string_;
+ };
+
+ static const CppType kTypeToCppTypeMap[MAX_TYPE + 1];
+
+ static const char * const kTypeToName[MAX_TYPE + 1];
+
+ static const char * const kLabelToName[MAX_LABEL + 1];
+
+ // Must be constructed using DescriptorPool.
+ FieldDescriptor() {}
+ friend class DescriptorBuilder;
+ friend class FileDescriptor;
+ friend class Descriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor);
+};
+
+// Describes an enum type defined in a .proto file. To get the EnumDescriptor
+// for a generated enum type, call TypeName_descriptor(). Use DescriptorPool
+// to construct your own descriptors.
+class LIBPROTOBUF_EXPORT EnumDescriptor {
+ public:
+ // The name of this enum type in the containing scope.
+ const string& name() const;
+
+ // The fully-qualified name of the enum type, scope delimited by periods.
+ const string& full_name() const;
+
+ // Index of this enum within the file or containing message's enum array.
+ int index() const;
+
+ // The .proto file in which this enum type was defined. Never NULL.
+ const FileDescriptor* file() const;
+
+ // The number of values for this EnumDescriptor. Guaranteed to be greater
+ // than zero.
+ int value_count() const;
+ // Gets a value by index, where 0 <= index < value_count().
+ // These are returned in the order they were defined in the .proto file.
+ const EnumValueDescriptor* value(int index) const;
+
+ // Looks up a value by name. Returns NULL if no such value exists.
+ const EnumValueDescriptor* FindValueByName(const string& name) const;
+ // Looks up a value by number. Returns NULL if no such value exists. If
+ // multiple values have this number, the first one defined is returned.
+ const EnumValueDescriptor* FindValueByNumber(int number) const;
+
+ // If this enum type is nested in a message type, this is that message type.
+ // Otherwise, NULL.
+ const Descriptor* containing_type() const;
+
+ // Get options for this enum type. These are specified in the .proto file by
+ // placing lines like "option foo = 1234;" in the enum definition. Allowed
+ // options are defined by EnumOptions in google/protobuf/descriptor.proto,
+ // and any available extensions of that message.
+ const EnumOptions& options() const;
+
+ // See Descriptor::CopyTo().
+ void CopyTo(EnumDescriptorProto* proto) const;
+
+ // See Descriptor::DebugString().
+ string DebugString() const;
+
+ private:
+ typedef EnumOptions OptionsType;
+
+ // See Descriptor::DebugString().
+ void DebugString(int depth, string *contents) const;
+
+ const string* name_;
+ const string* full_name_;
+ const FileDescriptor* file_;
+ const Descriptor* containing_type_;
+ const EnumOptions* options_;
+
+ // True if this is a placeholder for an unknown type.
+ bool is_placeholder_;
+ // True if this is a placeholder and the type name wasn't fully-qualified.
+ bool is_unqualified_placeholder_;
+
+ int value_count_;
+ EnumValueDescriptor* values_;
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<EnumDescriptor>() and AllocateArray<EnumDescriptor>() in
+ // descriptor.cc and update them to initialize the field.
+
+ // Must be constructed using DescriptorPool.
+ EnumDescriptor() {}
+ friend class DescriptorBuilder;
+ friend class Descriptor;
+ friend class FieldDescriptor;
+ friend class EnumValueDescriptor;
+ friend class FileDescriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor);
+};
+
+// Describes an individual enum constant of a particular type. To get the
+// EnumValueDescriptor for a given enum value, first get the EnumDescriptor
+// for its type, then use EnumDescriptor::FindValueByName() or
+// EnumDescriptor::FindValueByNumber(). Use DescriptorPool to construct
+// your own descriptors.
+class LIBPROTOBUF_EXPORT EnumValueDescriptor {
+ public:
+ const string& name() const; // Name of this enum constant.
+ int index() const; // Index within the enums's Descriptor.
+ int number() const; // Numeric value of this enum constant.
+
+ // The full_name of an enum value is a sibling symbol of the enum type.
+ // e.g. the full name of FieldDescriptorProto::TYPE_INT32 is actually
+ // "google.protobuf.FieldDescriptorProto.TYPE_INT32", NOT
+ // "google.protobuf.FieldDescriptorProto.Type.TYPE_INT32". This is to conform
+ // with C++ scoping rules for enums.
+ const string& full_name() const;
+
+ // The type of this value. Never NULL.
+ const EnumDescriptor* type() const;
+
+ // Get options for this enum value. These are specified in the .proto file
+ // by adding text like "[foo = 1234]" after an enum value definition.
+ // Allowed options are defined by EnumValueOptions in
+ // google/protobuf/descriptor.proto, and any available extensions of that
+ // message.
+ const EnumValueOptions& options() const;
+
+ // See Descriptor::CopyTo().
+ void CopyTo(EnumValueDescriptorProto* proto) const;
+
+ // See Descriptor::DebugString().
+ string DebugString() const;
+
+ private:
+ typedef EnumValueOptions OptionsType;
+
+ // See Descriptor::DebugString().
+ void DebugString(int depth, string *contents) const;
+
+ const string* name_;
+ const string* full_name_;
+ int number_;
+ const EnumDescriptor* type_;
+ const EnumValueOptions* options_;
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<EnumValueDescriptor>() and AllocateArray<EnumValueDescriptor>()
+ // in descriptor.cc and update them to initialize the field.
+
+ // Must be constructed using DescriptorPool.
+ EnumValueDescriptor() {}
+ friend class DescriptorBuilder;
+ friend class EnumDescriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor);
+};
+
+// Describes an RPC service. To get the ServiceDescriptor for a service,
+// call Service::GetDescriptor(). Generated service classes also have a
+// static method called descriptor() which returns the type's
+// ServiceDescriptor. Use DescriptorPool to construct your own descriptors.
+class LIBPROTOBUF_EXPORT ServiceDescriptor {
+ public:
+ // The name of the service, not including its containing scope.
+ const string& name() const;
+ // The fully-qualified name of the service, scope delimited by periods.
+ const string& full_name() const;
+ // Index of this service within the file's services array.
+ int index() const;
+
+ // The .proto file in which this service was defined. Never NULL.
+ const FileDescriptor* file() const;
+
+ // Get options for this service type. These are specified in the .proto file
+ // by placing lines like "option foo = 1234;" in the service definition.
+ // Allowed options are defined by ServiceOptions in
+ // google/protobuf/descriptor.proto, and any available extensions of that
+ // message.
+ const ServiceOptions& options() const;
+
+ // The number of methods this service defines.
+ int method_count() const;
+ // Gets a MethodDescriptor by index, where 0 <= index < method_count().
+ // These are returned in the order they were defined in the .proto file.
+ const MethodDescriptor* method(int index) const;
+
+ // Look up a MethodDescriptor by name.
+ const MethodDescriptor* FindMethodByName(const string& name) const;
+
+ // See Descriptor::CopyTo().
+ void CopyTo(ServiceDescriptorProto* proto) const;
+
+ // See Descriptor::DebugString().
+ string DebugString() const;
+
+ private:
+ typedef ServiceOptions OptionsType;
+
+ // See Descriptor::DebugString().
+ void DebugString(string *contents) const;
+
+ const string* name_;
+ const string* full_name_;
+ const FileDescriptor* file_;
+ const ServiceOptions* options_;
+ int method_count_;
+ MethodDescriptor* methods_;
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<ServiceDescriptor>() and AllocateArray<ServiceDescriptor>() in
+ // descriptor.cc and update them to initialize the field.
+
+ // Must be constructed using DescriptorPool.
+ ServiceDescriptor() {}
+ friend class DescriptorBuilder;
+ friend class FileDescriptor;
+ friend class MethodDescriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceDescriptor);
+};
+
+// Describes an individual service method. To obtain a MethodDescriptor given
+// a service, first get its ServiceDescriptor, then call
+// ServiceDescriptor::FindMethodByName(). Use DescriptorPool to construct your
+// own descriptors.
+class LIBPROTOBUF_EXPORT MethodDescriptor {
+ public:
+ // Name of this method, not including containing scope.
+ const string& name() const;
+ // The fully-qualified name of the method, scope delimited by periods.
+ const string& full_name() const;
+ // Index within the service's Descriptor.
+ int index() const;
+
+ // Gets the service to which this method belongs. Never NULL.
+ const ServiceDescriptor* service() const;
+
+ // Gets the type of protocol message which this method accepts as input.
+ const Descriptor* input_type() const;
+ // Gets the type of protocol message which this message produces as output.
+ const Descriptor* output_type() const;
+
+ // Get options for this method. These are specified in the .proto file by
+ // placing lines like "option foo = 1234;" in curly-braces after a method
+ // declaration. Allowed options are defined by MethodOptions in
+ // google/protobuf/descriptor.proto, and any available extensions of that
+ // message.
+ const MethodOptions& options() const;
+
+ // See Descriptor::CopyTo().
+ void CopyTo(MethodDescriptorProto* proto) const;
+
+ // See Descriptor::DebugString().
+ string DebugString() const;
+
+ private:
+ typedef MethodOptions OptionsType;
+
+ // See Descriptor::DebugString().
+ void DebugString(int depth, string *contents) const;
+
+ const string* name_;
+ const string* full_name_;
+ const ServiceDescriptor* service_;
+ const Descriptor* input_type_;
+ const Descriptor* output_type_;
+ const MethodOptions* options_;
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<MethodDescriptor>() and AllocateArray<MethodDescriptor>() in
+ // descriptor.cc and update them to initialize the field.
+
+ // Must be constructed using DescriptorPool.
+ MethodDescriptor() {}
+ friend class DescriptorBuilder;
+ friend class ServiceDescriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MethodDescriptor);
+};
+
+// Describes a whole .proto file. To get the FileDescriptor for a compiled-in
+// file, get the descriptor for something defined in that file and call
+// descriptor->file(). Use DescriptorPool to construct your own descriptors.
+class LIBPROTOBUF_EXPORT FileDescriptor {
+ public:
+ // The filename, relative to the source tree.
+ // e.g. "google/protobuf/descriptor.proto"
+ const string& name() const;
+
+ // The package, e.g. "google.protobuf.compiler".
+ const string& package() const;
+
+ // The DescriptorPool in which this FileDescriptor and all its contents were
+ // allocated. Never NULL.
+ const DescriptorPool* pool() const;
+
+ // The number of files imported by this one.
+ int dependency_count() const;
+ // Gets an imported file by index, where 0 <= index < dependency_count().
+ // These are returned in the order they were defined in the .proto file.
+ const FileDescriptor* dependency(int index) const;
+
+ // Number of top-level message types defined in this file. (This does not
+ // include nested types.)
+ int message_type_count() const;
+ // Gets a top-level message type, where 0 <= index < message_type_count().
+ // These are returned in the order they were defined in the .proto file.
+ const Descriptor* message_type(int index) const;
+
+ // Number of top-level enum types defined in this file. (This does not
+ // include nested types.)
+ int enum_type_count() const;
+ // Gets a top-level enum type, where 0 <= index < enum_type_count().
+ // These are returned in the order they were defined in the .proto file.
+ const EnumDescriptor* enum_type(int index) const;
+
+ // Number of services defined in this file.
+ int service_count() const;
+ // Gets a service, where 0 <= index < service_count().
+ // These are returned in the order they were defined in the .proto file.
+ const ServiceDescriptor* service(int index) const;
+
+ // Number of extensions defined at file scope. (This does not include
+ // extensions nested within message types.)
+ int extension_count() const;
+ // Gets an extension's descriptor, where 0 <= index < extension_count().
+ // These are returned in the order they were defined in the .proto file.
+ const FieldDescriptor* extension(int index) const;
+
+ // Get options for this file. These are specified in the .proto file by
+ // placing lines like "option foo = 1234;" at the top level, outside of any
+ // other definitions. Allowed options are defined by FileOptions in
+ // google/protobuf/descriptor.proto, and any available extensions of that
+ // message.
+ const FileOptions& options() const;
+
+ // Find a top-level message type by name. Returns NULL if not found.
+ const Descriptor* FindMessageTypeByName(const string& name) const;
+ // Find a top-level enum type by name. Returns NULL if not found.
+ const EnumDescriptor* FindEnumTypeByName(const string& name) const;
+ // Find an enum value defined in any top-level enum by name. Returns NULL if
+ // not found.
+ const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
+ // Find a service definition by name. Returns NULL if not found.
+ const ServiceDescriptor* FindServiceByName(const string& name) const;
+ // Find a top-level extension definition by name. Returns NULL if not found.
+ const FieldDescriptor* FindExtensionByName(const string& name) const;
+ // Similar to FindExtensionByName(), but searches by lowercased-name. See
+ // Descriptor::FindFieldByLowercaseName().
+ const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const;
+ // Similar to FindExtensionByName(), but searches by camelcased-name. See
+ // Descriptor::FindFieldByCamelcaseName().
+ const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
+
+ // See Descriptor::CopyTo().
+ void CopyTo(FileDescriptorProto* proto) const;
+
+ // See Descriptor::DebugString().
+ string DebugString() const;
+
+ private:
+ typedef FileOptions OptionsType;
+
+ const string* name_;
+ const string* package_;
+ const DescriptorPool* pool_;
+ int dependency_count_;
+ const FileDescriptor** dependencies_;
+ int message_type_count_;
+ Descriptor* message_types_;
+ int enum_type_count_;
+ EnumDescriptor* enum_types_;
+ int service_count_;
+ ServiceDescriptor* services_;
+ int extension_count_;
+ FieldDescriptor* extensions_;
+ const FileOptions* options_;
+
+ const FileDescriptorTables* tables_;
+ // IMPORTANT: If you add a new field, make sure to search for all instances
+ // of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in
+ // descriptor.cc and update them to initialize the field.
+
+ FileDescriptor() {}
+ friend class DescriptorBuilder;
+ friend class Descriptor;
+ friend class FieldDescriptor;
+ friend class EnumDescriptor;
+ friend class ServiceDescriptor;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileDescriptor);
+};
+
+// ===================================================================
+
+// Used to construct descriptors.
+//
+// Normally you won't want to build your own descriptors. Message classes
+// constructed by the protocol compiler will provide them for you. However,
+// if you are implementing Message on your own, or if you are writing a
+// program which can operate on totally arbitrary types and needs to load
+// them from some sort of database, you might need to.
+//
+// Since Descriptors are composed of a whole lot of cross-linked bits of
+// data that would be a pain to put together manually, the
+// DescriptorPool class is provided to make the process easier. It can
+// take a FileDescriptorProto (defined in descriptor.proto), validate it,
+// and convert it to a set of nicely cross-linked Descriptors.
+//
+// DescriptorPool also helps with memory management. Descriptors are
+// composed of many objects containing static data and pointers to each
+// other. In all likelihood, when it comes time to delete this data,
+// you'll want to delete it all at once. In fact, it is not uncommon to
+// have a whole pool of descriptors all cross-linked with each other which
+// you wish to delete all at once. This class represents such a pool, and
+// handles the memory management for you.
+//
+// You can also search for descriptors within a DescriptorPool by name, and
+// extensions by number.
+class LIBPROTOBUF_EXPORT DescriptorPool {
+ public:
+ // Create a normal, empty DescriptorPool.
+ DescriptorPool();
+
+ // Constructs a DescriptorPool that, when it can't find something among the
+ // descriptors already in the pool, looks for it in the given
+ // DescriptorDatabase.
+ // Notes:
+ // - If a DescriptorPool is constructed this way, its BuildFile*() methods
+ // must not be called (they will assert-fail). The only way to populate
+ // the pool with descriptors is to call the Find*By*() methods.
+ // - The Find*By*() methods may block the calling thread if the
+ // DescriptorDatabase blocks. This in turn means that parsing messages
+ // may block if they need to look up extensions.
+ // - The Find*By*() methods will use mutexes for thread-safety, thus making
+ // them slower even when they don't have to fall back to the database.
+ // In fact, even the Find*By*() methods of descriptor objects owned by
+ // this pool will be slower, since they will have to obtain locks too.
+ // - An ErrorCollector may optionally be given to collect validation errors
+ // in files loaded from the database. If not given, errors will be printed
+ // to GOOGLE_LOG(ERROR). Remember that files are built on-demand, so this
+ // ErrorCollector may be called from any thread that calls one of the
+ // Find*By*() methods.
+ class ErrorCollector;
+ explicit DescriptorPool(DescriptorDatabase* fallback_database,
+ ErrorCollector* error_collector = NULL);
+
+ ~DescriptorPool();
+
+ // Get a pointer to the generated pool. Generated protocol message classes
+ // which are compiled into the binary will allocate their descriptors in
+ // this pool. Do not add your own descriptors to this pool.
+ static const DescriptorPool* generated_pool();
+
+ // Find a FileDescriptor in the pool by file name. Returns NULL if not
+ // found.
+ const FileDescriptor* FindFileByName(const string& name) const;
+
+ // Find the FileDescriptor in the pool which defines the given symbol.
+ // If any of the Find*ByName() methods below would succeed, then this is
+ // equivalent to calling that method and calling the result's file() method.
+ // Otherwise this returns NULL.
+ const FileDescriptor* FindFileContainingSymbol(
+ const string& symbol_name) const;
+
+ // Looking up descriptors ------------------------------------------
+ // These find descriptors by fully-qualified name. These will find both
+ // top-level descriptors and nested descriptors. They return NULL if not
+ // found.
+
+ const Descriptor* FindMessageTypeByName(const string& name) const;
+ const FieldDescriptor* FindFieldByName(const string& name) const;
+ const FieldDescriptor* FindExtensionByName(const string& name) const;
+ const EnumDescriptor* FindEnumTypeByName(const string& name) const;
+ const EnumValueDescriptor* FindEnumValueByName(const string& name) const;
+ const ServiceDescriptor* FindServiceByName(const string& name) const;
+ const MethodDescriptor* FindMethodByName(const string& name) const;
+
+ // Finds an extension of the given type by number. The extendee must be
+ // a member of this DescriptorPool or one of its underlays.
+ const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee,
+ int number) const;
+
+ // Finds extensions of extendee. The extensions will be appended to
+ // out in an undefined order. Only extensions defined directly in
+ // this DescriptorPool or one of its underlays are guaranteed to be
+ // found: extensions defined in the fallback database might not be found
+ // depending on the database implementation.
+ void FindAllExtensions(const Descriptor* extendee,
+ vector<const FieldDescriptor*>* out) const;
+
+ // Building descriptors --------------------------------------------
+
+ // When converting a FileDescriptorProto to a FileDescriptor, various
+ // errors might be detected in the input. The caller may handle these
+ // programmatically by implementing an ErrorCollector.
+ class LIBPROTOBUF_EXPORT ErrorCollector {
+ public:
+ inline ErrorCollector() {}
+ virtual ~ErrorCollector();
+
+ // These constants specify what exact part of the construct is broken.
+ // This is useful e.g. for mapping the error back to an exact location
+ // in a .proto file.
+ enum ErrorLocation {
+ NAME, // the symbol name, or the package name for files
+ NUMBER, // field or extension range number
+ TYPE, // field type
+ EXTENDEE, // field extendee
+ DEFAULT_VALUE, // field default value
+ INPUT_TYPE, // method input type
+ OUTPUT_TYPE, // method output type
+ OPTION_NAME, // name in assignment
+ OPTION_VALUE, // value in option assignment
+ OTHER // some other problem
+ };
+
+ // Reports an error in the FileDescriptorProto.
+ virtual void AddError(
+ const string& filename, // File name in which the error occurred.
+ const string& element_name, // Full name of the erroneous element.
+ const Message* descriptor, // Descriptor of the erroneous element.
+ ErrorLocation location, // One of the location constants, above.
+ const string& message // Human-readable error message.
+ ) = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
+ };
+
+ // Convert the FileDescriptorProto to real descriptors and place them in
+ // this DescriptorPool. All dependencies of the file must already be in
+ // the pool. Returns the resulting FileDescriptor, or NULL if there were
+ // problems with the input (e.g. the message was invalid, or dependencies
+ // were missing). Details about the errors are written to GOOGLE_LOG(ERROR).
+ const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
+
+ // Same as BuildFile() except errors are sent to the given ErrorCollector.
+ const FileDescriptor* BuildFileCollectingErrors(
+ const FileDescriptorProto& proto,
+ ErrorCollector* error_collector);
+
+ // By default, it is an error if a FileDescriptorProto contains references
+ // to types or other files that are not found in the DescriptorPool (or its
+ // backing DescriptorDatabase, if any). If you call
+ // AllowUnknownDependencies(), however, then unknown types and files
+ // will be replaced by placeholder descriptors. This can allow you to
+ // perform some useful operations with a .proto file even if you do not
+ // have access to other .proto files on which it depends. However, some
+ // heuristics must be used to fill in the gaps in information, and these
+ // can lead to descriptors which are inaccurate. For example, the
+ // DescriptorPool may be forced to guess whether an unknown type is a message
+ // or an enum, as well as what package it resides in. Furthermore,
+ // placeholder types will not be discoverable via FindMessageTypeByName()
+ // and similar methods, which could confuse some descriptor-based algorithms.
+ // Generally, the results of this option should only be relied upon for
+ // debugging purposes.
+ void AllowUnknownDependencies() { allow_unknown_ = true; }
+
+ // Internal stuff --------------------------------------------------
+ // These methods MUST NOT be called from outside the proto2 library.
+ // These methods may contain hidden pitfalls and may be removed in a
+ // future library version.
+
+ // Create a DescriptorPool which is overlaid on top of some other pool.
+ // If you search for a descriptor in the overlay and it is not found, the
+ // underlay will be searched as a backup. If the underlay has its own
+ // underlay, that will be searched next, and so on. This also means that
+ // files built in the overlay will be cross-linked with the underlay's
+ // descriptors if necessary. The underlay remains property of the caller;
+ // it must remain valid for the lifetime of the newly-constructed pool.
+ //
+ // Example: Say you want to parse a .proto file at runtime in order to use
+ // its type with a DynamicMessage. Say this .proto file has dependencies,
+ // but you know that all the dependencies will be things that are already
+ // compiled into the binary. For ease of use, you'd like to load the types
+ // right out of generated_pool() rather than have to parse redundant copies
+ // of all these .protos and runtime. But, you don't want to add the parsed
+ // types directly into generated_pool(): this is not allowed, and would be
+ // bad design anyway. So, instead, you could use generated_pool() as an
+ // underlay for a new DescriptorPool in which you add only the new file.
+ //
+ // WARNING: Use of underlays can lead to many subtle gotchas. Instead,
+ // try to formulate what you want to do in terms of DescriptorDatabases.
+ explicit DescriptorPool(const DescriptorPool* underlay);
+
+ // Called by generated classes at init time to add their descriptors to
+ // generated_pool. Do NOT call this in your own code! filename must be a
+ // permanent string (e.g. a string literal).
+ static void InternalAddGeneratedFile(
+ const void* encoded_file_descriptor, int size);
+
+
+ // For internal use only: Gets a non-const pointer to the generated pool.
+ // This is called at static-initialization time only, so thread-safety is
+ // not a concern. If both an underlay and a fallback database are present,
+ // the fallback database takes precedence.
+ static DescriptorPool* internal_generated_pool();
+
+ // For internal use only: Changes the behavior of BuildFile() such that it
+ // allows the file to make reference to message types declared in other files
+ // which it did not officially declare as dependencies.
+ void InternalDontEnforceDependencies();
+
+ // For internal use only.
+ void internal_set_underlay(const DescriptorPool* underlay) {
+ underlay_ = underlay;
+ }
+
+ // For internal (unit test) use only: Returns true if a FileDescriptor has
+ // been constructed for the given file, false otherwise. Useful for testing
+ // lazy descriptor initialization behavior.
+ bool InternalIsFileLoaded(const string& filename) const;
+
+ private:
+ friend class Descriptor;
+ friend class FieldDescriptor;
+ friend class EnumDescriptor;
+ friend class ServiceDescriptor;
+ friend class FileDescriptor;
+ friend class DescriptorBuilder;
+
+ // Tries to find something in the fallback database and link in the
+ // corresponding proto file. Returns true if successful, in which case
+ // the caller should search for the thing again. These are declared
+ // const because they are called by (semantically) const methods.
+ bool TryFindFileInFallbackDatabase(const string& name) const;
+ bool TryFindSymbolInFallbackDatabase(const string& name) const;
+ bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type,
+ int field_number) const;
+
+ // Like BuildFile() but called internally when the file has been loaded from
+ // fallback_database_. Declared const because it is called by (semantically)
+ // const methods.
+ const FileDescriptor* BuildFileFromDatabase(
+ const FileDescriptorProto& proto) const;
+
+ // If fallback_database_ is NULL, this is NULL. Otherwise, this is a mutex
+ // which must be locked while accessing tables_.
+ Mutex* mutex_;
+
+ // See constructor.
+ DescriptorDatabase* fallback_database_;
+ ErrorCollector* default_error_collector_;
+ const DescriptorPool* underlay_;
+
+ // This class contains a lot of hash maps with complicated types that
+ // we'd like to keep out of the header.
+ class Tables;
+ scoped_ptr<Tables> tables_;
+
+ bool enforce_dependencies_;
+ bool allow_unknown_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool);
+};
+
+// inline methods ====================================================
+
+// These macros makes this repetitive code more readable.
+#define PROTOBUF_DEFINE_ACCESSOR(CLASS, FIELD, TYPE) \
+ inline TYPE CLASS::FIELD() const { return FIELD##_; }
+
+// Strings fields are stored as pointers but returned as const references.
+#define PROTOBUF_DEFINE_STRING_ACCESSOR(CLASS, FIELD) \
+ inline const string& CLASS::FIELD() const { return *FIELD##_; }
+
+// Arrays take an index parameter, obviously.
+#define PROTOBUF_DEFINE_ARRAY_ACCESSOR(CLASS, FIELD, TYPE) \
+ inline TYPE CLASS::FIELD(int index) const { return FIELD##s_ + index; }
+
+#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \
+ inline const TYPE& CLASS::options() const { return *options_; }
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(Descriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*)
+
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int)
+
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, field, const FieldDescriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, nested_type, const Descriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, enum_type, const EnumDescriptor*)
+
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_range_count, int)
+PROTOBUF_DEFINE_ACCESSOR(Descriptor, extension_count, int)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension_range,
+ const Descriptor::ExtensionRange*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, extension,
+ const FieldDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, experimental_map_key,
+ const FieldDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions);
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32 , int32 )
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int64 , int64 )
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint32, uint32)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float )
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool , bool )
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum,
+ const EnumValueDescriptor*)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string)
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(EnumDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value,
+ const EnumValueDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(EnumValueDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int)
+PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(ServiceDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method,
+ const MethodDescriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions);
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FileDescriptor, package)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, pool, const DescriptorPool*)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, dependency_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int)
+PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions);
+
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, enum_type, const EnumDescriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, service,
+ const ServiceDescriptor*)
+PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension,
+ const FieldDescriptor*)
+
+#undef PROTOBUF_DEFINE_ACCESSOR
+#undef PROTOBUF_DEFINE_STRING_ACCESSOR
+#undef PROTOBUF_DEFINE_ARRAY_ACCESSOR
+
+// A few accessors differ from the macros...
+
+inline bool FieldDescriptor::is_required() const {
+ return label() == LABEL_REQUIRED;
+}
+
+inline bool FieldDescriptor::is_optional() const {
+ return label() == LABEL_OPTIONAL;
+}
+
+inline bool FieldDescriptor::is_repeated() const {
+ return label() == LABEL_REPEATED;
+}
+
+inline bool FieldDescriptor::is_packable() const {
+ return is_repeated() && IsTypePackable(type());
+}
+
+// To save space, index() is computed by looking at the descriptor's position
+// in the parent's array of children.
+inline int FieldDescriptor::index() const {
+ if (!is_extension_) {
+ return this - containing_type_->fields_;
+ } else if (extension_scope_ != NULL) {
+ return this - extension_scope_->extensions_;
+ } else {
+ return this - file_->extensions_;
+ }
+}
+
+inline int Descriptor::index() const {
+ if (containing_type_ == NULL) {
+ return this - file_->message_types_;
+ } else {
+ return this - containing_type_->nested_types_;
+ }
+}
+
+inline int EnumDescriptor::index() const {
+ if (containing_type_ == NULL) {
+ return this - file_->enum_types_;
+ } else {
+ return this - containing_type_->enum_types_;
+ }
+}
+
+inline int EnumValueDescriptor::index() const {
+ return this - type_->values_;
+}
+
+inline int ServiceDescriptor::index() const {
+ return this - file_->services_;
+}
+
+inline int MethodDescriptor::index() const {
+ return this - service_->methods_;
+}
+
+inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const {
+ return kTypeToCppTypeMap[type_];
+}
+
+inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) {
+ return kTypeToCppTypeMap[type];
+}
+
+inline bool FieldDescriptor::IsTypePackable(Type field_type) {
+ return (field_type != FieldDescriptor::TYPE_STRING &&
+ field_type != FieldDescriptor::TYPE_GROUP &&
+ field_type != FieldDescriptor::TYPE_MESSAGE &&
+ field_type != FieldDescriptor::TYPE_BYTES);
+}
+
+inline const FileDescriptor* FileDescriptor::dependency(int index) const {
+ return dependencies_[index];
+}
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_DESCRIPTOR_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor.pb.cc b/src/third_party/protobuf/src/google/protobuf/descriptor.pb.cc
new file mode 100644
index 0000000..7d16080
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor.pb.cc
@@ -0,0 +1,7753 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "google/protobuf/descriptor.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+const ::google::protobuf::Descriptor* FileDescriptorSet_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ FileDescriptorSet_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ FileDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ DescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ DescriptorProto_ExtensionRange_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ FieldDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL;
+const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ EnumDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ EnumValueDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ ServiceDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ MethodDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ FileOptions_reflection_ = NULL;
+const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ MessageOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ FieldOptions_reflection_ = NULL;
+const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ EnumOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ EnumValueOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ ServiceOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ MethodOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* UninterpretedOption_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ UninterpretedOption_reflection_ = NULL;
+const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ UninterpretedOption_NamePart_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SourceCodeInfo_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ SourceCodeInfo_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ SourceCodeInfo_Location_reflection_ = NULL;
+
+} // namespace
+
+
+void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
+ protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ const ::google::protobuf::FileDescriptor* file =
+ ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+ "google/protobuf/descriptor.proto");
+ GOOGLE_CHECK(file != NULL);
+ FileDescriptorSet_descriptor_ = file->message_type(0);
+ static const int FileDescriptorSet_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_),
+ };
+ FileDescriptorSet_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ FileDescriptorSet_descriptor_,
+ FileDescriptorSet::default_instance_,
+ FileDescriptorSet_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(FileDescriptorSet));
+ FileDescriptorProto_descriptor_ = file->message_type(1);
+ static const int FileDescriptorProto_offsets_[9] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, message_type_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, enum_type_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, source_code_info_),
+ };
+ FileDescriptorProto_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ FileDescriptorProto_descriptor_,
+ FileDescriptorProto::default_instance_,
+ FileDescriptorProto_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(FileDescriptorProto));
+ DescriptorProto_descriptor_ = file->message_type(2);
+ static const int DescriptorProto_offsets_[7] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, nested_type_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, enum_type_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_),
+ };
+ DescriptorProto_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ DescriptorProto_descriptor_,
+ DescriptorProto::default_instance_,
+ DescriptorProto_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(DescriptorProto));
+ DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0);
+ static const int DescriptorProto_ExtensionRange_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_),
+ };
+ DescriptorProto_ExtensionRange_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ DescriptorProto_ExtensionRange_descriptor_,
+ DescriptorProto_ExtensionRange::default_instance_,
+ DescriptorProto_ExtensionRange_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(DescriptorProto_ExtensionRange));
+ FieldDescriptorProto_descriptor_ = file->message_type(3);
+ static const int FieldDescriptorProto_offsets_[8] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, extendee_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, default_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_),
+ };
+ FieldDescriptorProto_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ FieldDescriptorProto_descriptor_,
+ FieldDescriptorProto::default_instance_,
+ FieldDescriptorProto_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(FieldDescriptorProto));
+ FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0);
+ FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1);
+ EnumDescriptorProto_descriptor_ = file->message_type(4);
+ static const int EnumDescriptorProto_offsets_[3] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_),
+ };
+ EnumDescriptorProto_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ EnumDescriptorProto_descriptor_,
+ EnumDescriptorProto::default_instance_,
+ EnumDescriptorProto_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(EnumDescriptorProto));
+ EnumValueDescriptorProto_descriptor_ = file->message_type(5);
+ static const int EnumValueDescriptorProto_offsets_[3] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_),
+ };
+ EnumValueDescriptorProto_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ EnumValueDescriptorProto_descriptor_,
+ EnumValueDescriptorProto::default_instance_,
+ EnumValueDescriptorProto_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(EnumValueDescriptorProto));
+ ServiceDescriptorProto_descriptor_ = file->message_type(6);
+ static const int ServiceDescriptorProto_offsets_[3] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_),
+ };
+ ServiceDescriptorProto_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ ServiceDescriptorProto_descriptor_,
+ ServiceDescriptorProto::default_instance_,
+ ServiceDescriptorProto_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(ServiceDescriptorProto));
+ MethodDescriptorProto_descriptor_ = file->message_type(7);
+ static const int MethodDescriptorProto_offsets_[4] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, options_),
+ };
+ MethodDescriptorProto_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ MethodDescriptorProto_descriptor_,
+ MethodDescriptorProto::default_instance_,
+ MethodDescriptorProto_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(MethodDescriptorProto));
+ FileOptions_descriptor_ = file->message_type(8);
+ static const int FileOptions_offsets_[10] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, retain_unknown_fields_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generate_equals_and_hash_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
+ };
+ FileOptions_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ FileOptions_descriptor_,
+ FileOptions::default_instance_,
+ FileOptions_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _unknown_fields_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_),
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(FileOptions));
+ FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0);
+ MessageOptions_descriptor_ = file->message_type(9);
+ static const int MessageOptions_offsets_[3] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, uninterpreted_option_),
+ };
+ MessageOptions_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ MessageOptions_descriptor_,
+ MessageOptions::default_instance_,
+ MessageOptions_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _unknown_fields_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_),
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(MessageOptions));
+ FieldOptions_descriptor_ = file->message_type(10);
+ static const int FieldOptions_offsets_[5] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, deprecated_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_),
+ };
+ FieldOptions_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ FieldOptions_descriptor_,
+ FieldOptions::default_instance_,
+ FieldOptions_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _unknown_fields_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_),
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(FieldOptions));
+ FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
+ EnumOptions_descriptor_ = file->message_type(11);
+ static const int EnumOptions_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_),
+ };
+ EnumOptions_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ EnumOptions_descriptor_,
+ EnumOptions::default_instance_,
+ EnumOptions_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _unknown_fields_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_),
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(EnumOptions));
+ EnumValueOptions_descriptor_ = file->message_type(12);
+ static const int EnumValueOptions_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_),
+ };
+ EnumValueOptions_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ EnumValueOptions_descriptor_,
+ EnumValueOptions::default_instance_,
+ EnumValueOptions_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _unknown_fields_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_),
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(EnumValueOptions));
+ ServiceOptions_descriptor_ = file->message_type(13);
+ static const int ServiceOptions_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_),
+ };
+ ServiceOptions_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ ServiceOptions_descriptor_,
+ ServiceOptions::default_instance_,
+ ServiceOptions_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _unknown_fields_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_),
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(ServiceOptions));
+ MethodOptions_descriptor_ = file->message_type(14);
+ static const int MethodOptions_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_),
+ };
+ MethodOptions_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ MethodOptions_descriptor_,
+ MethodOptions::default_instance_,
+ MethodOptions_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _unknown_fields_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_),
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(MethodOptions));
+ UninterpretedOption_descriptor_ = file->message_type(15);
+ static const int UninterpretedOption_offsets_[7] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, aggregate_value_),
+ };
+ UninterpretedOption_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ UninterpretedOption_descriptor_,
+ UninterpretedOption::default_instance_,
+ UninterpretedOption_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(UninterpretedOption));
+ UninterpretedOption_NamePart_descriptor_ = UninterpretedOption_descriptor_->nested_type(0);
+ static const int UninterpretedOption_NamePart_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, is_extension_),
+ };
+ UninterpretedOption_NamePart_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ UninterpretedOption_NamePart_descriptor_,
+ UninterpretedOption_NamePart::default_instance_,
+ UninterpretedOption_NamePart_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(UninterpretedOption_NamePart));
+ SourceCodeInfo_descriptor_ = file->message_type(16);
+ static const int SourceCodeInfo_offsets_[1] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
+ };
+ SourceCodeInfo_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ SourceCodeInfo_descriptor_,
+ SourceCodeInfo::default_instance_,
+ SourceCodeInfo_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(SourceCodeInfo));
+ SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0);
+ static const int SourceCodeInfo_Location_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_),
+ };
+ SourceCodeInfo_Location_reflection_ =
+ new ::google::protobuf::internal::GeneratedMessageReflection(
+ SourceCodeInfo_Location_descriptor_,
+ SourceCodeInfo_Location::default_instance_,
+ SourceCodeInfo_Location_offsets_,
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _has_bits_[0]),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _unknown_fields_),
+ -1,
+ ::google::protobuf::DescriptorPool::generated_pool(),
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(SourceCodeInfo_Location));
+}
+
+namespace {
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
+inline void protobuf_AssignDescriptorsOnce() {
+ ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
+ &protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ DescriptorProto_descriptor_, &DescriptorProto::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ FileOptions_descriptor_, &FileOptions::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ MessageOptions_descriptor_, &MessageOptions::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ FieldOptions_descriptor_, &FieldOptions::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ EnumOptions_descriptor_, &EnumOptions::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ EnumValueOptions_descriptor_, &EnumValueOptions::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ ServiceOptions_descriptor_, &ServiceOptions::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ MethodOptions_descriptor_, &MethodOptions::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ UninterpretedOption_descriptor_, &UninterpretedOption::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance());
+}
+
+} // namespace
+
+void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
+ delete FileDescriptorSet::default_instance_;
+ delete FileDescriptorSet_reflection_;
+ delete FileDescriptorProto::default_instance_;
+ delete FileDescriptorProto_reflection_;
+ delete DescriptorProto::default_instance_;
+ delete DescriptorProto_reflection_;
+ delete DescriptorProto_ExtensionRange::default_instance_;
+ delete DescriptorProto_ExtensionRange_reflection_;
+ delete FieldDescriptorProto::default_instance_;
+ delete FieldDescriptorProto_reflection_;
+ delete EnumDescriptorProto::default_instance_;
+ delete EnumDescriptorProto_reflection_;
+ delete EnumValueDescriptorProto::default_instance_;
+ delete EnumValueDescriptorProto_reflection_;
+ delete ServiceDescriptorProto::default_instance_;
+ delete ServiceDescriptorProto_reflection_;
+ delete MethodDescriptorProto::default_instance_;
+ delete MethodDescriptorProto_reflection_;
+ delete FileOptions::default_instance_;
+ delete FileOptions_reflection_;
+ delete MessageOptions::default_instance_;
+ delete MessageOptions_reflection_;
+ delete FieldOptions::default_instance_;
+ delete FieldOptions_reflection_;
+ delete EnumOptions::default_instance_;
+ delete EnumOptions_reflection_;
+ delete EnumValueOptions::default_instance_;
+ delete EnumValueOptions_reflection_;
+ delete ServiceOptions::default_instance_;
+ delete ServiceOptions_reflection_;
+ delete MethodOptions::default_instance_;
+ delete MethodOptions_reflection_;
+ delete UninterpretedOption::default_instance_;
+ delete UninterpretedOption_reflection_;
+ delete UninterpretedOption_NamePart::default_instance_;
+ delete UninterpretedOption_NamePart_reflection_;
+ delete SourceCodeInfo::default_instance_;
+ delete SourceCodeInfo_reflection_;
+ delete SourceCodeInfo_Location::default_instance_;
+ delete SourceCodeInfo_Location_reflection_;
+}
+
+void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
+ static bool already_here = false;
+ if (already_here) return;
+ already_here = true;
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ "\n google/protobuf/descriptor.proto\022\017goog"
+ "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
+ "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
+ "roto\"\227\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
+ "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
+ "6\n\014message_type\030\004 \003(\0132 .google.protobuf."
+ "DescriptorProto\0227\n\tenum_type\030\005 \003(\0132$.goo"
+ "gle.protobuf.EnumDescriptorProto\0228\n\007serv"
+ "ice\030\006 \003(\0132\'.google.protobuf.ServiceDescr"
+ "iptorProto\0228\n\textension\030\007 \003(\0132%.google.p"
+ "rotobuf.FieldDescriptorProto\022-\n\007options\030"
+ "\010 \001(\0132\034.google.protobuf.FileOptions\0229\n\020s"
+ "ource_code_info\030\t \001(\0132\037.google.protobuf."
+ "SourceCodeInfo\"\251\003\n\017DescriptorProto\022\014\n\004na"
+ "me\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.google.protobu"
+ "f.FieldDescriptorProto\0228\n\textension\030\006 \003("
+ "\0132%.google.protobuf.FieldDescriptorProto"
+ "\0225\n\013nested_type\030\003 \003(\0132 .google.protobuf."
+ "DescriptorProto\0227\n\tenum_type\030\004 \003(\0132$.goo"
+ "gle.protobuf.EnumDescriptorProto\022H\n\017exte"
+ "nsion_range\030\005 \003(\0132/.google.protobuf.Desc"
+ "riptorProto.ExtensionRange\0220\n\007options\030\007 "
+ "\001(\0132\037.google.protobuf.MessageOptions\032,\n\016"
+ "ExtensionRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001"
+ "(\005\"\224\005\n\024FieldDescriptorProto\022\014\n\004name\030\001 \001("
+ "\t\022\016\n\006number\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.googl"
+ "e.protobuf.FieldDescriptorProto.Label\0228\n"
+ "\004type\030\005 \001(\0162*.google.protobuf.FieldDescr"
+ "iptorProto.Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010ex"
+ "tendee\030\002 \001(\t\022\025\n\rdefault_value\030\007 \001(\t\022.\n\007o"
+ "ptions\030\010 \001(\0132\035.google.protobuf.FieldOpti"
+ "ons\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FL"
+ "OAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016"
+ "\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE"
+ "_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING"
+ "\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\n"
+ "TYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_EN"
+ "UM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64"
+ "\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005"
+ "Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUI"
+ "RED\020\002\022\022\n\016LABEL_REPEATED\020\003\"\214\001\n\023EnumDescri"
+ "ptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132)"
+ ".google.protobuf.EnumValueDescriptorProt"
+ "o\022-\n\007options\030\003 \001(\0132\034.google.protobuf.Enu"
+ "mOptions\"l\n\030EnumValueDescriptorProto\022\014\n\004"
+ "name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 "
+ "\001(\0132!.google.protobuf.EnumValueOptions\"\220"
+ "\001\n\026ServiceDescriptorProto\022\014\n\004name\030\001 \001(\t\022"
+ "6\n\006method\030\002 \003(\0132&.google.protobuf.Method"
+ "DescriptorProto\0220\n\007options\030\003 \001(\0132\037.googl"
+ "e.protobuf.ServiceOptions\"\177\n\025MethodDescr"
+ "iptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002"
+ " \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001"
+ "(\0132\036.google.protobuf.MethodOptions\"\373\003\n\013F"
+ "ileOptions\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java"
+ "_outer_classname\030\010 \001(\t\022\"\n\023java_multiple_"
+ "files\030\n \001(\010:\005false\022$\n\025retain_unknown_fie"
+ "lds\030\013 \001(\010:\005false\022,\n\035java_generate_equals"
+ "_and_hash\030\024 \001(\010:\005false\022F\n\014optimize_for\030\t"
+ " \001(\0162).google.protobuf.FileOptions.Optim"
+ "izeMode:\005SPEED\022\"\n\023cc_generic_services\030\020 "
+ "\001(\010:\005false\022$\n\025java_generic_services\030\021 \001("
+ "\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010:\005f"
+ "alse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go"
+ "ogle.protobuf.UninterpretedOption\":\n\014Opt"
+ "imizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014L"
+ "ITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOpti"
+ "ons\022&\n\027message_set_wire_format\030\001 \001(\010:\005fa"
+ "lse\022.\n\037no_standard_descriptor_accessor\030\002"
+ " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003"
+ "(\0132$.google.protobuf.UninterpretedOption"
+ "*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptions\022:\n\005ctype\030\001 "
+ "\001(\0162#.google.protobuf.FieldOptions.CType"
+ ":\006STRING\022\016\n\006packed\030\002 \001(\010\022\031\n\ndeprecated\030\003"
+ " \001(\010:\005false\022\034\n\024experimental_map_key\030\t \001("
+ "\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl"
+ "e.protobuf.UninterpretedOption\"/\n\005CType\022"
+ "\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002*"
+ "\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022C\n\024uninterpret"
+ "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
+ "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n\020EnumValueOp"
+ "tions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
+ "oogle.protobuf.UninterpretedOption*\t\010\350\007\020"
+ "\200\200\200\200\002\"`\n\016ServiceOptions\022C\n\024uninterpreted"
+ "_option\030\347\007 \003(\0132$.google.protobuf.Uninter"
+ "pretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rMethodOptions"
+ "\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.google"
+ ".protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002"
+ "\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132-"
+ ".google.protobuf.UninterpretedOption.Nam"
+ "ePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posit"
+ "ive_int_value\030\004 \001(\004\022\032\n\022negative_int_valu"
+ "e\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_"
+ "value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010"
+ "NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extens"
+ "ion\030\002 \002(\010\"|\n\016SourceCodeInfo\022:\n\010location\030"
+ "\001 \003(\0132(.google.protobuf.SourceCodeInfo.L"
+ "ocation\032.\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n"
+ "\004span\030\002 \003(\005B\002\020\001B)\n\023com.google.protobufB\020"
+ "DescriptorProtosH\001", 3978);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
+ FileDescriptorSet::default_instance_ = new FileDescriptorSet();
+ FileDescriptorProto::default_instance_ = new FileDescriptorProto();
+ DescriptorProto::default_instance_ = new DescriptorProto();
+ DescriptorProto_ExtensionRange::default_instance_ = new DescriptorProto_ExtensionRange();
+ FieldDescriptorProto::default_instance_ = new FieldDescriptorProto();
+ EnumDescriptorProto::default_instance_ = new EnumDescriptorProto();
+ EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto();
+ ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto();
+ MethodDescriptorProto::default_instance_ = new MethodDescriptorProto();
+ FileOptions::default_instance_ = new FileOptions();
+ MessageOptions::default_instance_ = new MessageOptions();
+ FieldOptions::default_instance_ = new FieldOptions();
+ EnumOptions::default_instance_ = new EnumOptions();
+ EnumValueOptions::default_instance_ = new EnumValueOptions();
+ ServiceOptions::default_instance_ = new ServiceOptions();
+ MethodOptions::default_instance_ = new MethodOptions();
+ UninterpretedOption::default_instance_ = new UninterpretedOption();
+ UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart();
+ SourceCodeInfo::default_instance_ = new SourceCodeInfo();
+ SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location();
+ FileDescriptorSet::default_instance_->InitAsDefaultInstance();
+ FileDescriptorProto::default_instance_->InitAsDefaultInstance();
+ DescriptorProto::default_instance_->InitAsDefaultInstance();
+ DescriptorProto_ExtensionRange::default_instance_->InitAsDefaultInstance();
+ FieldDescriptorProto::default_instance_->InitAsDefaultInstance();
+ EnumDescriptorProto::default_instance_->InitAsDefaultInstance();
+ EnumValueDescriptorProto::default_instance_->InitAsDefaultInstance();
+ ServiceDescriptorProto::default_instance_->InitAsDefaultInstance();
+ MethodDescriptorProto::default_instance_->InitAsDefaultInstance();
+ FileOptions::default_instance_->InitAsDefaultInstance();
+ MessageOptions::default_instance_->InitAsDefaultInstance();
+ FieldOptions::default_instance_->InitAsDefaultInstance();
+ EnumOptions::default_instance_->InitAsDefaultInstance();
+ EnumValueOptions::default_instance_->InitAsDefaultInstance();
+ ServiceOptions::default_instance_->InitAsDefaultInstance();
+ MethodOptions::default_instance_->InitAsDefaultInstance();
+ UninterpretedOption::default_instance_->InitAsDefaultInstance();
+ UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance();
+ SourceCodeInfo::default_instance_->InitAsDefaultInstance();
+ SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance();
+ ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
+ StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto() {
+ protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ }
+} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int FileDescriptorSet::kFileFieldNumber;
+#endif // !_MSC_VER
+
+FileDescriptorSet::FileDescriptorSet()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void FileDescriptorSet::InitAsDefaultInstance() {
+}
+
+FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void FileDescriptorSet::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FileDescriptorSet::~FileDescriptorSet() {
+ SharedDtor();
+}
+
+void FileDescriptorSet::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void FileDescriptorSet::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FileDescriptorSet_descriptor_;
+}
+
+const FileDescriptorSet& FileDescriptorSet::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+FileDescriptorSet* FileDescriptorSet::default_instance_ = NULL;
+
+FileDescriptorSet* FileDescriptorSet::New() const {
+ return new FileDescriptorSet;
+}
+
+void FileDescriptorSet::Clear() {
+ file_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool FileDescriptorSet::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_file:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_file()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(10)) goto parse_file;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void FileDescriptorSet::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ for (int i = 0; i < this->file_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, this->file(i), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ for (int i = 0; i < this->file_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 1, this->file(i), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int FileDescriptorSet::ByteSize() const {
+ int total_size = 0;
+
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ total_size += 1 * this->file_size();
+ for (int i = 0; i < this->file_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->file(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const FileDescriptorSet* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorSet*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ file_.MergeFrom(from.file_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FileDescriptorSet::IsInitialized() const {
+
+ for (int i = 0; i < file_size(); i++) {
+ if (!this->file(i).IsInitialized()) return false;
+ }
+ return true;
+}
+
+void FileDescriptorSet::Swap(FileDescriptorSet* other) {
+ if (other != this) {
+ file_.Swap(&other->file_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = FileDescriptorSet_descriptor_;
+ metadata.reflection = FileDescriptorSet_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int FileDescriptorProto::kNameFieldNumber;
+const int FileDescriptorProto::kPackageFieldNumber;
+const int FileDescriptorProto::kDependencyFieldNumber;
+const int FileDescriptorProto::kMessageTypeFieldNumber;
+const int FileDescriptorProto::kEnumTypeFieldNumber;
+const int FileDescriptorProto::kServiceFieldNumber;
+const int FileDescriptorProto::kExtensionFieldNumber;
+const int FileDescriptorProto::kOptionsFieldNumber;
+const int FileDescriptorProto::kSourceCodeInfoFieldNumber;
+#endif // !_MSC_VER
+
+FileDescriptorProto::FileDescriptorProto()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void FileDescriptorProto::InitAsDefaultInstance() {
+ options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance());
+ source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(&::google::protobuf::SourceCodeInfo::default_instance());
+}
+
+FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void FileDescriptorProto::SharedCtor() {
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ options_ = NULL;
+ source_code_info_ = NULL;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FileDescriptorProto::~FileDescriptorProto() {
+ SharedDtor();
+}
+
+void FileDescriptorProto::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_;
+ }
+ if (package_ != &::google::protobuf::internal::kEmptyString) {
+ delete package_;
+ }
+ if (this != default_instance_) {
+ delete options_;
+ delete source_code_info_;
+ }
+}
+
+void FileDescriptorProto::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FileDescriptorProto_descriptor_;
+}
+
+const FileDescriptorProto& FileDescriptorProto::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+FileDescriptorProto* FileDescriptorProto::default_instance_ = NULL;
+
+FileDescriptorProto* FileDescriptorProto::New() const {
+ return new FileDescriptorProto;
+}
+
+void FileDescriptorProto::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ }
+ if (has_package()) {
+ if (package_ != &::google::protobuf::internal::kEmptyString) {
+ package_->clear();
+ }
+ }
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
+ }
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (has_source_code_info()) {
+ if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+ }
+ }
+ dependency_.Clear();
+ message_type_.Clear();
+ enum_type_.Clear();
+ service_.Clear();
+ extension_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool FileDescriptorProto::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_package;
+ break;
+ }
+
+ // optional string package = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_package:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_package()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->package().data(), this->package().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(26)) goto parse_dependency;
+ break;
+ }
+
+ // repeated string dependency = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_dependency:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->add_dependency()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->dependency(this->dependency_size() - 1).data(),
+ this->dependency(this->dependency_size() - 1).length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(26)) goto parse_dependency;
+ if (input->ExpectTag(34)) goto parse_message_type;
+ break;
+ }
+
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ case 4: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_message_type:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_message_type()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(34)) goto parse_message_type;
+ if (input->ExpectTag(42)) goto parse_enum_type;
+ break;
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ case 5: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_enum_type:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_enum_type()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(42)) goto parse_enum_type;
+ if (input->ExpectTag(50)) goto parse_service;
+ break;
+ }
+
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ case 6: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_service:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_service()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(50)) goto parse_service;
+ if (input->ExpectTag(58)) goto parse_extension;
+ break;
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ case 7: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_extension:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_extension()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(58)) goto parse_extension;
+ if (input->ExpectTag(66)) goto parse_options;
+ break;
+ }
+
+ // optional .google.protobuf.FileOptions options = 8;
+ case 8: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_options:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_options()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(74)) goto parse_source_code_info;
+ break;
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ case 9: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_source_code_info:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_source_code_info()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void FileDescriptorProto::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name(), output);
+ }
+
+ // optional string package = 2;
+ if (has_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->package().data(), this->package().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 2, this->package(), output);
+ }
+
+ // repeated string dependency = 3;
+ for (int i = 0; i < this->dependency_size(); i++) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->dependency(i).data(), this->dependency(i).length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 3, this->dependency(i), output);
+ }
+
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ for (int i = 0; i < this->message_type_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 4, this->message_type(i), output);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ for (int i = 0; i < this->enum_type_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 5, this->enum_type(i), output);
+ }
+
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ for (int i = 0; i < this->service_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 6, this->service(i), output);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ for (int i = 0; i < this->extension_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 7, this->extension(i), output);
+ }
+
+ // optional .google.protobuf.FileOptions options = 8;
+ if (has_options()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 8, this->options(), output);
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (has_source_code_info()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 9, this->source_code_info(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // optional string package = 2;
+ if (has_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->package().data(), this->package().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 2, this->package(), target);
+ }
+
+ // repeated string dependency = 3;
+ for (int i = 0; i < this->dependency_size(); i++) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->dependency(i).data(), this->dependency(i).length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteStringToArray(3, this->dependency(i), target);
+ }
+
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ for (int i = 0; i < this->message_type_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 4, this->message_type(i), target);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ for (int i = 0; i < this->enum_type_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 5, this->enum_type(i), target);
+ }
+
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ for (int i = 0; i < this->service_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 6, this->service(i), target);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ for (int i = 0; i < this->extension_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 7, this->extension(i), target);
+ }
+
+ // optional .google.protobuf.FileOptions options = 8;
+ if (has_options()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 8, this->options(), target);
+ }
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (has_source_code_info()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 9, this->source_code_info(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int FileDescriptorProto::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional string package = 2;
+ if (has_package()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->package());
+ }
+
+ // optional .google.protobuf.FileOptions options = 8;
+ if (has_options()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->options());
+ }
+
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ if (has_source_code_info()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->source_code_info());
+ }
+
+ }
+ // repeated string dependency = 3;
+ total_size += 1 * this->dependency_size();
+ for (int i = 0; i < this->dependency_size(); i++) {
+ total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->dependency(i));
+ }
+
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ total_size += 1 * this->message_type_size();
+ for (int i = 0; i < this->message_type_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->message_type(i));
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ total_size += 1 * this->enum_type_size();
+ for (int i = 0; i < this->enum_type_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->enum_type(i));
+ }
+
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ total_size += 1 * this->service_size();
+ for (int i = 0; i < this->service_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->service(i));
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ total_size += 1 * this->extension_size();
+ for (int i = 0; i < this->extension_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->extension(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const FileDescriptorProto* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorProto*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ dependency_.MergeFrom(from.dependency_);
+ message_type_.MergeFrom(from.message_type_);
+ enum_type_.MergeFrom(from.enum_type_);
+ service_.MergeFrom(from.service_);
+ extension_.MergeFrom(from.extension_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ if (from.has_package()) {
+ set_package(from.package());
+ }
+ if (from.has_options()) {
+ mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
+ }
+ }
+ if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (from.has_source_code_info()) {
+ mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FileDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FileDescriptorProto::IsInitialized() const {
+
+ for (int i = 0; i < message_type_size(); i++) {
+ if (!this->message_type(i).IsInitialized()) return false;
+ }
+ for (int i = 0; i < enum_type_size(); i++) {
+ if (!this->enum_type(i).IsInitialized()) return false;
+ }
+ for (int i = 0; i < service_size(); i++) {
+ if (!this->service(i).IsInitialized()) return false;
+ }
+ for (int i = 0; i < extension_size(); i++) {
+ if (!this->extension(i).IsInitialized()) return false;
+ }
+ if (has_options()) {
+ if (!this->options().IsInitialized()) return false;
+ }
+ return true;
+}
+
+void FileDescriptorProto::Swap(FileDescriptorProto* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ std::swap(package_, other->package_);
+ dependency_.Swap(&other->dependency_);
+ message_type_.Swap(&other->message_type_);
+ enum_type_.Swap(&other->enum_type_);
+ service_.Swap(&other->service_);
+ extension_.Swap(&other->extension_);
+ std::swap(options_, other->options_);
+ std::swap(source_code_info_, other->source_code_info_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = FileDescriptorProto_descriptor_;
+ metadata.reflection = FileDescriptorProto_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int DescriptorProto_ExtensionRange::kStartFieldNumber;
+const int DescriptorProto_ExtensionRange::kEndFieldNumber;
+#endif // !_MSC_VER
+
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void DescriptorProto_ExtensionRange::InitAsDefaultInstance() {
+}
+
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void DescriptorProto_ExtensionRange::SharedCtor() {
+ _cached_size_ = 0;
+ start_ = 0;
+ end_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
+ SharedDtor();
+}
+
+void DescriptorProto_ExtensionRange::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return DescriptorProto_ExtensionRange_descriptor_;
+}
+
+const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::default_instance_ = NULL;
+
+DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const {
+ return new DescriptorProto_ExtensionRange;
+}
+
+void DescriptorProto_ExtensionRange::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ start_ = 0;
+ end_ = 0;
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional int32 start = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &start_)));
+ set_has_start();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(16)) goto parse_end;
+ break;
+ }
+
+ // optional int32 end = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_end:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &end_)));
+ set_has_end();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional int32 start = 1;
+ if (has_start()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
+ }
+
+ // optional int32 end = 2;
+ if (has_end()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional int32 start = 1;
+ if (has_start()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
+ }
+
+ // optional int32 end = 2;
+ if (has_end()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int DescriptorProto_ExtensionRange::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional int32 start = 1;
+ if (has_start()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->start());
+ }
+
+ // optional int32 end = 2;
+ if (has_end()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->end());
+ }
+
+ }
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const DescriptorProto_ExtensionRange* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto_ExtensionRange*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_start()) {
+ set_start(from.start());
+ }
+ if (from.has_end()) {
+ set_end(from.end());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void DescriptorProto_ExtensionRange::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool DescriptorProto_ExtensionRange::IsInitialized() const {
+
+ return true;
+}
+
+void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) {
+ if (other != this) {
+ std::swap(start_, other->start_);
+ std::swap(end_, other->end_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = DescriptorProto_ExtensionRange_descriptor_;
+ metadata.reflection = DescriptorProto_ExtensionRange_reflection_;
+ return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int DescriptorProto::kNameFieldNumber;
+const int DescriptorProto::kFieldFieldNumber;
+const int DescriptorProto::kExtensionFieldNumber;
+const int DescriptorProto::kNestedTypeFieldNumber;
+const int DescriptorProto::kEnumTypeFieldNumber;
+const int DescriptorProto::kExtensionRangeFieldNumber;
+const int DescriptorProto::kOptionsFieldNumber;
+#endif // !_MSC_VER
+
+DescriptorProto::DescriptorProto()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void DescriptorProto::InitAsDefaultInstance() {
+ options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance());
+}
+
+DescriptorProto::DescriptorProto(const DescriptorProto& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void DescriptorProto::SharedCtor() {
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ options_ = NULL;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+DescriptorProto::~DescriptorProto() {
+ SharedDtor();
+}
+
+void DescriptorProto::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_;
+ }
+ if (this != default_instance_) {
+ delete options_;
+ }
+}
+
+void DescriptorProto::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return DescriptorProto_descriptor_;
+}
+
+const DescriptorProto& DescriptorProto::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+DescriptorProto* DescriptorProto::default_instance_ = NULL;
+
+DescriptorProto* DescriptorProto::New() const {
+ return new DescriptorProto;
+}
+
+void DescriptorProto::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ }
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
+ }
+ }
+ field_.Clear();
+ extension_.Clear();
+ nested_type_.Clear();
+ enum_type_.Clear();
+ extension_range_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool DescriptorProto::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_field;
+ break;
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto field = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_field:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_field()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_field;
+ if (input->ExpectTag(26)) goto parse_nested_type;
+ break;
+ }
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_nested_type:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_nested_type()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(26)) goto parse_nested_type;
+ if (input->ExpectTag(34)) goto parse_enum_type;
+ break;
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ case 4: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_enum_type:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_enum_type()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(34)) goto parse_enum_type;
+ if (input->ExpectTag(42)) goto parse_extension_range;
+ break;
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ case 5: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_extension_range:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_extension_range()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(42)) goto parse_extension_range;
+ if (input->ExpectTag(50)) goto parse_extension;
+ break;
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ case 6: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_extension:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_extension()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(50)) goto parse_extension;
+ if (input->ExpectTag(58)) goto parse_options;
+ break;
+ }
+
+ // optional .google.protobuf.MessageOptions options = 7;
+ case 7: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_options:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_options()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void DescriptorProto::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name(), output);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto field = 2;
+ for (int i = 0; i < this->field_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 2, this->field(i), output);
+ }
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ for (int i = 0; i < this->nested_type_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 3, this->nested_type(i), output);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ for (int i = 0; i < this->enum_type_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 4, this->enum_type(i), output);
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ for (int i = 0; i < this->extension_range_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 5, this->extension_range(i), output);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ for (int i = 0; i < this->extension_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 6, this->extension(i), output);
+ }
+
+ // optional .google.protobuf.MessageOptions options = 7;
+ if (has_options()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 7, this->options(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto field = 2;
+ for (int i = 0; i < this->field_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 2, this->field(i), target);
+ }
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ for (int i = 0; i < this->nested_type_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 3, this->nested_type(i), target);
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ for (int i = 0; i < this->enum_type_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 4, this->enum_type(i), target);
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ for (int i = 0; i < this->extension_range_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 5, this->extension_range(i), target);
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ for (int i = 0; i < this->extension_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 6, this->extension(i), target);
+ }
+
+ // optional .google.protobuf.MessageOptions options = 7;
+ if (has_options()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 7, this->options(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int DescriptorProto::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional .google.protobuf.MessageOptions options = 7;
+ if (has_options()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->options());
+ }
+
+ }
+ // repeated .google.protobuf.FieldDescriptorProto field = 2;
+ total_size += 1 * this->field_size();
+ for (int i = 0; i < this->field_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->field(i));
+ }
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ total_size += 1 * this->extension_size();
+ for (int i = 0; i < this->extension_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->extension(i));
+ }
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ total_size += 1 * this->nested_type_size();
+ for (int i = 0; i < this->nested_type_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->nested_type(i));
+ }
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ total_size += 1 * this->enum_type_size();
+ for (int i = 0; i < this->enum_type_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->enum_type(i));
+ }
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ total_size += 1 * this->extension_range_size();
+ for (int i = 0; i < this->extension_range_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->extension_range(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const DescriptorProto* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void DescriptorProto::MergeFrom(const DescriptorProto& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ field_.MergeFrom(from.field_);
+ extension_.MergeFrom(from.extension_);
+ nested_type_.MergeFrom(from.nested_type_);
+ enum_type_.MergeFrom(from.enum_type_);
+ extension_range_.MergeFrom(from.extension_range_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ if (from.has_options()) {
+ mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void DescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void DescriptorProto::CopyFrom(const DescriptorProto& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool DescriptorProto::IsInitialized() const {
+
+ for (int i = 0; i < field_size(); i++) {
+ if (!this->field(i).IsInitialized()) return false;
+ }
+ for (int i = 0; i < extension_size(); i++) {
+ if (!this->extension(i).IsInitialized()) return false;
+ }
+ for (int i = 0; i < nested_type_size(); i++) {
+ if (!this->nested_type(i).IsInitialized()) return false;
+ }
+ for (int i = 0; i < enum_type_size(); i++) {
+ if (!this->enum_type(i).IsInitialized()) return false;
+ }
+ if (has_options()) {
+ if (!this->options().IsInitialized()) return false;
+ }
+ return true;
+}
+
+void DescriptorProto::Swap(DescriptorProto* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ field_.Swap(&other->field_);
+ extension_.Swap(&other->extension_);
+ nested_type_.Swap(&other->nested_type_);
+ enum_type_.Swap(&other->enum_type_);
+ extension_range_.Swap(&other->extension_range_);
+ std::swap(options_, other->options_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata DescriptorProto::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = DescriptorProto_descriptor_;
+ metadata.reflection = DescriptorProto_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FieldDescriptorProto_Type_descriptor_;
+}
+bool FieldDescriptorProto_Type_IsValid(int value) {
+ switch(value) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
+const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
+const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
+const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
+const int FieldDescriptorProto::Type_ARRAYSIZE;
+#endif // _MSC_VER
+const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FieldDescriptorProto_Label_descriptor_;
+}
+bool FieldDescriptorProto_Label_IsValid(int value) {
+ switch(value) {
+ case 1:
+ case 2:
+ case 3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
+const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
+const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
+const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
+const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
+const int FieldDescriptorProto::Label_ARRAYSIZE;
+#endif // _MSC_VER
+#ifndef _MSC_VER
+const int FieldDescriptorProto::kNameFieldNumber;
+const int FieldDescriptorProto::kNumberFieldNumber;
+const int FieldDescriptorProto::kLabelFieldNumber;
+const int FieldDescriptorProto::kTypeFieldNumber;
+const int FieldDescriptorProto::kTypeNameFieldNumber;
+const int FieldDescriptorProto::kExtendeeFieldNumber;
+const int FieldDescriptorProto::kDefaultValueFieldNumber;
+const int FieldDescriptorProto::kOptionsFieldNumber;
+#endif // !_MSC_VER
+
+FieldDescriptorProto::FieldDescriptorProto()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void FieldDescriptorProto::InitAsDefaultInstance() {
+ options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance());
+}
+
+FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void FieldDescriptorProto::SharedCtor() {
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ number_ = 0;
+ label_ = 1;
+ type_ = 1;
+ type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ options_ = NULL;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FieldDescriptorProto::~FieldDescriptorProto() {
+ SharedDtor();
+}
+
+void FieldDescriptorProto::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_;
+ }
+ if (type_name_ != &::google::protobuf::internal::kEmptyString) {
+ delete type_name_;
+ }
+ if (extendee_ != &::google::protobuf::internal::kEmptyString) {
+ delete extendee_;
+ }
+ if (default_value_ != &::google::protobuf::internal::kEmptyString) {
+ delete default_value_;
+ }
+ if (this != default_instance_) {
+ delete options_;
+ }
+}
+
+void FieldDescriptorProto::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FieldDescriptorProto_descriptor_;
+}
+
+const FieldDescriptorProto& FieldDescriptorProto::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+FieldDescriptorProto* FieldDescriptorProto::default_instance_ = NULL;
+
+FieldDescriptorProto* FieldDescriptorProto::New() const {
+ return new FieldDescriptorProto;
+}
+
+void FieldDescriptorProto::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ }
+ number_ = 0;
+ label_ = 1;
+ type_ = 1;
+ if (has_type_name()) {
+ if (type_name_ != &::google::protobuf::internal::kEmptyString) {
+ type_name_->clear();
+ }
+ }
+ if (has_extendee()) {
+ if (extendee_ != &::google::protobuf::internal::kEmptyString) {
+ extendee_->clear();
+ }
+ }
+ if (has_default_value()) {
+ if (default_value_ != &::google::protobuf::internal::kEmptyString) {
+ default_value_->clear();
+ }
+ }
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
+ }
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool FieldDescriptorProto::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_extendee;
+ break;
+ }
+
+ // optional string extendee = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_extendee:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_extendee()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->extendee().data(), this->extendee().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(24)) goto parse_number;
+ break;
+ }
+
+ // optional int32 number = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_number:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &number_)));
+ set_has_number();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(32)) goto parse_label;
+ break;
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ case 4: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_label:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) {
+ set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value));
+ } else {
+ mutable_unknown_fields()->AddVarint(4, value);
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(40)) goto parse_type;
+ break;
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ case 5: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_type:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) {
+ set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value));
+ } else {
+ mutable_unknown_fields()->AddVarint(5, value);
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(50)) goto parse_type_name;
+ break;
+ }
+
+ // optional string type_name = 6;
+ case 6: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_type_name:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_type_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->type_name().data(), this->type_name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(58)) goto parse_default_value;
+ break;
+ }
+
+ // optional string default_value = 7;
+ case 7: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_default_value:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_default_value()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->default_value().data(), this->default_value().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(66)) goto parse_options;
+ break;
+ }
+
+ // optional .google.protobuf.FieldOptions options = 8;
+ case 8: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_options:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_options()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void FieldDescriptorProto::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name(), output);
+ }
+
+ // optional string extendee = 2;
+ if (has_extendee()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->extendee().data(), this->extendee().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 2, this->extendee(), output);
+ }
+
+ // optional int32 number = 3;
+ if (has_number()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output);
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ if (has_label()) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 4, this->label(), output);
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ if (has_type()) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 5, this->type(), output);
+ }
+
+ // optional string type_name = 6;
+ if (has_type_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->type_name().data(), this->type_name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 6, this->type_name(), output);
+ }
+
+ // optional string default_value = 7;
+ if (has_default_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->default_value().data(), this->default_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 7, this->default_value(), output);
+ }
+
+ // optional .google.protobuf.FieldOptions options = 8;
+ if (has_options()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 8, this->options(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // optional string extendee = 2;
+ if (has_extendee()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->extendee().data(), this->extendee().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 2, this->extendee(), target);
+ }
+
+ // optional int32 number = 3;
+ if (has_number()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target);
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ if (has_label()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 4, this->label(), target);
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ if (has_type()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 5, this->type(), target);
+ }
+
+ // optional string type_name = 6;
+ if (has_type_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->type_name().data(), this->type_name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 6, this->type_name(), target);
+ }
+
+ // optional string default_value = 7;
+ if (has_default_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->default_value().data(), this->default_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 7, this->default_value(), target);
+ }
+
+ // optional .google.protobuf.FieldOptions options = 8;
+ if (has_options()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 8, this->options(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int FieldDescriptorProto::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional int32 number = 3;
+ if (has_number()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->number());
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ if (has_label()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->label());
+ }
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ if (has_type()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
+ }
+
+ // optional string type_name = 6;
+ if (has_type_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->type_name());
+ }
+
+ // optional string extendee = 2;
+ if (has_extendee()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->extendee());
+ }
+
+ // optional string default_value = 7;
+ if (has_default_value()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->default_value());
+ }
+
+ // optional .google.protobuf.FieldOptions options = 8;
+ if (has_options()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->options());
+ }
+
+ }
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const FieldDescriptorProto* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const FieldDescriptorProto*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ if (from.has_number()) {
+ set_number(from.number());
+ }
+ if (from.has_label()) {
+ set_label(from.label());
+ }
+ if (from.has_type()) {
+ set_type(from.type());
+ }
+ if (from.has_type_name()) {
+ set_type_name(from.type_name());
+ }
+ if (from.has_extendee()) {
+ set_extendee(from.extendee());
+ }
+ if (from.has_default_value()) {
+ set_default_value(from.default_value());
+ }
+ if (from.has_options()) {
+ mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FieldDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FieldDescriptorProto::IsInitialized() const {
+
+ if (has_options()) {
+ if (!this->options().IsInitialized()) return false;
+ }
+ return true;
+}
+
+void FieldDescriptorProto::Swap(FieldDescriptorProto* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ std::swap(number_, other->number_);
+ std::swap(label_, other->label_);
+ std::swap(type_, other->type_);
+ std::swap(type_name_, other->type_name_);
+ std::swap(extendee_, other->extendee_);
+ std::swap(default_value_, other->default_value_);
+ std::swap(options_, other->options_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = FieldDescriptorProto_descriptor_;
+ metadata.reflection = FieldDescriptorProto_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int EnumDescriptorProto::kNameFieldNumber;
+const int EnumDescriptorProto::kValueFieldNumber;
+const int EnumDescriptorProto::kOptionsFieldNumber;
+#endif // !_MSC_VER
+
+EnumDescriptorProto::EnumDescriptorProto()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void EnumDescriptorProto::InitAsDefaultInstance() {
+ options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance());
+}
+
+EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void EnumDescriptorProto::SharedCtor() {
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ options_ = NULL;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+EnumDescriptorProto::~EnumDescriptorProto() {
+ SharedDtor();
+}
+
+void EnumDescriptorProto::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_;
+ }
+ if (this != default_instance_) {
+ delete options_;
+ }
+}
+
+void EnumDescriptorProto::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return EnumDescriptorProto_descriptor_;
+}
+
+const EnumDescriptorProto& EnumDescriptorProto::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+EnumDescriptorProto* EnumDescriptorProto::default_instance_ = NULL;
+
+EnumDescriptorProto* EnumDescriptorProto::New() const {
+ return new EnumDescriptorProto;
+}
+
+void EnumDescriptorProto::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ }
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
+ }
+ }
+ value_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool EnumDescriptorProto::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_value;
+ break;
+ }
+
+ // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_value:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_value()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_value;
+ if (input->ExpectTag(26)) goto parse_options;
+ break;
+ }
+
+ // optional .google.protobuf.EnumOptions options = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_options:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_options()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void EnumDescriptorProto::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name(), output);
+ }
+
+ // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ for (int i = 0; i < this->value_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 2, this->value(i), output);
+ }
+
+ // optional .google.protobuf.EnumOptions options = 3;
+ if (has_options()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 3, this->options(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ for (int i = 0; i < this->value_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 2, this->value(i), target);
+ }
+
+ // optional .google.protobuf.EnumOptions options = 3;
+ if (has_options()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 3, this->options(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int EnumDescriptorProto::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional .google.protobuf.EnumOptions options = 3;
+ if (has_options()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->options());
+ }
+
+ }
+ // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ total_size += 1 * this->value_size();
+ for (int i = 0; i < this->value_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->value(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const EnumDescriptorProto* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const EnumDescriptorProto*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ value_.MergeFrom(from.value_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ if (from.has_options()) {
+ mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void EnumDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumDescriptorProto::IsInitialized() const {
+
+ for (int i = 0; i < value_size(); i++) {
+ if (!this->value(i).IsInitialized()) return false;
+ }
+ if (has_options()) {
+ if (!this->options().IsInitialized()) return false;
+ }
+ return true;
+}
+
+void EnumDescriptorProto::Swap(EnumDescriptorProto* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ value_.Swap(&other->value_);
+ std::swap(options_, other->options_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = EnumDescriptorProto_descriptor_;
+ metadata.reflection = EnumDescriptorProto_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int EnumValueDescriptorProto::kNameFieldNumber;
+const int EnumValueDescriptorProto::kNumberFieldNumber;
+const int EnumValueDescriptorProto::kOptionsFieldNumber;
+#endif // !_MSC_VER
+
+EnumValueDescriptorProto::EnumValueDescriptorProto()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void EnumValueDescriptorProto::InitAsDefaultInstance() {
+ options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance());
+}
+
+EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void EnumValueDescriptorProto::SharedCtor() {
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ number_ = 0;
+ options_ = NULL;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+EnumValueDescriptorProto::~EnumValueDescriptorProto() {
+ SharedDtor();
+}
+
+void EnumValueDescriptorProto::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_;
+ }
+ if (this != default_instance_) {
+ delete options_;
+ }
+}
+
+void EnumValueDescriptorProto::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return EnumValueDescriptorProto_descriptor_;
+}
+
+const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+EnumValueDescriptorProto* EnumValueDescriptorProto::default_instance_ = NULL;
+
+EnumValueDescriptorProto* EnumValueDescriptorProto::New() const {
+ return new EnumValueDescriptorProto;
+}
+
+void EnumValueDescriptorProto::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ }
+ number_ = 0;
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
+ }
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool EnumValueDescriptorProto::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(16)) goto parse_number;
+ break;
+ }
+
+ // optional int32 number = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_number:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &number_)));
+ set_has_number();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(26)) goto parse_options;
+ break;
+ }
+
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_options:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_options()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void EnumValueDescriptorProto::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name(), output);
+ }
+
+ // optional int32 number = 2;
+ if (has_number()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output);
+ }
+
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ if (has_options()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 3, this->options(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // optional int32 number = 2;
+ if (has_number()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target);
+ }
+
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ if (has_options()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 3, this->options(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int EnumValueDescriptorProto::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional int32 number = 2;
+ if (has_number()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->number());
+ }
+
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ if (has_options()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->options());
+ }
+
+ }
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const EnumValueDescriptorProto* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueDescriptorProto*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ if (from.has_number()) {
+ set_number(from.number());
+ }
+ if (from.has_options()) {
+ mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void EnumValueDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumValueDescriptorProto::IsInitialized() const {
+
+ if (has_options()) {
+ if (!this->options().IsInitialized()) return false;
+ }
+ return true;
+}
+
+void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ std::swap(number_, other->number_);
+ std::swap(options_, other->options_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = EnumValueDescriptorProto_descriptor_;
+ metadata.reflection = EnumValueDescriptorProto_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int ServiceDescriptorProto::kNameFieldNumber;
+const int ServiceDescriptorProto::kMethodFieldNumber;
+const int ServiceDescriptorProto::kOptionsFieldNumber;
+#endif // !_MSC_VER
+
+ServiceDescriptorProto::ServiceDescriptorProto()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void ServiceDescriptorProto::InitAsDefaultInstance() {
+ options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance());
+}
+
+ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void ServiceDescriptorProto::SharedCtor() {
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ options_ = NULL;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+ServiceDescriptorProto::~ServiceDescriptorProto() {
+ SharedDtor();
+}
+
+void ServiceDescriptorProto::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_;
+ }
+ if (this != default_instance_) {
+ delete options_;
+ }
+}
+
+void ServiceDescriptorProto::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return ServiceDescriptorProto_descriptor_;
+}
+
+const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+ServiceDescriptorProto* ServiceDescriptorProto::default_instance_ = NULL;
+
+ServiceDescriptorProto* ServiceDescriptorProto::New() const {
+ return new ServiceDescriptorProto;
+}
+
+void ServiceDescriptorProto::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ }
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
+ }
+ }
+ method_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool ServiceDescriptorProto::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_method;
+ break;
+ }
+
+ // repeated .google.protobuf.MethodDescriptorProto method = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_method:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_method()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_method;
+ if (input->ExpectTag(26)) goto parse_options;
+ break;
+ }
+
+ // optional .google.protobuf.ServiceOptions options = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_options:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_options()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void ServiceDescriptorProto::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name(), output);
+ }
+
+ // repeated .google.protobuf.MethodDescriptorProto method = 2;
+ for (int i = 0; i < this->method_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 2, this->method(i), output);
+ }
+
+ // optional .google.protobuf.ServiceOptions options = 3;
+ if (has_options()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 3, this->options(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // repeated .google.protobuf.MethodDescriptorProto method = 2;
+ for (int i = 0; i < this->method_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 2, this->method(i), target);
+ }
+
+ // optional .google.protobuf.ServiceOptions options = 3;
+ if (has_options()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 3, this->options(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int ServiceDescriptorProto::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional .google.protobuf.ServiceOptions options = 3;
+ if (has_options()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->options());
+ }
+
+ }
+ // repeated .google.protobuf.MethodDescriptorProto method = 2;
+ total_size += 1 * this->method_size();
+ for (int i = 0; i < this->method_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->method(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const ServiceDescriptorProto* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const ServiceDescriptorProto*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ method_.MergeFrom(from.method_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ if (from.has_options()) {
+ mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void ServiceDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool ServiceDescriptorProto::IsInitialized() const {
+
+ for (int i = 0; i < method_size(); i++) {
+ if (!this->method(i).IsInitialized()) return false;
+ }
+ if (has_options()) {
+ if (!this->options().IsInitialized()) return false;
+ }
+ return true;
+}
+
+void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ method_.Swap(&other->method_);
+ std::swap(options_, other->options_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = ServiceDescriptorProto_descriptor_;
+ metadata.reflection = ServiceDescriptorProto_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int MethodDescriptorProto::kNameFieldNumber;
+const int MethodDescriptorProto::kInputTypeFieldNumber;
+const int MethodDescriptorProto::kOutputTypeFieldNumber;
+const int MethodDescriptorProto::kOptionsFieldNumber;
+#endif // !_MSC_VER
+
+MethodDescriptorProto::MethodDescriptorProto()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void MethodDescriptorProto::InitAsDefaultInstance() {
+ options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance());
+}
+
+MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void MethodDescriptorProto::SharedCtor() {
+ _cached_size_ = 0;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ options_ = NULL;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+MethodDescriptorProto::~MethodDescriptorProto() {
+ SharedDtor();
+}
+
+void MethodDescriptorProto::SharedDtor() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_;
+ }
+ if (input_type_ != &::google::protobuf::internal::kEmptyString) {
+ delete input_type_;
+ }
+ if (output_type_ != &::google::protobuf::internal::kEmptyString) {
+ delete output_type_;
+ }
+ if (this != default_instance_) {
+ delete options_;
+ }
+}
+
+void MethodDescriptorProto::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return MethodDescriptorProto_descriptor_;
+}
+
+const MethodDescriptorProto& MethodDescriptorProto::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+MethodDescriptorProto* MethodDescriptorProto::default_instance_ = NULL;
+
+MethodDescriptorProto* MethodDescriptorProto::New() const {
+ return new MethodDescriptorProto;
+}
+
+void MethodDescriptorProto::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name()) {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ }
+ if (has_input_type()) {
+ if (input_type_ != &::google::protobuf::internal::kEmptyString) {
+ input_type_->clear();
+ }
+ }
+ if (has_output_type()) {
+ if (output_type_ != &::google::protobuf::internal::kEmptyString) {
+ output_type_->clear();
+ }
+ }
+ if (has_options()) {
+ if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
+ }
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool MethodDescriptorProto::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_input_type;
+ break;
+ }
+
+ // optional string input_type = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_input_type:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_input_type()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->input_type().data(), this->input_type().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(26)) goto parse_output_type;
+ break;
+ }
+
+ // optional string output_type = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_output_type:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_output_type()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->output_type().data(), this->output_type().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(34)) goto parse_options;
+ break;
+ }
+
+ // optional .google.protobuf.MethodOptions options = 4;
+ case 4: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_options:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, mutable_options()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void MethodDescriptorProto::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name(), output);
+ }
+
+ // optional string input_type = 2;
+ if (has_input_type()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->input_type().data(), this->input_type().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 2, this->input_type(), output);
+ }
+
+ // optional string output_type = 3;
+ if (has_output_type()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->output_type().data(), this->output_type().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 3, this->output_type(), output);
+ }
+
+ // optional .google.protobuf.MethodOptions options = 4;
+ if (has_options()) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 4, this->options(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string name = 1;
+ if (has_name()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // optional string input_type = 2;
+ if (has_input_type()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->input_type().data(), this->input_type().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 2, this->input_type(), target);
+ }
+
+ // optional string output_type = 3;
+ if (has_output_type()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->output_type().data(), this->output_type().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 3, this->output_type(), target);
+ }
+
+ // optional .google.protobuf.MethodOptions options = 4;
+ if (has_options()) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 4, this->options(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int MethodDescriptorProto::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string name = 1;
+ if (has_name()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional string input_type = 2;
+ if (has_input_type()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->input_type());
+ }
+
+ // optional string output_type = 3;
+ if (has_output_type()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->output_type());
+ }
+
+ // optional .google.protobuf.MethodOptions options = 4;
+ if (has_options()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->options());
+ }
+
+ }
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const MethodDescriptorProto* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const MethodDescriptorProto*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name()) {
+ set_name(from.name());
+ }
+ if (from.has_input_type()) {
+ set_input_type(from.input_type());
+ }
+ if (from.has_output_type()) {
+ set_output_type(from.output_type());
+ }
+ if (from.has_options()) {
+ mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void MethodDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool MethodDescriptorProto::IsInitialized() const {
+
+ if (has_options()) {
+ if (!this->options().IsInitialized()) return false;
+ }
+ return true;
+}
+
+void MethodDescriptorProto::Swap(MethodDescriptorProto* other) {
+ if (other != this) {
+ std::swap(name_, other->name_);
+ std::swap(input_type_, other->input_type_);
+ std::swap(output_type_, other->output_type_);
+ std::swap(options_, other->options_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = MethodDescriptorProto_descriptor_;
+ metadata.reflection = MethodDescriptorProto_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FileOptions_OptimizeMode_descriptor_;
+}
+bool FileOptions_OptimizeMode_IsValid(int value) {
+ switch(value) {
+ case 1:
+ case 2:
+ case 3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const FileOptions_OptimizeMode FileOptions::SPEED;
+const FileOptions_OptimizeMode FileOptions::CODE_SIZE;
+const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
+const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
+const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
+const int FileOptions::OptimizeMode_ARRAYSIZE;
+#endif // _MSC_VER
+#ifndef _MSC_VER
+const int FileOptions::kJavaPackageFieldNumber;
+const int FileOptions::kJavaOuterClassnameFieldNumber;
+const int FileOptions::kJavaMultipleFilesFieldNumber;
+const int FileOptions::kRetainUnknownFieldsFieldNumber;
+const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber;
+const int FileOptions::kOptimizeForFieldNumber;
+const int FileOptions::kCcGenericServicesFieldNumber;
+const int FileOptions::kJavaGenericServicesFieldNumber;
+const int FileOptions::kPyGenericServicesFieldNumber;
+const int FileOptions::kUninterpretedOptionFieldNumber;
+#endif // !_MSC_VER
+
+FileOptions::FileOptions()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void FileOptions::InitAsDefaultInstance() {
+}
+
+FileOptions::FileOptions(const FileOptions& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void FileOptions::SharedCtor() {
+ _cached_size_ = 0;
+ java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ java_multiple_files_ = false;
+ retain_unknown_fields_ = false;
+ java_generate_equals_and_hash_ = false;
+ optimize_for_ = 1;
+ cc_generic_services_ = false;
+ java_generic_services_ = false;
+ py_generic_services_ = false;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FileOptions::~FileOptions() {
+ SharedDtor();
+}
+
+void FileOptions::SharedDtor() {
+ if (java_package_ != &::google::protobuf::internal::kEmptyString) {
+ delete java_package_;
+ }
+ if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
+ delete java_outer_classname_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void FileOptions::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FileOptions::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FileOptions_descriptor_;
+}
+
+const FileOptions& FileOptions::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+FileOptions* FileOptions::default_instance_ = NULL;
+
+FileOptions* FileOptions::New() const {
+ return new FileOptions;
+}
+
+void FileOptions::Clear() {
+ _extensions_.Clear();
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_java_package()) {
+ if (java_package_ != &::google::protobuf::internal::kEmptyString) {
+ java_package_->clear();
+ }
+ }
+ if (has_java_outer_classname()) {
+ if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
+ java_outer_classname_->clear();
+ }
+ }
+ java_multiple_files_ = false;
+ retain_unknown_fields_ = false;
+ java_generate_equals_and_hash_ = false;
+ optimize_for_ = 1;
+ cc_generic_services_ = false;
+ java_generic_services_ = false;
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ py_generic_services_ = false;
+ }
+ uninterpreted_option_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool FileOptions::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string java_package = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_java_package()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->java_package().data(), this->java_package().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(66)) goto parse_java_outer_classname;
+ break;
+ }
+
+ // optional string java_outer_classname = 8;
+ case 8: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_java_outer_classname:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_java_outer_classname()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->java_outer_classname().data(), this->java_outer_classname().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(72)) goto parse_optimize_for;
+ break;
+ }
+
+ // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ case 9: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_optimize_for:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) {
+ set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
+ } else {
+ mutable_unknown_fields()->AddVarint(9, value);
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(80)) goto parse_java_multiple_files;
+ break;
+ }
+
+ // optional bool java_multiple_files = 10 [default = false];
+ case 10: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_java_multiple_files:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &java_multiple_files_)));
+ set_has_java_multiple_files();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(88)) goto parse_retain_unknown_fields;
+ break;
+ }
+
+ // optional bool retain_unknown_fields = 11 [default = false];
+ case 11: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_retain_unknown_fields:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &retain_unknown_fields_)));
+ set_has_retain_unknown_fields();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(128)) goto parse_cc_generic_services;
+ break;
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
+ case 16: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_cc_generic_services:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &cc_generic_services_)));
+ set_has_cc_generic_services();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(136)) goto parse_java_generic_services;
+ break;
+ }
+
+ // optional bool java_generic_services = 17 [default = false];
+ case 17: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_java_generic_services:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &java_generic_services_)));
+ set_has_java_generic_services();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(144)) goto parse_py_generic_services;
+ break;
+ }
+
+ // optional bool py_generic_services = 18 [default = false];
+ case 18: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_py_generic_services:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &py_generic_services_)));
+ set_has_py_generic_services();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(160)) goto parse_java_generate_equals_and_hash;
+ break;
+ }
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ case 20: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_java_generate_equals_and_hash:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &java_generate_equals_and_hash_)));
+ set_has_java_generate_equals_and_hash();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ break;
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_uninterpreted_option:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_uninterpreted_option()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ if ((8000u <= tag)) {
+ DO_(_extensions_.ParseField(tag, input, default_instance_,
+ mutable_unknown_fields()));
+ continue;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void FileOptions::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional string java_package = 1;
+ if (has_java_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->java_package().data(), this->java_package().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->java_package(), output);
+ }
+
+ // optional string java_outer_classname = 8;
+ if (has_java_outer_classname()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->java_outer_classname().data(), this->java_outer_classname().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 8, this->java_outer_classname(), output);
+ }
+
+ // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ if (has_optimize_for()) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 9, this->optimize_for(), output);
+ }
+
+ // optional bool java_multiple_files = 10 [default = false];
+ if (has_java_multiple_files()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
+ }
+
+ // optional bool retain_unknown_fields = 11 [default = false];
+ if (has_retain_unknown_fields()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(11, this->retain_unknown_fields(), output);
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
+ if (has_cc_generic_services()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
+ }
+
+ // optional bool java_generic_services = 17 [default = false];
+ if (has_java_generic_services()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
+ }
+
+ // optional bool py_generic_services = 18 [default = false];
+ if (has_py_generic_services()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
+ }
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 999, this->uninterpreted_option(i), output);
+ }
+
+ // Extension range [1000, 536870912)
+ _extensions_.SerializeWithCachedSizes(
+ 1000, 536870912, output);
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional string java_package = 1;
+ if (has_java_package()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->java_package().data(), this->java_package().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->java_package(), target);
+ }
+
+ // optional string java_outer_classname = 8;
+ if (has_java_outer_classname()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->java_outer_classname().data(), this->java_outer_classname().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 8, this->java_outer_classname(), target);
+ }
+
+ // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ if (has_optimize_for()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 9, this->optimize_for(), target);
+ }
+
+ // optional bool java_multiple_files = 10 [default = false];
+ if (has_java_multiple_files()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
+ }
+
+ // optional bool retain_unknown_fields = 11 [default = false];
+ if (has_retain_unknown_fields()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(11, this->retain_unknown_fields(), target);
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
+ if (has_cc_generic_services()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
+ }
+
+ // optional bool java_generic_services = 17 [default = false];
+ if (has_java_generic_services()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
+ }
+
+ // optional bool py_generic_services = 18 [default = false];
+ if (has_py_generic_services()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
+ }
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), target);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_.SerializeWithCachedSizesToArray(
+ 1000, 536870912, target);
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int FileOptions::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional string java_package = 1;
+ if (has_java_package()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->java_package());
+ }
+
+ // optional string java_outer_classname = 8;
+ if (has_java_outer_classname()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->java_outer_classname());
+ }
+
+ // optional bool java_multiple_files = 10 [default = false];
+ if (has_java_multiple_files()) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool retain_unknown_fields = 11 [default = false];
+ if (has_retain_unknown_fields()) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ if (has_java_generate_equals_and_hash()) {
+ total_size += 2 + 1;
+ }
+
+ // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ if (has_optimize_for()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for());
+ }
+
+ // optional bool cc_generic_services = 16 [default = false];
+ if (has_cc_generic_services()) {
+ total_size += 2 + 1;
+ }
+
+ // optional bool java_generic_services = 17 [default = false];
+ if (has_java_generic_services()) {
+ total_size += 2 + 1;
+ }
+
+ }
+ if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ // optional bool py_generic_services = 18 [default = false];
+ if (has_py_generic_services()) {
+ total_size += 2 + 1;
+ }
+
+ }
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->uninterpreted_option(i));
+ }
+
+ total_size += _extensions_.ByteSize();
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const FileOptions* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const FileOptions*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void FileOptions::MergeFrom(const FileOptions& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_java_package()) {
+ set_java_package(from.java_package());
+ }
+ if (from.has_java_outer_classname()) {
+ set_java_outer_classname(from.java_outer_classname());
+ }
+ if (from.has_java_multiple_files()) {
+ set_java_multiple_files(from.java_multiple_files());
+ }
+ if (from.has_retain_unknown_fields()) {
+ set_retain_unknown_fields(from.retain_unknown_fields());
+ }
+ if (from.has_java_generate_equals_and_hash()) {
+ set_java_generate_equals_and_hash(from.java_generate_equals_and_hash());
+ }
+ if (from.has_optimize_for()) {
+ set_optimize_for(from.optimize_for());
+ }
+ if (from.has_cc_generic_services()) {
+ set_cc_generic_services(from.cc_generic_services());
+ }
+ if (from.has_java_generic_services()) {
+ set_java_generic_services(from.java_generic_services());
+ }
+ }
+ if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+ if (from.has_py_generic_services()) {
+ set_py_generic_services(from.py_generic_services());
+ }
+ }
+ _extensions_.MergeFrom(from._extensions_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FileOptions::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void FileOptions::CopyFrom(const FileOptions& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FileOptions::IsInitialized() const {
+
+ for (int i = 0; i < uninterpreted_option_size(); i++) {
+ if (!this->uninterpreted_option(i).IsInitialized()) return false;
+ }
+
+ if (!_extensions_.IsInitialized()) return false; return true;
+}
+
+void FileOptions::Swap(FileOptions* other) {
+ if (other != this) {
+ std::swap(java_package_, other->java_package_);
+ std::swap(java_outer_classname_, other->java_outer_classname_);
+ std::swap(java_multiple_files_, other->java_multiple_files_);
+ std::swap(retain_unknown_fields_, other->retain_unknown_fields_);
+ std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_);
+ std::swap(optimize_for_, other->optimize_for_);
+ std::swap(cc_generic_services_, other->cc_generic_services_);
+ std::swap(java_generic_services_, other->java_generic_services_);
+ std::swap(py_generic_services_, other->py_generic_services_);
+ uninterpreted_option_.Swap(&other->uninterpreted_option_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ _extensions_.Swap(&other->_extensions_);
+ }
+}
+
+::google::protobuf::Metadata FileOptions::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = FileOptions_descriptor_;
+ metadata.reflection = FileOptions_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int MessageOptions::kMessageSetWireFormatFieldNumber;
+const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber;
+const int MessageOptions::kUninterpretedOptionFieldNumber;
+#endif // !_MSC_VER
+
+MessageOptions::MessageOptions()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void MessageOptions::InitAsDefaultInstance() {
+}
+
+MessageOptions::MessageOptions(const MessageOptions& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void MessageOptions::SharedCtor() {
+ _cached_size_ = 0;
+ message_set_wire_format_ = false;
+ no_standard_descriptor_accessor_ = false;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+MessageOptions::~MessageOptions() {
+ SharedDtor();
+}
+
+void MessageOptions::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void MessageOptions::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return MessageOptions_descriptor_;
+}
+
+const MessageOptions& MessageOptions::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+MessageOptions* MessageOptions::default_instance_ = NULL;
+
+MessageOptions* MessageOptions::New() const {
+ return new MessageOptions;
+}
+
+void MessageOptions::Clear() {
+ _extensions_.Clear();
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ message_set_wire_format_ = false;
+ no_standard_descriptor_accessor_ = false;
+ }
+ uninterpreted_option_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool MessageOptions::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional bool message_set_wire_format = 1 [default = false];
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &message_set_wire_format_)));
+ set_has_message_set_wire_format();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor;
+ break;
+ }
+
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_no_standard_descriptor_accessor:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &no_standard_descriptor_accessor_)));
+ set_has_no_standard_descriptor_accessor();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ break;
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_uninterpreted_option:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_uninterpreted_option()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ if ((8000u <= tag)) {
+ DO_(_extensions_.ParseField(tag, input, default_instance_,
+ mutable_unknown_fields()));
+ continue;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void MessageOptions::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional bool message_set_wire_format = 1 [default = false];
+ if (has_message_set_wire_format()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output);
+ }
+
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ if (has_no_standard_descriptor_accessor()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 999, this->uninterpreted_option(i), output);
+ }
+
+ // Extension range [1000, 536870912)
+ _extensions_.SerializeWithCachedSizes(
+ 1000, 536870912, output);
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional bool message_set_wire_format = 1 [default = false];
+ if (has_message_set_wire_format()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target);
+ }
+
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ if (has_no_standard_descriptor_accessor()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), target);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_.SerializeWithCachedSizesToArray(
+ 1000, 536870912, target);
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int MessageOptions::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional bool message_set_wire_format = 1 [default = false];
+ if (has_message_set_wire_format()) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ if (has_no_standard_descriptor_accessor()) {
+ total_size += 1 + 1;
+ }
+
+ }
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->uninterpreted_option(i));
+ }
+
+ total_size += _extensions_.ByteSize();
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const MessageOptions* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const MessageOptions*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void MessageOptions::MergeFrom(const MessageOptions& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_message_set_wire_format()) {
+ set_message_set_wire_format(from.message_set_wire_format());
+ }
+ if (from.has_no_standard_descriptor_accessor()) {
+ set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor());
+ }
+ }
+ _extensions_.MergeFrom(from._extensions_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void MessageOptions::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void MessageOptions::CopyFrom(const MessageOptions& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool MessageOptions::IsInitialized() const {
+
+ for (int i = 0; i < uninterpreted_option_size(); i++) {
+ if (!this->uninterpreted_option(i).IsInitialized()) return false;
+ }
+
+ if (!_extensions_.IsInitialized()) return false; return true;
+}
+
+void MessageOptions::Swap(MessageOptions* other) {
+ if (other != this) {
+ std::swap(message_set_wire_format_, other->message_set_wire_format_);
+ std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_);
+ uninterpreted_option_.Swap(&other->uninterpreted_option_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ _extensions_.Swap(&other->_extensions_);
+ }
+}
+
+::google::protobuf::Metadata MessageOptions::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = MessageOptions_descriptor_;
+ metadata.reflection = MessageOptions_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FieldOptions_CType_descriptor_;
+}
+bool FieldOptions_CType_IsValid(int value) {
+ switch(value) {
+ case 0:
+ case 1:
+ case 2:
+ return true;
+ default:
+ return false;
+ }
+}
+
+#ifndef _MSC_VER
+const FieldOptions_CType FieldOptions::STRING;
+const FieldOptions_CType FieldOptions::CORD;
+const FieldOptions_CType FieldOptions::STRING_PIECE;
+const FieldOptions_CType FieldOptions::CType_MIN;
+const FieldOptions_CType FieldOptions::CType_MAX;
+const int FieldOptions::CType_ARRAYSIZE;
+#endif // _MSC_VER
+#ifndef _MSC_VER
+const int FieldOptions::kCtypeFieldNumber;
+const int FieldOptions::kPackedFieldNumber;
+const int FieldOptions::kDeprecatedFieldNumber;
+const int FieldOptions::kExperimentalMapKeyFieldNumber;
+const int FieldOptions::kUninterpretedOptionFieldNumber;
+#endif // !_MSC_VER
+
+FieldOptions::FieldOptions()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void FieldOptions::InitAsDefaultInstance() {
+}
+
+FieldOptions::FieldOptions(const FieldOptions& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void FieldOptions::SharedCtor() {
+ _cached_size_ = 0;
+ ctype_ = 0;
+ packed_ = false;
+ deprecated_ = false;
+ experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FieldOptions::~FieldOptions() {
+ SharedDtor();
+}
+
+void FieldOptions::SharedDtor() {
+ if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
+ delete experimental_map_key_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void FieldOptions::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return FieldOptions_descriptor_;
+}
+
+const FieldOptions& FieldOptions::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+FieldOptions* FieldOptions::default_instance_ = NULL;
+
+FieldOptions* FieldOptions::New() const {
+ return new FieldOptions;
+}
+
+void FieldOptions::Clear() {
+ _extensions_.Clear();
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ ctype_ = 0;
+ packed_ = false;
+ deprecated_ = false;
+ if (has_experimental_map_key()) {
+ if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
+ experimental_map_key_->clear();
+ }
+ }
+ }
+ uninterpreted_option_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool FieldOptions::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ if (::google::protobuf::FieldOptions_CType_IsValid(value)) {
+ set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value));
+ } else {
+ mutable_unknown_fields()->AddVarint(1, value);
+ }
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(16)) goto parse_packed;
+ break;
+ }
+
+ // optional bool packed = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_packed:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &packed_)));
+ set_has_packed();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(24)) goto parse_deprecated;
+ break;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_deprecated:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &deprecated_)));
+ set_has_deprecated();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(74)) goto parse_experimental_map_key;
+ break;
+ }
+
+ // optional string experimental_map_key = 9;
+ case 9: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_experimental_map_key:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_experimental_map_key()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->experimental_map_key().data(), this->experimental_map_key().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ break;
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_uninterpreted_option:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_uninterpreted_option()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ if ((8000u <= tag)) {
+ DO_(_extensions_.ParseField(tag, input, default_instance_,
+ mutable_unknown_fields()));
+ continue;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void FieldOptions::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ if (has_ctype()) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 1, this->ctype(), output);
+ }
+
+ // optional bool packed = 2;
+ if (has_packed()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
+ }
+
+ // optional string experimental_map_key = 9;
+ if (has_experimental_map_key()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->experimental_map_key().data(), this->experimental_map_key().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 9, this->experimental_map_key(), output);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 999, this->uninterpreted_option(i), output);
+ }
+
+ // Extension range [1000, 536870912)
+ _extensions_.SerializeWithCachedSizes(
+ 1000, 536870912, output);
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ if (has_ctype()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 1, this->ctype(), target);
+ }
+
+ // optional bool packed = 2;
+ if (has_packed()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target);
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
+ }
+
+ // optional string experimental_map_key = 9;
+ if (has_experimental_map_key()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->experimental_map_key().data(), this->experimental_map_key().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 9, this->experimental_map_key(), target);
+ }
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), target);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_.SerializeWithCachedSizesToArray(
+ 1000, 536870912, target);
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int FieldOptions::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ if (has_ctype()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype());
+ }
+
+ // optional bool packed = 2;
+ if (has_packed()) {
+ total_size += 1 + 1;
+ }
+
+ // optional bool deprecated = 3 [default = false];
+ if (has_deprecated()) {
+ total_size += 1 + 1;
+ }
+
+ // optional string experimental_map_key = 9;
+ if (has_experimental_map_key()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->experimental_map_key());
+ }
+
+ }
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->uninterpreted_option(i));
+ }
+
+ total_size += _extensions_.ByteSize();
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const FieldOptions* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const FieldOptions*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void FieldOptions::MergeFrom(const FieldOptions& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_ctype()) {
+ set_ctype(from.ctype());
+ }
+ if (from.has_packed()) {
+ set_packed(from.packed());
+ }
+ if (from.has_deprecated()) {
+ set_deprecated(from.deprecated());
+ }
+ if (from.has_experimental_map_key()) {
+ set_experimental_map_key(from.experimental_map_key());
+ }
+ }
+ _extensions_.MergeFrom(from._extensions_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FieldOptions::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void FieldOptions::CopyFrom(const FieldOptions& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool FieldOptions::IsInitialized() const {
+
+ for (int i = 0; i < uninterpreted_option_size(); i++) {
+ if (!this->uninterpreted_option(i).IsInitialized()) return false;
+ }
+
+ if (!_extensions_.IsInitialized()) return false; return true;
+}
+
+void FieldOptions::Swap(FieldOptions* other) {
+ if (other != this) {
+ std::swap(ctype_, other->ctype_);
+ std::swap(packed_, other->packed_);
+ std::swap(deprecated_, other->deprecated_);
+ std::swap(experimental_map_key_, other->experimental_map_key_);
+ uninterpreted_option_.Swap(&other->uninterpreted_option_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ _extensions_.Swap(&other->_extensions_);
+ }
+}
+
+::google::protobuf::Metadata FieldOptions::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = FieldOptions_descriptor_;
+ metadata.reflection = FieldOptions_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int EnumOptions::kUninterpretedOptionFieldNumber;
+#endif // !_MSC_VER
+
+EnumOptions::EnumOptions()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void EnumOptions::InitAsDefaultInstance() {
+}
+
+EnumOptions::EnumOptions(const EnumOptions& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void EnumOptions::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+EnumOptions::~EnumOptions() {
+ SharedDtor();
+}
+
+void EnumOptions::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void EnumOptions::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return EnumOptions_descriptor_;
+}
+
+const EnumOptions& EnumOptions::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+EnumOptions* EnumOptions::default_instance_ = NULL;
+
+EnumOptions* EnumOptions::New() const {
+ return new EnumOptions;
+}
+
+void EnumOptions::Clear() {
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool EnumOptions::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_uninterpreted_option:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_uninterpreted_option()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ if ((8000u <= tag)) {
+ DO_(_extensions_.ParseField(tag, input, default_instance_,
+ mutable_unknown_fields()));
+ continue;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void EnumOptions::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 999, this->uninterpreted_option(i), output);
+ }
+
+ // Extension range [1000, 536870912)
+ _extensions_.SerializeWithCachedSizes(
+ 1000, 536870912, output);
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), target);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_.SerializeWithCachedSizesToArray(
+ 1000, 536870912, target);
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int EnumOptions::ByteSize() const {
+ int total_size = 0;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->uninterpreted_option(i));
+ }
+
+ total_size += _extensions_.ByteSize();
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const EnumOptions* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const EnumOptions*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void EnumOptions::MergeFrom(const EnumOptions& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ _extensions_.MergeFrom(from._extensions_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void EnumOptions::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void EnumOptions::CopyFrom(const EnumOptions& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumOptions::IsInitialized() const {
+
+ for (int i = 0; i < uninterpreted_option_size(); i++) {
+ if (!this->uninterpreted_option(i).IsInitialized()) return false;
+ }
+
+ if (!_extensions_.IsInitialized()) return false; return true;
+}
+
+void EnumOptions::Swap(EnumOptions* other) {
+ if (other != this) {
+ uninterpreted_option_.Swap(&other->uninterpreted_option_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ _extensions_.Swap(&other->_extensions_);
+ }
+}
+
+::google::protobuf::Metadata EnumOptions::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = EnumOptions_descriptor_;
+ metadata.reflection = EnumOptions_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int EnumValueOptions::kUninterpretedOptionFieldNumber;
+#endif // !_MSC_VER
+
+EnumValueOptions::EnumValueOptions()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void EnumValueOptions::InitAsDefaultInstance() {
+}
+
+EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void EnumValueOptions::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+EnumValueOptions::~EnumValueOptions() {
+ SharedDtor();
+}
+
+void EnumValueOptions::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void EnumValueOptions::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return EnumValueOptions_descriptor_;
+}
+
+const EnumValueOptions& EnumValueOptions::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+EnumValueOptions* EnumValueOptions::default_instance_ = NULL;
+
+EnumValueOptions* EnumValueOptions::New() const {
+ return new EnumValueOptions;
+}
+
+void EnumValueOptions::Clear() {
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool EnumValueOptions::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_uninterpreted_option:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_uninterpreted_option()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ if ((8000u <= tag)) {
+ DO_(_extensions_.ParseField(tag, input, default_instance_,
+ mutable_unknown_fields()));
+ continue;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void EnumValueOptions::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 999, this->uninterpreted_option(i), output);
+ }
+
+ // Extension range [1000, 536870912)
+ _extensions_.SerializeWithCachedSizes(
+ 1000, 536870912, output);
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), target);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_.SerializeWithCachedSizesToArray(
+ 1000, 536870912, target);
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int EnumValueOptions::ByteSize() const {
+ int total_size = 0;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->uninterpreted_option(i));
+ }
+
+ total_size += _extensions_.ByteSize();
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const EnumValueOptions* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueOptions*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ _extensions_.MergeFrom(from._extensions_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void EnumValueOptions::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void EnumValueOptions::CopyFrom(const EnumValueOptions& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool EnumValueOptions::IsInitialized() const {
+
+ for (int i = 0; i < uninterpreted_option_size(); i++) {
+ if (!this->uninterpreted_option(i).IsInitialized()) return false;
+ }
+
+ if (!_extensions_.IsInitialized()) return false; return true;
+}
+
+void EnumValueOptions::Swap(EnumValueOptions* other) {
+ if (other != this) {
+ uninterpreted_option_.Swap(&other->uninterpreted_option_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ _extensions_.Swap(&other->_extensions_);
+ }
+}
+
+::google::protobuf::Metadata EnumValueOptions::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = EnumValueOptions_descriptor_;
+ metadata.reflection = EnumValueOptions_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int ServiceOptions::kUninterpretedOptionFieldNumber;
+#endif // !_MSC_VER
+
+ServiceOptions::ServiceOptions()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void ServiceOptions::InitAsDefaultInstance() {
+}
+
+ServiceOptions::ServiceOptions(const ServiceOptions& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void ServiceOptions::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+ServiceOptions::~ServiceOptions() {
+ SharedDtor();
+}
+
+void ServiceOptions::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void ServiceOptions::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return ServiceOptions_descriptor_;
+}
+
+const ServiceOptions& ServiceOptions::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+ServiceOptions* ServiceOptions::default_instance_ = NULL;
+
+ServiceOptions* ServiceOptions::New() const {
+ return new ServiceOptions;
+}
+
+void ServiceOptions::Clear() {
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool ServiceOptions::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_uninterpreted_option:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_uninterpreted_option()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ if ((8000u <= tag)) {
+ DO_(_extensions_.ParseField(tag, input, default_instance_,
+ mutable_unknown_fields()));
+ continue;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void ServiceOptions::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 999, this->uninterpreted_option(i), output);
+ }
+
+ // Extension range [1000, 536870912)
+ _extensions_.SerializeWithCachedSizes(
+ 1000, 536870912, output);
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), target);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_.SerializeWithCachedSizesToArray(
+ 1000, 536870912, target);
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int ServiceOptions::ByteSize() const {
+ int total_size = 0;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->uninterpreted_option(i));
+ }
+
+ total_size += _extensions_.ByteSize();
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const ServiceOptions* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const ServiceOptions*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void ServiceOptions::MergeFrom(const ServiceOptions& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ _extensions_.MergeFrom(from._extensions_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void ServiceOptions::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void ServiceOptions::CopyFrom(const ServiceOptions& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool ServiceOptions::IsInitialized() const {
+
+ for (int i = 0; i < uninterpreted_option_size(); i++) {
+ if (!this->uninterpreted_option(i).IsInitialized()) return false;
+ }
+
+ if (!_extensions_.IsInitialized()) return false; return true;
+}
+
+void ServiceOptions::Swap(ServiceOptions* other) {
+ if (other != this) {
+ uninterpreted_option_.Swap(&other->uninterpreted_option_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ _extensions_.Swap(&other->_extensions_);
+ }
+}
+
+::google::protobuf::Metadata ServiceOptions::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = ServiceOptions_descriptor_;
+ metadata.reflection = ServiceOptions_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int MethodOptions::kUninterpretedOptionFieldNumber;
+#endif // !_MSC_VER
+
+MethodOptions::MethodOptions()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void MethodOptions::InitAsDefaultInstance() {
+}
+
+MethodOptions::MethodOptions(const MethodOptions& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void MethodOptions::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+MethodOptions::~MethodOptions() {
+ SharedDtor();
+}
+
+void MethodOptions::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void MethodOptions::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return MethodOptions_descriptor_;
+}
+
+const MethodOptions& MethodOptions::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+MethodOptions* MethodOptions::default_instance_ = NULL;
+
+MethodOptions* MethodOptions::New() const {
+ return new MethodOptions;
+}
+
+void MethodOptions::Clear() {
+ _extensions_.Clear();
+ uninterpreted_option_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool MethodOptions::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ case 999: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_uninterpreted_option:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_uninterpreted_option()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ if ((8000u <= tag)) {
+ DO_(_extensions_.ParseField(tag, input, default_instance_,
+ mutable_unknown_fields()));
+ continue;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void MethodOptions::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 999, this->uninterpreted_option(i), output);
+ }
+
+ // Extension range [1000, 536870912)
+ _extensions_.SerializeWithCachedSizes(
+ 1000, 536870912, output);
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 999, this->uninterpreted_option(i), target);
+ }
+
+ // Extension range [1000, 536870912)
+ target = _extensions_.SerializeWithCachedSizesToArray(
+ 1000, 536870912, target);
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int MethodOptions::ByteSize() const {
+ int total_size = 0;
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ total_size += 2 * this->uninterpreted_option_size();
+ for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->uninterpreted_option(i));
+ }
+
+ total_size += _extensions_.ByteSize();
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const MethodOptions* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const MethodOptions*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void MethodOptions::MergeFrom(const MethodOptions& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+ _extensions_.MergeFrom(from._extensions_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void MethodOptions::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void MethodOptions::CopyFrom(const MethodOptions& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool MethodOptions::IsInitialized() const {
+
+ for (int i = 0; i < uninterpreted_option_size(); i++) {
+ if (!this->uninterpreted_option(i).IsInitialized()) return false;
+ }
+
+ if (!_extensions_.IsInitialized()) return false; return true;
+}
+
+void MethodOptions::Swap(MethodOptions* other) {
+ if (other != this) {
+ uninterpreted_option_.Swap(&other->uninterpreted_option_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ _extensions_.Swap(&other->_extensions_);
+ }
+}
+
+::google::protobuf::Metadata MethodOptions::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = MethodOptions_descriptor_;
+ metadata.reflection = MethodOptions_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int UninterpretedOption_NamePart::kNamePartFieldNumber;
+const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
+#endif // !_MSC_VER
+
+UninterpretedOption_NamePart::UninterpretedOption_NamePart()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void UninterpretedOption_NamePart::InitAsDefaultInstance() {
+}
+
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void UninterpretedOption_NamePart::SharedCtor() {
+ _cached_size_ = 0;
+ name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ is_extension_ = false;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
+ SharedDtor();
+}
+
+void UninterpretedOption_NamePart::SharedDtor() {
+ if (name_part_ != &::google::protobuf::internal::kEmptyString) {
+ delete name_part_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void UninterpretedOption_NamePart::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return UninterpretedOption_NamePart_descriptor_;
+}
+
+const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+UninterpretedOption_NamePart* UninterpretedOption_NamePart::default_instance_ = NULL;
+
+UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const {
+ return new UninterpretedOption_NamePart;
+}
+
+void UninterpretedOption_NamePart::Clear() {
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (has_name_part()) {
+ if (name_part_ != &::google::protobuf::internal::kEmptyString) {
+ name_part_->clear();
+ }
+ }
+ is_extension_ = false;
+ }
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // required string name_part = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name_part()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name_part().data(), this->name_part().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(16)) goto parse_is_extension;
+ break;
+ }
+
+ // required bool is_extension = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_is_extension:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+ input, &is_extension_)));
+ set_has_is_extension();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void UninterpretedOption_NamePart::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // required string name_part = 1;
+ if (has_name_part()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name_part().data(), this->name_part().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 1, this->name_part(), output);
+ }
+
+ // required bool is_extension = 2;
+ if (has_is_extension()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // required string name_part = 1;
+ if (has_name_part()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->name_part().data(), this->name_part().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name_part(), target);
+ }
+
+ // required bool is_extension = 2;
+ if (has_is_extension()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int UninterpretedOption_NamePart::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ // required string name_part = 1;
+ if (has_name_part()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name_part());
+ }
+
+ // required bool is_extension = 2;
+ if (has_is_extension()) {
+ total_size += 1 + 1;
+ }
+
+ }
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const UninterpretedOption_NamePart* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const UninterpretedOption_NamePart*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+ if (from.has_name_part()) {
+ set_name_part(from.name_part());
+ }
+ if (from.has_is_extension()) {
+ set_is_extension(from.is_extension());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void UninterpretedOption_NamePart::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool UninterpretedOption_NamePart::IsInitialized() const {
+ if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
+
+ return true;
+}
+
+void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) {
+ if (other != this) {
+ std::swap(name_part_, other->name_part_);
+ std::swap(is_extension_, other->is_extension_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = UninterpretedOption_NamePart_descriptor_;
+ metadata.reflection = UninterpretedOption_NamePart_reflection_;
+ return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int UninterpretedOption::kNameFieldNumber;
+const int UninterpretedOption::kIdentifierValueFieldNumber;
+const int UninterpretedOption::kPositiveIntValueFieldNumber;
+const int UninterpretedOption::kNegativeIntValueFieldNumber;
+const int UninterpretedOption::kDoubleValueFieldNumber;
+const int UninterpretedOption::kStringValueFieldNumber;
+const int UninterpretedOption::kAggregateValueFieldNumber;
+#endif // !_MSC_VER
+
+UninterpretedOption::UninterpretedOption()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void UninterpretedOption::InitAsDefaultInstance() {
+}
+
+UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void UninterpretedOption::SharedCtor() {
+ _cached_size_ = 0;
+ identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ positive_int_value_ = GOOGLE_ULONGLONG(0);
+ negative_int_value_ = GOOGLE_LONGLONG(0);
+ double_value_ = 0;
+ string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+UninterpretedOption::~UninterpretedOption() {
+ SharedDtor();
+}
+
+void UninterpretedOption::SharedDtor() {
+ if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
+ delete identifier_value_;
+ }
+ if (string_value_ != &::google::protobuf::internal::kEmptyString) {
+ delete string_value_;
+ }
+ if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
+ delete aggregate_value_;
+ }
+ if (this != default_instance_) {
+ }
+}
+
+void UninterpretedOption::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return UninterpretedOption_descriptor_;
+}
+
+const UninterpretedOption& UninterpretedOption::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+UninterpretedOption* UninterpretedOption::default_instance_ = NULL;
+
+UninterpretedOption* UninterpretedOption::New() const {
+ return new UninterpretedOption;
+}
+
+void UninterpretedOption::Clear() {
+ if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ if (has_identifier_value()) {
+ if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
+ identifier_value_->clear();
+ }
+ }
+ positive_int_value_ = GOOGLE_ULONGLONG(0);
+ negative_int_value_ = GOOGLE_LONGLONG(0);
+ double_value_ = 0;
+ if (has_string_value()) {
+ if (string_value_ != &::google::protobuf::internal::kEmptyString) {
+ string_value_->clear();
+ }
+ }
+ if (has_aggregate_value()) {
+ if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_->clear();
+ }
+ }
+ }
+ name_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool UninterpretedOption::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_name:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_name()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_name;
+ if (input->ExpectTag(26)) goto parse_identifier_value;
+ break;
+ }
+
+ // optional string identifier_value = 3;
+ case 3: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_identifier_value:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_identifier_value()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->identifier_value().data(), this->identifier_value().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(32)) goto parse_positive_int_value;
+ break;
+ }
+
+ // optional uint64 positive_int_value = 4;
+ case 4: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_positive_int_value:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+ input, &positive_int_value_)));
+ set_has_positive_int_value();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(40)) goto parse_negative_int_value;
+ break;
+ }
+
+ // optional int64 negative_int_value = 5;
+ case 5: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_negative_int_value:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
+ input, &negative_int_value_)));
+ set_has_negative_int_value();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(49)) goto parse_double_value;
+ break;
+ }
+
+ // optional double double_value = 6;
+ case 6: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) {
+ parse_double_value:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+ input, &double_value_)));
+ set_has_double_value();
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(58)) goto parse_string_value;
+ break;
+ }
+
+ // optional bytes string_value = 7;
+ case 7: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_string_value:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+ input, this->mutable_string_value()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(66)) goto parse_aggregate_value;
+ break;
+ }
+
+ // optional string aggregate_value = 8;
+ case 8: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_aggregate_value:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_aggregate_value()));
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::PARSE);
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void UninterpretedOption::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ for (int i = 0; i < this->name_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 2, this->name(i), output);
+ }
+
+ // optional string identifier_value = 3;
+ if (has_identifier_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->identifier_value().data(), this->identifier_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 3, this->identifier_value(), output);
+ }
+
+ // optional uint64 positive_int_value = 4;
+ if (has_positive_int_value()) {
+ ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output);
+ }
+
+ // optional int64 negative_int_value = 5;
+ if (has_negative_int_value()) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output);
+ }
+
+ // optional double double_value = 6;
+ if (has_double_value()) {
+ ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output);
+ }
+
+ // optional bytes string_value = 7;
+ if (has_string_value()) {
+ ::google::protobuf::internal::WireFormatLite::WriteBytes(
+ 7, this->string_value(), output);
+ }
+
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ ::google::protobuf::internal::WireFormatLite::WriteString(
+ 8, this->aggregate_value(), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ for (int i = 0; i < this->name_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 2, this->name(i), target);
+ }
+
+ // optional string identifier_value = 3;
+ if (has_identifier_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->identifier_value().data(), this->identifier_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 3, this->identifier_value(), target);
+ }
+
+ // optional uint64 positive_int_value = 4;
+ if (has_positive_int_value()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target);
+ }
+
+ // optional int64 negative_int_value = 5;
+ if (has_negative_int_value()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target);
+ }
+
+ // optional double double_value = 6;
+ if (has_double_value()) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target);
+ }
+
+ // optional bytes string_value = 7;
+ if (has_string_value()) {
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
+ 7, this->string_value(), target);
+ }
+
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+ this->aggregate_value().data(), this->aggregate_value().length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE);
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 8, this->aggregate_value(), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int UninterpretedOption::ByteSize() const {
+ int total_size = 0;
+
+ if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ // optional string identifier_value = 3;
+ if (has_identifier_value()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->identifier_value());
+ }
+
+ // optional uint64 positive_int_value = 4;
+ if (has_positive_int_value()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::UInt64Size(
+ this->positive_int_value());
+ }
+
+ // optional int64 negative_int_value = 5;
+ if (has_negative_int_value()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int64Size(
+ this->negative_int_value());
+ }
+
+ // optional double double_value = 6;
+ if (has_double_value()) {
+ total_size += 1 + 8;
+ }
+
+ // optional bytes string_value = 7;
+ if (has_string_value()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::BytesSize(
+ this->string_value());
+ }
+
+ // optional string aggregate_value = 8;
+ if (has_aggregate_value()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->aggregate_value());
+ }
+
+ }
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ total_size += 1 * this->name_size();
+ for (int i = 0; i < this->name_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->name(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const UninterpretedOption* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const UninterpretedOption*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ name_.MergeFrom(from.name_);
+ if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+ if (from.has_identifier_value()) {
+ set_identifier_value(from.identifier_value());
+ }
+ if (from.has_positive_int_value()) {
+ set_positive_int_value(from.positive_int_value());
+ }
+ if (from.has_negative_int_value()) {
+ set_negative_int_value(from.negative_int_value());
+ }
+ if (from.has_double_value()) {
+ set_double_value(from.double_value());
+ }
+ if (from.has_string_value()) {
+ set_string_value(from.string_value());
+ }
+ if (from.has_aggregate_value()) {
+ set_aggregate_value(from.aggregate_value());
+ }
+ }
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void UninterpretedOption::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void UninterpretedOption::CopyFrom(const UninterpretedOption& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool UninterpretedOption::IsInitialized() const {
+
+ for (int i = 0; i < name_size(); i++) {
+ if (!this->name(i).IsInitialized()) return false;
+ }
+ return true;
+}
+
+void UninterpretedOption::Swap(UninterpretedOption* other) {
+ if (other != this) {
+ name_.Swap(&other->name_);
+ std::swap(identifier_value_, other->identifier_value_);
+ std::swap(positive_int_value_, other->positive_int_value_);
+ std::swap(negative_int_value_, other->negative_int_value_);
+ std::swap(double_value_, other->double_value_);
+ std::swap(string_value_, other->string_value_);
+ std::swap(aggregate_value_, other->aggregate_value_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata UninterpretedOption::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = UninterpretedOption_descriptor_;
+ metadata.reflection = UninterpretedOption_reflection_;
+ return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int SourceCodeInfo_Location::kPathFieldNumber;
+const int SourceCodeInfo_Location::kSpanFieldNumber;
+#endif // !_MSC_VER
+
+SourceCodeInfo_Location::SourceCodeInfo_Location()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void SourceCodeInfo_Location::InitAsDefaultInstance() {
+}
+
+SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo_Location::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SourceCodeInfo_Location::~SourceCodeInfo_Location() {
+ SharedDtor();
+}
+
+void SourceCodeInfo_Location::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void SourceCodeInfo_Location::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return SourceCodeInfo_Location_descriptor_;
+}
+
+const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL;
+
+SourceCodeInfo_Location* SourceCodeInfo_Location::New() const {
+ return new SourceCodeInfo_Location;
+}
+
+void SourceCodeInfo_Location::Clear() {
+ path_.Clear();
+ span_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool SourceCodeInfo_Location::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated int32 path = 1 [packed = true];
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, this->mutable_path())));
+ } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
+ == ::google::protobuf::internal::WireFormatLite::
+ WIRETYPE_VARINT) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ 1, 10, input, this->mutable_path())));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(18)) goto parse_span;
+ break;
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ case 2: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_span:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, this->mutable_span())));
+ } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
+ == ::google::protobuf::internal::WireFormatLite::
+ WIRETYPE_VARINT) {
+ DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ 1, 18, input, this->mutable_span())));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void SourceCodeInfo_Location::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated int32 path = 1 [packed = true];
+ if (this->path_size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(_path_cached_byte_size_);
+ }
+ for (int i = 0; i < this->path_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+ this->path(i), output);
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ if (this->span_size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(_span_cached_byte_size_);
+ }
+ for (int i = 0; i < this->span_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+ this->span(i), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated int32 path = 1 [packed = true];
+ if (this->path_size() > 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+ 1,
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ target);
+ target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+ _path_cached_byte_size_, target);
+ }
+ for (int i = 0; i < this->path_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteInt32NoTagToArray(this->path(i), target);
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ if (this->span_size() > 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+ 2,
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+ target);
+ target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+ _span_cached_byte_size_, target);
+ }
+ for (int i = 0; i < this->span_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteInt32NoTagToArray(this->span(i), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int SourceCodeInfo_Location::ByteSize() const {
+ int total_size = 0;
+
+ // repeated int32 path = 1 [packed = true];
+ {
+ int data_size = 0;
+ for (int i = 0; i < this->path_size(); i++) {
+ data_size += ::google::protobuf::internal::WireFormatLite::
+ Int32Size(this->path(i));
+ }
+ if (data_size > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+ }
+ _path_cached_byte_size_ = data_size;
+ total_size += data_size;
+ }
+
+ // repeated int32 span = 2 [packed = true];
+ {
+ int data_size = 0;
+ for (int i = 0; i < this->span_size(); i++) {
+ data_size += ::google::protobuf::internal::WireFormatLite::
+ Int32Size(this->span(i));
+ }
+ if (data_size > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+ }
+ _span_cached_byte_size_ = data_size;
+ total_size += data_size;
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const SourceCodeInfo_Location* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo_Location*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ path_.MergeFrom(from.path_);
+ span_.MergeFrom(from.span_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceCodeInfo_Location::IsInitialized() const {
+
+ return true;
+}
+
+void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) {
+ if (other != this) {
+ path_.Swap(&other->path_);
+ span_.Swap(&other->span_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = SourceCodeInfo_Location_descriptor_;
+ metadata.reflection = SourceCodeInfo_Location_reflection_;
+ return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int SourceCodeInfo::kLocationFieldNumber;
+#endif // !_MSC_VER
+
+SourceCodeInfo::SourceCodeInfo()
+ : ::google::protobuf::Message() {
+ SharedCtor();
+}
+
+void SourceCodeInfo::InitAsDefaultInstance() {
+}
+
+SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
+ : ::google::protobuf::Message() {
+ SharedCtor();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo::SharedCtor() {
+ _cached_size_ = 0;
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SourceCodeInfo::~SourceCodeInfo() {
+ SharedDtor();
+}
+
+void SourceCodeInfo::SharedDtor() {
+ if (this != default_instance_) {
+ }
+}
+
+void SourceCodeInfo::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return SourceCodeInfo_descriptor_;
+}
+
+const SourceCodeInfo& SourceCodeInfo::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ return *default_instance_;
+}
+
+SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL;
+
+SourceCodeInfo* SourceCodeInfo::New() const {
+ return new SourceCodeInfo;
+}
+
+void SourceCodeInfo::Clear() {
+ location_.Clear();
+ ::memset(_has_bits_, 0, sizeof(_has_bits_));
+ mutable_unknown_fields()->Clear();
+}
+
+bool SourceCodeInfo::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+ ::google::protobuf::uint32 tag;
+ while ((tag = input->ReadTag()) != 0) {
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ case 1: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ parse_location:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+ input, add_location()));
+ } else {
+ goto handle_uninterpreted;
+ }
+ if (input->ExpectTag(10)) goto parse_location;
+ if (input->ExpectAtEnd()) return true;
+ break;
+ }
+
+ default: {
+ handle_uninterpreted:
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ return true;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));
+ break;
+ }
+ }
+ }
+ return true;
+#undef DO_
+}
+
+void SourceCodeInfo::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ for (int i = 0; i < this->location_size(); i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, this->location(i), output);
+ }
+
+ if (!unknown_fields().empty()) {
+ ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(
+ unknown_fields(), output);
+ }
+}
+
+::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ for (int i = 0; i < this->location_size(); i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 1, this->location(i), target);
+ }
+
+ if (!unknown_fields().empty()) {
+ target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(
+ unknown_fields(), target);
+ }
+ return target;
+}
+
+int SourceCodeInfo::ByteSize() const {
+ int total_size = 0;
+
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ total_size += 1 * this->location_size();
+ for (int i = 0; i < this->location_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->location(i));
+ }
+
+ if (!unknown_fields().empty()) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(
+ unknown_fields());
+ }
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ const SourceCodeInfo* source =
+ ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo*>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
+ GOOGLE_CHECK_NE(&from, this);
+ location_.MergeFrom(from.location_);
+ mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool SourceCodeInfo::IsInitialized() const {
+
+ return true;
+}
+
+void SourceCodeInfo::Swap(SourceCodeInfo* other) {
+ if (other != this) {
+ location_.Swap(&other->location_);
+ std::swap(_has_bits_[0], other->_has_bits_[0]);
+ _unknown_fields_.Swap(&other->_unknown_fields_);
+ std::swap(_cached_size_, other->_cached_size_);
+ }
+}
+
+::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = SourceCodeInfo_descriptor_;
+ metadata.reflection = SourceCodeInfo_reflection_;
+ return metadata;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace protobuf
+} // namespace google
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor.pb.h b/src/third_party/protobuf/src/google/protobuf/descriptor.pb.h
new file mode 100644
index 0000000..1f91d79
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor.pb.h
@@ -0,0 +1,5256 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: google/protobuf/descriptor.proto
+
+#ifndef PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
+#define PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2004000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please update
+#error your headers.
+#endif
+#if 2004002 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers. Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/generated_message_reflection.h>
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+
+// Internal implementation detail -- do not call these.
+void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+class FileDescriptorSet;
+class FileDescriptorProto;
+class DescriptorProto;
+class DescriptorProto_ExtensionRange;
+class FieldDescriptorProto;
+class EnumDescriptorProto;
+class EnumValueDescriptorProto;
+class ServiceDescriptorProto;
+class MethodDescriptorProto;
+class FileOptions;
+class MessageOptions;
+class FieldOptions;
+class EnumOptions;
+class EnumValueOptions;
+class ServiceOptions;
+class MethodOptions;
+class UninterpretedOption;
+class UninterpretedOption_NamePart;
+class SourceCodeInfo;
+class SourceCodeInfo_Location;
+
+enum FieldDescriptorProto_Type {
+ FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
+ FieldDescriptorProto_Type_TYPE_FLOAT = 2,
+ FieldDescriptorProto_Type_TYPE_INT64 = 3,
+ FieldDescriptorProto_Type_TYPE_UINT64 = 4,
+ FieldDescriptorProto_Type_TYPE_INT32 = 5,
+ FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
+ FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
+ FieldDescriptorProto_Type_TYPE_BOOL = 8,
+ FieldDescriptorProto_Type_TYPE_STRING = 9,
+ FieldDescriptorProto_Type_TYPE_GROUP = 10,
+ FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
+ FieldDescriptorProto_Type_TYPE_BYTES = 12,
+ FieldDescriptorProto_Type_TYPE_UINT32 = 13,
+ FieldDescriptorProto_Type_TYPE_ENUM = 14,
+ FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
+ FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
+ FieldDescriptorProto_Type_TYPE_SINT32 = 17,
+ FieldDescriptorProto_Type_TYPE_SINT64 = 18
+};
+LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Type_IsValid(int value);
+const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
+const FieldDescriptorProto_Type FieldDescriptorProto_Type_Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
+const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor();
+inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) {
+ return ::google::protobuf::internal::NameOfEnum(
+ FieldDescriptorProto_Type_descriptor(), value);
+}
+inline bool FieldDescriptorProto_Type_Parse(
+ const ::std::string& name, FieldDescriptorProto_Type* value) {
+ return ::google::protobuf::internal::ParseNamedEnum<FieldDescriptorProto_Type>(
+ FieldDescriptorProto_Type_descriptor(), name, value);
+}
+enum FieldDescriptorProto_Label {
+ FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
+ FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
+ FieldDescriptorProto_Label_LABEL_REPEATED = 3
+};
+LIBPROTOBUF_EXPORT bool FieldDescriptorProto_Label_IsValid(int value);
+const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+const FieldDescriptorProto_Label FieldDescriptorProto_Label_Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
+const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor();
+inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) {
+ return ::google::protobuf::internal::NameOfEnum(
+ FieldDescriptorProto_Label_descriptor(), value);
+}
+inline bool FieldDescriptorProto_Label_Parse(
+ const ::std::string& name, FieldDescriptorProto_Label* value) {
+ return ::google::protobuf::internal::ParseNamedEnum<FieldDescriptorProto_Label>(
+ FieldDescriptorProto_Label_descriptor(), name, value);
+}
+enum FileOptions_OptimizeMode {
+ FileOptions_OptimizeMode_SPEED = 1,
+ FileOptions_OptimizeMode_CODE_SIZE = 2,
+ FileOptions_OptimizeMode_LITE_RUNTIME = 3
+};
+LIBPROTOBUF_EXPORT bool FileOptions_OptimizeMode_IsValid(int value);
+const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MIN = FileOptions_OptimizeMode_SPEED;
+const FileOptions_OptimizeMode FileOptions_OptimizeMode_OptimizeMode_MAX = FileOptions_OptimizeMode_LITE_RUNTIME;
+const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor();
+inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) {
+ return ::google::protobuf::internal::NameOfEnum(
+ FileOptions_OptimizeMode_descriptor(), value);
+}
+inline bool FileOptions_OptimizeMode_Parse(
+ const ::std::string& name, FileOptions_OptimizeMode* value) {
+ return ::google::protobuf::internal::ParseNamedEnum<FileOptions_OptimizeMode>(
+ FileOptions_OptimizeMode_descriptor(), name, value);
+}
+enum FieldOptions_CType {
+ FieldOptions_CType_STRING = 0,
+ FieldOptions_CType_CORD = 1,
+ FieldOptions_CType_STRING_PIECE = 2
+};
+LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value);
+const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING;
+const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE;
+const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor();
+inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) {
+ return ::google::protobuf::internal::NameOfEnum(
+ FieldOptions_CType_descriptor(), value);
+}
+inline bool FieldOptions_CType_Parse(
+ const ::std::string& name, FieldOptions_CType* value) {
+ return ::google::protobuf::internal::ParseNamedEnum<FieldOptions_CType>(
+ FieldOptions_CType_descriptor(), name, value);
+}
+// ===================================================================
+
+class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message {
+ public:
+ FileDescriptorSet();
+ virtual ~FileDescriptorSet();
+
+ FileDescriptorSet(const FileDescriptorSet& from);
+
+ inline FileDescriptorSet& operator=(const FileDescriptorSet& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const FileDescriptorSet& default_instance();
+
+ void Swap(FileDescriptorSet* other);
+
+ // implements Message ----------------------------------------------
+
+ FileDescriptorSet* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const FileDescriptorSet& from);
+ void MergeFrom(const FileDescriptorSet& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.FileDescriptorProto file = 1;
+ inline int file_size() const;
+ inline void clear_file();
+ static const int kFileFieldNumber = 1;
+ inline const ::google::protobuf::FileDescriptorProto& file(int index) const;
+ inline ::google::protobuf::FileDescriptorProto* mutable_file(int index);
+ inline ::google::protobuf::FileDescriptorProto* add_file();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+ file() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+ mutable_file();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
+ private:
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static FileDescriptorSet* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Message {
+ public:
+ FileDescriptorProto();
+ virtual ~FileDescriptorProto();
+
+ FileDescriptorProto(const FileDescriptorProto& from);
+
+ inline FileDescriptorProto& operator=(const FileDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const FileDescriptorProto& default_instance();
+
+ void Swap(FileDescriptorProto* other);
+
+ // implements Message ----------------------------------------------
+
+ FileDescriptorProto* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const FileDescriptorProto& from);
+ void MergeFrom(const FileDescriptorProto& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+
+ // optional string package = 2;
+ inline bool has_package() const;
+ inline void clear_package();
+ static const int kPackageFieldNumber = 2;
+ inline const ::std::string& package() const;
+ inline void set_package(const ::std::string& value);
+ inline void set_package(const char* value);
+ inline void set_package(const char* value, size_t size);
+ inline ::std::string* mutable_package();
+ inline ::std::string* release_package();
+
+ // repeated string dependency = 3;
+ inline int dependency_size() const;
+ inline void clear_dependency();
+ static const int kDependencyFieldNumber = 3;
+ inline const ::std::string& dependency(int index) const;
+ inline ::std::string* mutable_dependency(int index);
+ inline void set_dependency(int index, const ::std::string& value);
+ inline void set_dependency(int index, const char* value);
+ inline void set_dependency(int index, const char* value, size_t size);
+ inline ::std::string* add_dependency();
+ inline void add_dependency(const ::std::string& value);
+ inline void add_dependency(const char* value);
+ inline void add_dependency(const char* value, size_t size);
+ inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
+ inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
+
+ // repeated .google.protobuf.DescriptorProto message_type = 4;
+ inline int message_type_size() const;
+ inline void clear_message_type();
+ static const int kMessageTypeFieldNumber = 4;
+ inline const ::google::protobuf::DescriptorProto& message_type(int index) const;
+ inline ::google::protobuf::DescriptorProto* mutable_message_type(int index);
+ inline ::google::protobuf::DescriptorProto* add_message_type();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+ message_type() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+ mutable_message_type();
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+ inline int enum_type_size() const;
+ inline void clear_enum_type();
+ static const int kEnumTypeFieldNumber = 5;
+ inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
+ inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
+ inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+ enum_type() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+ mutable_enum_type();
+
+ // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+ inline int service_size() const;
+ inline void clear_service();
+ static const int kServiceFieldNumber = 6;
+ inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
+ inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
+ inline ::google::protobuf::ServiceDescriptorProto* add_service();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+ service() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
+ mutable_service();
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+ inline int extension_size() const;
+ inline void clear_extension();
+ static const int kExtensionFieldNumber = 7;
+ inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+ inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+ inline ::google::protobuf::FieldDescriptorProto* add_extension();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+ extension() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+ mutable_extension();
+
+ // optional .google.protobuf.FileOptions options = 8;
+ inline bool has_options() const;
+ inline void clear_options();
+ static const int kOptionsFieldNumber = 8;
+ inline const ::google::protobuf::FileOptions& options() const;
+ inline ::google::protobuf::FileOptions* mutable_options();
+ inline ::google::protobuf::FileOptions* release_options();
+
+ // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+ inline bool has_source_code_info() const;
+ inline void clear_source_code_info();
+ static const int kSourceCodeInfoFieldNumber = 9;
+ inline const ::google::protobuf::SourceCodeInfo& source_code_info() const;
+ inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
+ inline ::google::protobuf::SourceCodeInfo* release_source_code_info();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_package();
+ inline void clear_has_package();
+ inline void set_has_options();
+ inline void clear_has_options();
+ inline void set_has_source_code_info();
+ inline void clear_has_source_code_info();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_;
+ ::std::string* package_;
+ ::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
+ ::google::protobuf::FileOptions* options_;
+ ::google::protobuf::SourceCodeInfo* source_code_info_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static FileDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::protobuf::Message {
+ public:
+ DescriptorProto_ExtensionRange();
+ virtual ~DescriptorProto_ExtensionRange();
+
+ DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from);
+
+ inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const DescriptorProto_ExtensionRange& default_instance();
+
+ void Swap(DescriptorProto_ExtensionRange* other);
+
+ // implements Message ----------------------------------------------
+
+ DescriptorProto_ExtensionRange* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const DescriptorProto_ExtensionRange& from);
+ void MergeFrom(const DescriptorProto_ExtensionRange& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional int32 start = 1;
+ inline bool has_start() const;
+ inline void clear_start();
+ static const int kStartFieldNumber = 1;
+ inline ::google::protobuf::int32 start() const;
+ inline void set_start(::google::protobuf::int32 value);
+
+ // optional int32 end = 2;
+ inline bool has_end() const;
+ inline void clear_end();
+ static const int kEndFieldNumber = 2;
+ inline ::google::protobuf::int32 end() const;
+ inline void set_end(::google::protobuf::int32 value);
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
+ private:
+ inline void set_has_start();
+ inline void clear_has_start();
+ inline void set_has_end();
+ inline void clear_has_end();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::int32 start_;
+ ::google::protobuf::int32 end_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static DescriptorProto_ExtensionRange* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
+ public:
+ DescriptorProto();
+ virtual ~DescriptorProto();
+
+ DescriptorProto(const DescriptorProto& from);
+
+ inline DescriptorProto& operator=(const DescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const DescriptorProto& default_instance();
+
+ void Swap(DescriptorProto* other);
+
+ // implements Message ----------------------------------------------
+
+ DescriptorProto* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const DescriptorProto& from);
+ void MergeFrom(const DescriptorProto& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef DescriptorProto_ExtensionRange ExtensionRange;
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+
+ // repeated .google.protobuf.FieldDescriptorProto field = 2;
+ inline int field_size() const;
+ inline void clear_field();
+ static const int kFieldFieldNumber = 2;
+ inline const ::google::protobuf::FieldDescriptorProto& field(int index) const;
+ inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index);
+ inline ::google::protobuf::FieldDescriptorProto* add_field();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+ field() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+ mutable_field();
+
+ // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+ inline int extension_size() const;
+ inline void clear_extension();
+ static const int kExtensionFieldNumber = 6;
+ inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+ inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+ inline ::google::protobuf::FieldDescriptorProto* add_extension();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+ extension() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+ mutable_extension();
+
+ // repeated .google.protobuf.DescriptorProto nested_type = 3;
+ inline int nested_type_size() const;
+ inline void clear_nested_type();
+ static const int kNestedTypeFieldNumber = 3;
+ inline const ::google::protobuf::DescriptorProto& nested_type(int index) const;
+ inline ::google::protobuf::DescriptorProto* mutable_nested_type(int index);
+ inline ::google::protobuf::DescriptorProto* add_nested_type();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+ nested_type() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+ mutable_nested_type();
+
+ // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+ inline int enum_type_size() const;
+ inline void clear_enum_type();
+ static const int kEnumTypeFieldNumber = 4;
+ inline const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
+ inline ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
+ inline ::google::protobuf::EnumDescriptorProto* add_enum_type();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+ enum_type() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+ mutable_enum_type();
+
+ // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+ inline int extension_range_size() const;
+ inline void clear_extension_range();
+ static const int kExtensionRangeFieldNumber = 5;
+ inline const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const;
+ inline ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
+ inline ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+ extension_range() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
+ mutable_extension_range();
+
+ // optional .google.protobuf.MessageOptions options = 7;
+ inline bool has_options() const;
+ inline void clear_options();
+ static const int kOptionsFieldNumber = 7;
+ inline const ::google::protobuf::MessageOptions& options() const;
+ inline ::google::protobuf::MessageOptions* mutable_options();
+ inline ::google::protobuf::MessageOptions* release_options();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_;
+ ::google::protobuf::MessageOptions* options_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static DescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Message {
+ public:
+ FieldDescriptorProto();
+ virtual ~FieldDescriptorProto();
+
+ FieldDescriptorProto(const FieldDescriptorProto& from);
+
+ inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const FieldDescriptorProto& default_instance();
+
+ void Swap(FieldDescriptorProto* other);
+
+ // implements Message ----------------------------------------------
+
+ FieldDescriptorProto* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const FieldDescriptorProto& from);
+ void MergeFrom(const FieldDescriptorProto& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef FieldDescriptorProto_Type Type;
+ static const Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
+ static const Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
+ static const Type TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
+ static const Type TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
+ static const Type TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
+ static const Type TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
+ static const Type TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
+ static const Type TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
+ static const Type TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
+ static const Type TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
+ static const Type TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
+ static const Type TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
+ static const Type TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
+ static const Type TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
+ static const Type TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
+ static const Type TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
+ static const Type TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
+ static const Type TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
+ static inline bool Type_IsValid(int value) {
+ return FieldDescriptorProto_Type_IsValid(value);
+ }
+ static const Type Type_MIN =
+ FieldDescriptorProto_Type_Type_MIN;
+ static const Type Type_MAX =
+ FieldDescriptorProto_Type_Type_MAX;
+ static const int Type_ARRAYSIZE =
+ FieldDescriptorProto_Type_Type_ARRAYSIZE;
+ static inline const ::google::protobuf::EnumDescriptor*
+ Type_descriptor() {
+ return FieldDescriptorProto_Type_descriptor();
+ }
+ static inline const ::std::string& Type_Name(Type value) {
+ return FieldDescriptorProto_Type_Name(value);
+ }
+ static inline bool Type_Parse(const ::std::string& name,
+ Type* value) {
+ return FieldDescriptorProto_Type_Parse(name, value);
+ }
+
+ typedef FieldDescriptorProto_Label Label;
+ static const Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+ static const Label LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
+ static const Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
+ static inline bool Label_IsValid(int value) {
+ return FieldDescriptorProto_Label_IsValid(value);
+ }
+ static const Label Label_MIN =
+ FieldDescriptorProto_Label_Label_MIN;
+ static const Label Label_MAX =
+ FieldDescriptorProto_Label_Label_MAX;
+ static const int Label_ARRAYSIZE =
+ FieldDescriptorProto_Label_Label_ARRAYSIZE;
+ static inline const ::google::protobuf::EnumDescriptor*
+ Label_descriptor() {
+ return FieldDescriptorProto_Label_descriptor();
+ }
+ static inline const ::std::string& Label_Name(Label value) {
+ return FieldDescriptorProto_Label_Name(value);
+ }
+ static inline bool Label_Parse(const ::std::string& name,
+ Label* value) {
+ return FieldDescriptorProto_Label_Parse(name, value);
+ }
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+
+ // optional int32 number = 3;
+ inline bool has_number() const;
+ inline void clear_number();
+ static const int kNumberFieldNumber = 3;
+ inline ::google::protobuf::int32 number() const;
+ inline void set_number(::google::protobuf::int32 value);
+
+ // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+ inline bool has_label() const;
+ inline void clear_label();
+ static const int kLabelFieldNumber = 4;
+ inline ::google::protobuf::FieldDescriptorProto_Label label() const;
+ inline void set_label(::google::protobuf::FieldDescriptorProto_Label value);
+
+ // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+ inline bool has_type() const;
+ inline void clear_type();
+ static const int kTypeFieldNumber = 5;
+ inline ::google::protobuf::FieldDescriptorProto_Type type() const;
+ inline void set_type(::google::protobuf::FieldDescriptorProto_Type value);
+
+ // optional string type_name = 6;
+ inline bool has_type_name() const;
+ inline void clear_type_name();
+ static const int kTypeNameFieldNumber = 6;
+ inline const ::std::string& type_name() const;
+ inline void set_type_name(const ::std::string& value);
+ inline void set_type_name(const char* value);
+ inline void set_type_name(const char* value, size_t size);
+ inline ::std::string* mutable_type_name();
+ inline ::std::string* release_type_name();
+
+ // optional string extendee = 2;
+ inline bool has_extendee() const;
+ inline void clear_extendee();
+ static const int kExtendeeFieldNumber = 2;
+ inline const ::std::string& extendee() const;
+ inline void set_extendee(const ::std::string& value);
+ inline void set_extendee(const char* value);
+ inline void set_extendee(const char* value, size_t size);
+ inline ::std::string* mutable_extendee();
+ inline ::std::string* release_extendee();
+
+ // optional string default_value = 7;
+ inline bool has_default_value() const;
+ inline void clear_default_value();
+ static const int kDefaultValueFieldNumber = 7;
+ inline const ::std::string& default_value() const;
+ inline void set_default_value(const ::std::string& value);
+ inline void set_default_value(const char* value);
+ inline void set_default_value(const char* value, size_t size);
+ inline ::std::string* mutable_default_value();
+ inline ::std::string* release_default_value();
+
+ // optional .google.protobuf.FieldOptions options = 8;
+ inline bool has_options() const;
+ inline void clear_options();
+ static const int kOptionsFieldNumber = 8;
+ inline const ::google::protobuf::FieldOptions& options() const;
+ inline ::google::protobuf::FieldOptions* mutable_options();
+ inline ::google::protobuf::FieldOptions* release_options();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_number();
+ inline void clear_has_number();
+ inline void set_has_label();
+ inline void clear_has_label();
+ inline void set_has_type();
+ inline void clear_has_type();
+ inline void set_has_type_name();
+ inline void clear_has_type_name();
+ inline void set_has_extendee();
+ inline void clear_has_extendee();
+ inline void set_has_default_value();
+ inline void clear_has_default_value();
+ inline void set_has_options();
+ inline void clear_has_options();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_;
+ ::google::protobuf::int32 number_;
+ int label_;
+ ::std::string* type_name_;
+ ::std::string* extendee_;
+ ::std::string* default_value_;
+ ::google::protobuf::FieldOptions* options_;
+ int type_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static FieldDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Message {
+ public:
+ EnumDescriptorProto();
+ virtual ~EnumDescriptorProto();
+
+ EnumDescriptorProto(const EnumDescriptorProto& from);
+
+ inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const EnumDescriptorProto& default_instance();
+
+ void Swap(EnumDescriptorProto* other);
+
+ // implements Message ----------------------------------------------
+
+ EnumDescriptorProto* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const EnumDescriptorProto& from);
+ void MergeFrom(const EnumDescriptorProto& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+
+ // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+ inline int value_size() const;
+ inline void clear_value();
+ static const int kValueFieldNumber = 2;
+ inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
+ inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
+ inline ::google::protobuf::EnumValueDescriptorProto* add_value();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+ value() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
+ mutable_value();
+
+ // optional .google.protobuf.EnumOptions options = 3;
+ inline bool has_options() const;
+ inline void clear_options();
+ static const int kOptionsFieldNumber = 3;
+ inline const ::google::protobuf::EnumOptions& options() const;
+ inline ::google::protobuf::EnumOptions* mutable_options();
+ inline ::google::protobuf::EnumOptions* release_options();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
+ ::google::protobuf::EnumOptions* options_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static EnumDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::Message {
+ public:
+ EnumValueDescriptorProto();
+ virtual ~EnumValueDescriptorProto();
+
+ EnumValueDescriptorProto(const EnumValueDescriptorProto& from);
+
+ inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const EnumValueDescriptorProto& default_instance();
+
+ void Swap(EnumValueDescriptorProto* other);
+
+ // implements Message ----------------------------------------------
+
+ EnumValueDescriptorProto* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const EnumValueDescriptorProto& from);
+ void MergeFrom(const EnumValueDescriptorProto& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+
+ // optional int32 number = 2;
+ inline bool has_number() const;
+ inline void clear_number();
+ static const int kNumberFieldNumber = 2;
+ inline ::google::protobuf::int32 number() const;
+ inline void set_number(::google::protobuf::int32 value);
+
+ // optional .google.protobuf.EnumValueOptions options = 3;
+ inline bool has_options() const;
+ inline void clear_options();
+ static const int kOptionsFieldNumber = 3;
+ inline const ::google::protobuf::EnumValueOptions& options() const;
+ inline ::google::protobuf::EnumValueOptions* mutable_options();
+ inline ::google::protobuf::EnumValueOptions* release_options();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_number();
+ inline void clear_has_number();
+ inline void set_has_options();
+ inline void clear_has_options();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_;
+ ::google::protobuf::EnumValueOptions* options_;
+ ::google::protobuf::int32 number_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static EnumValueDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Message {
+ public:
+ ServiceDescriptorProto();
+ virtual ~ServiceDescriptorProto();
+
+ ServiceDescriptorProto(const ServiceDescriptorProto& from);
+
+ inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const ServiceDescriptorProto& default_instance();
+
+ void Swap(ServiceDescriptorProto* other);
+
+ // implements Message ----------------------------------------------
+
+ ServiceDescriptorProto* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const ServiceDescriptorProto& from);
+ void MergeFrom(const ServiceDescriptorProto& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+
+ // repeated .google.protobuf.MethodDescriptorProto method = 2;
+ inline int method_size() const;
+ inline void clear_method();
+ static const int kMethodFieldNumber = 2;
+ inline const ::google::protobuf::MethodDescriptorProto& method(int index) const;
+ inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index);
+ inline ::google::protobuf::MethodDescriptorProto* add_method();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+ method() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
+ mutable_method();
+
+ // optional .google.protobuf.ServiceOptions options = 3;
+ inline bool has_options() const;
+ inline void clear_options();
+ static const int kOptionsFieldNumber = 3;
+ inline const ::google::protobuf::ServiceOptions& options() const;
+ inline ::google::protobuf::ServiceOptions* mutable_options();
+ inline ::google::protobuf::ServiceOptions* release_options();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_options();
+ inline void clear_has_options();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
+ ::google::protobuf::ServiceOptions* options_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static ServiceDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Message {
+ public:
+ MethodDescriptorProto();
+ virtual ~MethodDescriptorProto();
+
+ MethodDescriptorProto(const MethodDescriptorProto& from);
+
+ inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const MethodDescriptorProto& default_instance();
+
+ void Swap(MethodDescriptorProto* other);
+
+ // implements Message ----------------------------------------------
+
+ MethodDescriptorProto* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const MethodDescriptorProto& from);
+ void MergeFrom(const MethodDescriptorProto& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ inline bool has_name() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 1;
+ inline const ::std::string& name() const;
+ inline void set_name(const ::std::string& value);
+ inline void set_name(const char* value);
+ inline void set_name(const char* value, size_t size);
+ inline ::std::string* mutable_name();
+ inline ::std::string* release_name();
+
+ // optional string input_type = 2;
+ inline bool has_input_type() const;
+ inline void clear_input_type();
+ static const int kInputTypeFieldNumber = 2;
+ inline const ::std::string& input_type() const;
+ inline void set_input_type(const ::std::string& value);
+ inline void set_input_type(const char* value);
+ inline void set_input_type(const char* value, size_t size);
+ inline ::std::string* mutable_input_type();
+ inline ::std::string* release_input_type();
+
+ // optional string output_type = 3;
+ inline bool has_output_type() const;
+ inline void clear_output_type();
+ static const int kOutputTypeFieldNumber = 3;
+ inline const ::std::string& output_type() const;
+ inline void set_output_type(const ::std::string& value);
+ inline void set_output_type(const char* value);
+ inline void set_output_type(const char* value, size_t size);
+ inline ::std::string* mutable_output_type();
+ inline ::std::string* release_output_type();
+
+ // optional .google.protobuf.MethodOptions options = 4;
+ inline bool has_options() const;
+ inline void clear_options();
+ static const int kOptionsFieldNumber = 4;
+ inline const ::google::protobuf::MethodOptions& options() const;
+ inline ::google::protobuf::MethodOptions* mutable_options();
+ inline ::google::protobuf::MethodOptions* release_options();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
+ private:
+ inline void set_has_name();
+ inline void clear_has_name();
+ inline void set_has_input_type();
+ inline void clear_has_input_type();
+ inline void set_has_output_type();
+ inline void clear_has_output_type();
+ inline void set_has_options();
+ inline void clear_has_options();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_;
+ ::std::string* input_type_;
+ ::std::string* output_type_;
+ ::google::protobuf::MethodOptions* options_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static MethodDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
+ public:
+ FileOptions();
+ virtual ~FileOptions();
+
+ FileOptions(const FileOptions& from);
+
+ inline FileOptions& operator=(const FileOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const FileOptions& default_instance();
+
+ void Swap(FileOptions* other);
+
+ // implements Message ----------------------------------------------
+
+ FileOptions* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const FileOptions& from);
+ void MergeFrom(const FileOptions& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef FileOptions_OptimizeMode OptimizeMode;
+ static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED;
+ static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE;
+ static const OptimizeMode LITE_RUNTIME = FileOptions_OptimizeMode_LITE_RUNTIME;
+ static inline bool OptimizeMode_IsValid(int value) {
+ return FileOptions_OptimizeMode_IsValid(value);
+ }
+ static const OptimizeMode OptimizeMode_MIN =
+ FileOptions_OptimizeMode_OptimizeMode_MIN;
+ static const OptimizeMode OptimizeMode_MAX =
+ FileOptions_OptimizeMode_OptimizeMode_MAX;
+ static const int OptimizeMode_ARRAYSIZE =
+ FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE;
+ static inline const ::google::protobuf::EnumDescriptor*
+ OptimizeMode_descriptor() {
+ return FileOptions_OptimizeMode_descriptor();
+ }
+ static inline const ::std::string& OptimizeMode_Name(OptimizeMode value) {
+ return FileOptions_OptimizeMode_Name(value);
+ }
+ static inline bool OptimizeMode_Parse(const ::std::string& name,
+ OptimizeMode* value) {
+ return FileOptions_OptimizeMode_Parse(name, value);
+ }
+
+ // accessors -------------------------------------------------------
+
+ // optional string java_package = 1;
+ inline bool has_java_package() const;
+ inline void clear_java_package();
+ static const int kJavaPackageFieldNumber = 1;
+ inline const ::std::string& java_package() const;
+ inline void set_java_package(const ::std::string& value);
+ inline void set_java_package(const char* value);
+ inline void set_java_package(const char* value, size_t size);
+ inline ::std::string* mutable_java_package();
+ inline ::std::string* release_java_package();
+
+ // optional string java_outer_classname = 8;
+ inline bool has_java_outer_classname() const;
+ inline void clear_java_outer_classname();
+ static const int kJavaOuterClassnameFieldNumber = 8;
+ inline const ::std::string& java_outer_classname() const;
+ inline void set_java_outer_classname(const ::std::string& value);
+ inline void set_java_outer_classname(const char* value);
+ inline void set_java_outer_classname(const char* value, size_t size);
+ inline ::std::string* mutable_java_outer_classname();
+ inline ::std::string* release_java_outer_classname();
+
+ // optional bool java_multiple_files = 10 [default = false];
+ inline bool has_java_multiple_files() const;
+ inline void clear_java_multiple_files();
+ static const int kJavaMultipleFilesFieldNumber = 10;
+ inline bool java_multiple_files() const;
+ inline void set_java_multiple_files(bool value);
+
+ // optional bool retain_unknown_fields = 11 [default = false];
+ inline bool has_retain_unknown_fields() const;
+ inline void clear_retain_unknown_fields();
+ static const int kRetainUnknownFieldsFieldNumber = 11;
+ inline bool retain_unknown_fields() const;
+ inline void set_retain_unknown_fields(bool value);
+
+ // optional bool java_generate_equals_and_hash = 20 [default = false];
+ inline bool has_java_generate_equals_and_hash() const;
+ inline void clear_java_generate_equals_and_hash();
+ static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
+ inline bool java_generate_equals_and_hash() const;
+ inline void set_java_generate_equals_and_hash(bool value);
+
+ // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+ inline bool has_optimize_for() const;
+ inline void clear_optimize_for();
+ static const int kOptimizeForFieldNumber = 9;
+ inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
+ inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
+
+ // optional bool cc_generic_services = 16 [default = false];
+ inline bool has_cc_generic_services() const;
+ inline void clear_cc_generic_services();
+ static const int kCcGenericServicesFieldNumber = 16;
+ inline bool cc_generic_services() const;
+ inline void set_cc_generic_services(bool value);
+
+ // optional bool java_generic_services = 17 [default = false];
+ inline bool has_java_generic_services() const;
+ inline void clear_java_generic_services();
+ static const int kJavaGenericServicesFieldNumber = 17;
+ inline bool java_generic_services() const;
+ inline void set_java_generic_services(bool value);
+
+ // optional bool py_generic_services = 18 [default = false];
+ inline bool has_py_generic_services() const;
+ inline void clear_py_generic_services();
+ static const int kPyGenericServicesFieldNumber = 18;
+ inline bool py_generic_services() const;
+ inline void set_py_generic_services(bool value);
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ inline int uninterpreted_option_size() const;
+ inline void clear_uninterpreted_option();
+ static const int kUninterpretedOptionFieldNumber = 999;
+ inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+ inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+ inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ mutable_uninterpreted_option();
+
+ GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
+ // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
+ private:
+ inline void set_has_java_package();
+ inline void clear_has_java_package();
+ inline void set_has_java_outer_classname();
+ inline void clear_has_java_outer_classname();
+ inline void set_has_java_multiple_files();
+ inline void clear_has_java_multiple_files();
+ inline void set_has_retain_unknown_fields();
+ inline void clear_has_retain_unknown_fields();
+ inline void set_has_java_generate_equals_and_hash();
+ inline void clear_has_java_generate_equals_and_hash();
+ inline void set_has_optimize_for();
+ inline void clear_has_optimize_for();
+ inline void set_has_cc_generic_services();
+ inline void clear_has_cc_generic_services();
+ inline void set_has_java_generic_services();
+ inline void clear_has_java_generic_services();
+ inline void set_has_py_generic_services();
+ inline void clear_has_py_generic_services();
+
+ ::google::protobuf::internal::ExtensionSet _extensions_;
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* java_package_;
+ ::std::string* java_outer_classname_;
+ bool java_multiple_files_;
+ bool retain_unknown_fields_;
+ bool java_generate_equals_and_hash_;
+ bool cc_generic_services_;
+ int optimize_for_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool java_generic_services_;
+ bool py_generic_services_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(10 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static FileOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
+ public:
+ MessageOptions();
+ virtual ~MessageOptions();
+
+ MessageOptions(const MessageOptions& from);
+
+ inline MessageOptions& operator=(const MessageOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const MessageOptions& default_instance();
+
+ void Swap(MessageOptions* other);
+
+ // implements Message ----------------------------------------------
+
+ MessageOptions* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const MessageOptions& from);
+ void MergeFrom(const MessageOptions& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional bool message_set_wire_format = 1 [default = false];
+ inline bool has_message_set_wire_format() const;
+ inline void clear_message_set_wire_format();
+ static const int kMessageSetWireFormatFieldNumber = 1;
+ inline bool message_set_wire_format() const;
+ inline void set_message_set_wire_format(bool value);
+
+ // optional bool no_standard_descriptor_accessor = 2 [default = false];
+ inline bool has_no_standard_descriptor_accessor() const;
+ inline void clear_no_standard_descriptor_accessor();
+ static const int kNoStandardDescriptorAccessorFieldNumber = 2;
+ inline bool no_standard_descriptor_accessor() const;
+ inline void set_no_standard_descriptor_accessor(bool value);
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ inline int uninterpreted_option_size() const;
+ inline void clear_uninterpreted_option();
+ static const int kUninterpretedOptionFieldNumber = 999;
+ inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+ inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+ inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ mutable_uninterpreted_option();
+
+ GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
+ // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
+ private:
+ inline void set_has_message_set_wire_format();
+ inline void clear_has_message_set_wire_format();
+ inline void set_has_no_standard_descriptor_accessor();
+ inline void clear_has_no_standard_descriptor_accessor();
+
+ ::google::protobuf::internal::ExtensionSet _extensions_;
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+ bool message_set_wire_format_;
+ bool no_standard_descriptor_accessor_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static MessageOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
+ public:
+ FieldOptions();
+ virtual ~FieldOptions();
+
+ FieldOptions(const FieldOptions& from);
+
+ inline FieldOptions& operator=(const FieldOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const FieldOptions& default_instance();
+
+ void Swap(FieldOptions* other);
+
+ // implements Message ----------------------------------------------
+
+ FieldOptions* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const FieldOptions& from);
+ void MergeFrom(const FieldOptions& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef FieldOptions_CType CType;
+ static const CType STRING = FieldOptions_CType_STRING;
+ static const CType CORD = FieldOptions_CType_CORD;
+ static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE;
+ static inline bool CType_IsValid(int value) {
+ return FieldOptions_CType_IsValid(value);
+ }
+ static const CType CType_MIN =
+ FieldOptions_CType_CType_MIN;
+ static const CType CType_MAX =
+ FieldOptions_CType_CType_MAX;
+ static const int CType_ARRAYSIZE =
+ FieldOptions_CType_CType_ARRAYSIZE;
+ static inline const ::google::protobuf::EnumDescriptor*
+ CType_descriptor() {
+ return FieldOptions_CType_descriptor();
+ }
+ static inline const ::std::string& CType_Name(CType value) {
+ return FieldOptions_CType_Name(value);
+ }
+ static inline bool CType_Parse(const ::std::string& name,
+ CType* value) {
+ return FieldOptions_CType_Parse(name, value);
+ }
+
+ // accessors -------------------------------------------------------
+
+ // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+ inline bool has_ctype() const;
+ inline void clear_ctype();
+ static const int kCtypeFieldNumber = 1;
+ inline ::google::protobuf::FieldOptions_CType ctype() const;
+ inline void set_ctype(::google::protobuf::FieldOptions_CType value);
+
+ // optional bool packed = 2;
+ inline bool has_packed() const;
+ inline void clear_packed();
+ static const int kPackedFieldNumber = 2;
+ inline bool packed() const;
+ inline void set_packed(bool value);
+
+ // optional bool deprecated = 3 [default = false];
+ inline bool has_deprecated() const;
+ inline void clear_deprecated();
+ static const int kDeprecatedFieldNumber = 3;
+ inline bool deprecated() const;
+ inline void set_deprecated(bool value);
+
+ // optional string experimental_map_key = 9;
+ inline bool has_experimental_map_key() const;
+ inline void clear_experimental_map_key();
+ static const int kExperimentalMapKeyFieldNumber = 9;
+ inline const ::std::string& experimental_map_key() const;
+ inline void set_experimental_map_key(const ::std::string& value);
+ inline void set_experimental_map_key(const char* value);
+ inline void set_experimental_map_key(const char* value, size_t size);
+ inline ::std::string* mutable_experimental_map_key();
+ inline ::std::string* release_experimental_map_key();
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ inline int uninterpreted_option_size() const;
+ inline void clear_uninterpreted_option();
+ static const int kUninterpretedOptionFieldNumber = 999;
+ inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+ inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+ inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ mutable_uninterpreted_option();
+
+ GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
+ // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
+ private:
+ inline void set_has_ctype();
+ inline void clear_has_ctype();
+ inline void set_has_packed();
+ inline void clear_has_packed();
+ inline void set_has_deprecated();
+ inline void clear_has_deprecated();
+ inline void set_has_experimental_map_key();
+ inline void clear_has_experimental_map_key();
+
+ ::google::protobuf::internal::ExtensionSet _extensions_;
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ int ctype_;
+ bool packed_;
+ bool deprecated_;
+ ::std::string* experimental_map_key_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static FieldOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
+ public:
+ EnumOptions();
+ virtual ~EnumOptions();
+
+ EnumOptions(const EnumOptions& from);
+
+ inline EnumOptions& operator=(const EnumOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const EnumOptions& default_instance();
+
+ void Swap(EnumOptions* other);
+
+ // implements Message ----------------------------------------------
+
+ EnumOptions* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const EnumOptions& from);
+ void MergeFrom(const EnumOptions& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ inline int uninterpreted_option_size() const;
+ inline void clear_uninterpreted_option();
+ static const int kUninterpretedOptionFieldNumber = 999;
+ inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+ inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+ inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ mutable_uninterpreted_option();
+
+ GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
+ // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
+ private:
+
+ ::google::protobuf::internal::ExtensionSet _extensions_;
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static EnumOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
+ public:
+ EnumValueOptions();
+ virtual ~EnumValueOptions();
+
+ EnumValueOptions(const EnumValueOptions& from);
+
+ inline EnumValueOptions& operator=(const EnumValueOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const EnumValueOptions& default_instance();
+
+ void Swap(EnumValueOptions* other);
+
+ // implements Message ----------------------------------------------
+
+ EnumValueOptions* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const EnumValueOptions& from);
+ void MergeFrom(const EnumValueOptions& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ inline int uninterpreted_option_size() const;
+ inline void clear_uninterpreted_option();
+ static const int kUninterpretedOptionFieldNumber = 999;
+ inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+ inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+ inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ mutable_uninterpreted_option();
+
+ GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
+ // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
+ private:
+
+ ::google::protobuf::internal::ExtensionSet _extensions_;
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static EnumValueOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
+ public:
+ ServiceOptions();
+ virtual ~ServiceOptions();
+
+ ServiceOptions(const ServiceOptions& from);
+
+ inline ServiceOptions& operator=(const ServiceOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const ServiceOptions& default_instance();
+
+ void Swap(ServiceOptions* other);
+
+ // implements Message ----------------------------------------------
+
+ ServiceOptions* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const ServiceOptions& from);
+ void MergeFrom(const ServiceOptions& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ inline int uninterpreted_option_size() const;
+ inline void clear_uninterpreted_option();
+ static const int kUninterpretedOptionFieldNumber = 999;
+ inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+ inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+ inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ mutable_uninterpreted_option();
+
+ GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
+ // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
+ private:
+
+ ::google::protobuf::internal::ExtensionSet _extensions_;
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static ServiceOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
+ public:
+ MethodOptions();
+ virtual ~MethodOptions();
+
+ MethodOptions(const MethodOptions& from);
+
+ inline MethodOptions& operator=(const MethodOptions& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const MethodOptions& default_instance();
+
+ void Swap(MethodOptions* other);
+
+ // implements Message ----------------------------------------------
+
+ MethodOptions* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const MethodOptions& from);
+ void MergeFrom(const MethodOptions& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+ inline int uninterpreted_option_size() const;
+ inline void clear_uninterpreted_option();
+ static const int kUninterpretedOptionFieldNumber = 999;
+ inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+ inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+ inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ mutable_uninterpreted_option();
+
+ GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
+ // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
+ private:
+
+ ::google::protobuf::internal::ExtensionSet _extensions_;
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static MethodOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message {
+ public:
+ UninterpretedOption_NamePart();
+ virtual ~UninterpretedOption_NamePart();
+
+ UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);
+
+ inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const UninterpretedOption_NamePart& default_instance();
+
+ void Swap(UninterpretedOption_NamePart* other);
+
+ // implements Message ----------------------------------------------
+
+ UninterpretedOption_NamePart* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const UninterpretedOption_NamePart& from);
+ void MergeFrom(const UninterpretedOption_NamePart& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // required string name_part = 1;
+ inline bool has_name_part() const;
+ inline void clear_name_part();
+ static const int kNamePartFieldNumber = 1;
+ inline const ::std::string& name_part() const;
+ inline void set_name_part(const ::std::string& value);
+ inline void set_name_part(const char* value);
+ inline void set_name_part(const char* value, size_t size);
+ inline ::std::string* mutable_name_part();
+ inline ::std::string* release_name_part();
+
+ // required bool is_extension = 2;
+ inline bool has_is_extension() const;
+ inline void clear_is_extension();
+ static const int kIsExtensionFieldNumber = 2;
+ inline bool is_extension() const;
+ inline void set_is_extension(bool value);
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
+ private:
+ inline void set_has_name_part();
+ inline void clear_has_name_part();
+ inline void set_has_is_extension();
+ inline void clear_has_is_extension();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::std::string* name_part_;
+ bool is_extension_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static UninterpretedOption_NamePart* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message {
+ public:
+ UninterpretedOption();
+ virtual ~UninterpretedOption();
+
+ UninterpretedOption(const UninterpretedOption& from);
+
+ inline UninterpretedOption& operator=(const UninterpretedOption& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const UninterpretedOption& default_instance();
+
+ void Swap(UninterpretedOption* other);
+
+ // implements Message ----------------------------------------------
+
+ UninterpretedOption* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const UninterpretedOption& from);
+ void MergeFrom(const UninterpretedOption& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef UninterpretedOption_NamePart NamePart;
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+ inline int name_size() const;
+ inline void clear_name();
+ static const int kNameFieldNumber = 2;
+ inline const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const;
+ inline ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index);
+ inline ::google::protobuf::UninterpretedOption_NamePart* add_name();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+ name() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
+ mutable_name();
+
+ // optional string identifier_value = 3;
+ inline bool has_identifier_value() const;
+ inline void clear_identifier_value();
+ static const int kIdentifierValueFieldNumber = 3;
+ inline const ::std::string& identifier_value() const;
+ inline void set_identifier_value(const ::std::string& value);
+ inline void set_identifier_value(const char* value);
+ inline void set_identifier_value(const char* value, size_t size);
+ inline ::std::string* mutable_identifier_value();
+ inline ::std::string* release_identifier_value();
+
+ // optional uint64 positive_int_value = 4;
+ inline bool has_positive_int_value() const;
+ inline void clear_positive_int_value();
+ static const int kPositiveIntValueFieldNumber = 4;
+ inline ::google::protobuf::uint64 positive_int_value() const;
+ inline void set_positive_int_value(::google::protobuf::uint64 value);
+
+ // optional int64 negative_int_value = 5;
+ inline bool has_negative_int_value() const;
+ inline void clear_negative_int_value();
+ static const int kNegativeIntValueFieldNumber = 5;
+ inline ::google::protobuf::int64 negative_int_value() const;
+ inline void set_negative_int_value(::google::protobuf::int64 value);
+
+ // optional double double_value = 6;
+ inline bool has_double_value() const;
+ inline void clear_double_value();
+ static const int kDoubleValueFieldNumber = 6;
+ inline double double_value() const;
+ inline void set_double_value(double value);
+
+ // optional bytes string_value = 7;
+ inline bool has_string_value() const;
+ inline void clear_string_value();
+ static const int kStringValueFieldNumber = 7;
+ inline const ::std::string& string_value() const;
+ inline void set_string_value(const ::std::string& value);
+ inline void set_string_value(const char* value);
+ inline void set_string_value(const void* value, size_t size);
+ inline ::std::string* mutable_string_value();
+ inline ::std::string* release_string_value();
+
+ // optional string aggregate_value = 8;
+ inline bool has_aggregate_value() const;
+ inline void clear_aggregate_value();
+ static const int kAggregateValueFieldNumber = 8;
+ inline const ::std::string& aggregate_value() const;
+ inline void set_aggregate_value(const ::std::string& value);
+ inline void set_aggregate_value(const char* value);
+ inline void set_aggregate_value(const char* value, size_t size);
+ inline ::std::string* mutable_aggregate_value();
+ inline ::std::string* release_aggregate_value();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
+ private:
+ inline void set_has_identifier_value();
+ inline void clear_has_identifier_value();
+ inline void set_has_positive_int_value();
+ inline void clear_has_positive_int_value();
+ inline void set_has_negative_int_value();
+ inline void clear_has_negative_int_value();
+ inline void set_has_double_value();
+ inline void clear_has_double_value();
+ inline void set_has_string_value();
+ inline void clear_has_string_value();
+ inline void set_has_aggregate_value();
+ inline void clear_has_aggregate_value();
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_;
+ ::std::string* identifier_value_;
+ ::google::protobuf::uint64 positive_int_value_;
+ ::google::protobuf::int64 negative_int_value_;
+ double double_value_;
+ ::std::string* string_value_;
+ ::std::string* aggregate_value_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static UninterpretedOption* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message {
+ public:
+ SourceCodeInfo_Location();
+ virtual ~SourceCodeInfo_Location();
+
+ SourceCodeInfo_Location(const SourceCodeInfo_Location& from);
+
+ inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const SourceCodeInfo_Location& default_instance();
+
+ void Swap(SourceCodeInfo_Location* other);
+
+ // implements Message ----------------------------------------------
+
+ SourceCodeInfo_Location* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const SourceCodeInfo_Location& from);
+ void MergeFrom(const SourceCodeInfo_Location& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // repeated int32 path = 1 [packed = true];
+ inline int path_size() const;
+ inline void clear_path();
+ static const int kPathFieldNumber = 1;
+ inline ::google::protobuf::int32 path(int index) const;
+ inline void set_path(int index, ::google::protobuf::int32 value);
+ inline void add_path(::google::protobuf::int32 value);
+ inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ path() const;
+ inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_path();
+
+ // repeated int32 span = 2 [packed = true];
+ inline int span_size() const;
+ inline void clear_span();
+ static const int kSpanFieldNumber = 2;
+ inline ::google::protobuf::int32 span(int index) const;
+ inline void set_span(int index, ::google::protobuf::int32 value);
+ inline void add_span(::google::protobuf::int32 value);
+ inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ span() const;
+ inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ mutable_span();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
+ private:
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
+ mutable int _path_cached_byte_size_;
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_;
+ mutable int _span_cached_byte_size_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static SourceCodeInfo_Location* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
+ public:
+ SourceCodeInfo();
+ virtual ~SourceCodeInfo();
+
+ SourceCodeInfo(const SourceCodeInfo& from);
+
+ inline SourceCodeInfo& operator=(const SourceCodeInfo& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+ return _unknown_fields_;
+ }
+
+ inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+ return &_unknown_fields_;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const SourceCodeInfo& default_instance();
+
+ void Swap(SourceCodeInfo* other);
+
+ // implements Message ----------------------------------------------
+
+ SourceCodeInfo* New() const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const SourceCodeInfo& from);
+ void MergeFrom(const SourceCodeInfo& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ typedef SourceCodeInfo_Location Location;
+
+ // accessors -------------------------------------------------------
+
+ // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+ inline int location_size() const;
+ inline void clear_location();
+ static const int kLocationFieldNumber = 1;
+ inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
+ inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
+ inline ::google::protobuf::SourceCodeInfo_Location* add_location();
+ inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+ location() const;
+ inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+ mutable_location();
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
+ private:
+
+ ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
+
+ mutable int _cached_size_;
+ ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32];
+
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+ void InitAsDefaultInstance();
+ static SourceCodeInfo* default_instance_;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+// FileDescriptorSet
+
+// repeated .google.protobuf.FileDescriptorProto file = 1;
+inline int FileDescriptorSet::file_size() const {
+ return file_.size();
+}
+inline void FileDescriptorSet::clear_file() {
+ file_.Clear();
+}
+inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
+ return file_.Get(index);
+}
+inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
+ return file_.Mutable(index);
+}
+inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
+ return file_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+FileDescriptorSet::file() const {
+ return file_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+FileDescriptorSet::mutable_file() {
+ return &file_;
+}
+
+// -------------------------------------------------------------------
+
+// FileDescriptorProto
+
+// optional string name = 1;
+inline bool FileDescriptorProto::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FileDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FileDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void FileDescriptorProto::clear_name() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& FileDescriptorProto::name() const {
+ return *name_;
+}
+inline void FileDescriptorProto::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void FileDescriptorProto::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void FileDescriptorProto::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FileDescriptorProto::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ return name_;
+}
+inline ::std::string* FileDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string package = 2;
+inline bool FileDescriptorProto::has_package() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FileDescriptorProto::set_has_package() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FileDescriptorProto::clear_has_package() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void FileDescriptorProto::clear_package() {
+ if (package_ != &::google::protobuf::internal::kEmptyString) {
+ package_->clear();
+ }
+ clear_has_package();
+}
+inline const ::std::string& FileDescriptorProto::package() const {
+ return *package_;
+}
+inline void FileDescriptorProto::set_package(const ::std::string& value) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
+ package_ = new ::std::string;
+ }
+ package_->assign(value);
+}
+inline void FileDescriptorProto::set_package(const char* value) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
+ package_ = new ::std::string;
+ }
+ package_->assign(value);
+}
+inline void FileDescriptorProto::set_package(const char* value, size_t size) {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
+ package_ = new ::std::string;
+ }
+ package_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FileDescriptorProto::mutable_package() {
+ set_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
+ package_ = new ::std::string;
+ }
+ return package_;
+}
+inline ::std::string* FileDescriptorProto::release_package() {
+ clear_has_package();
+ if (package_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = package_;
+ package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// repeated string dependency = 3;
+inline int FileDescriptorProto::dependency_size() const {
+ return dependency_.size();
+}
+inline void FileDescriptorProto::clear_dependency() {
+ dependency_.Clear();
+}
+inline const ::std::string& FileDescriptorProto::dependency(int index) const {
+ return dependency_.Get(index);
+}
+inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
+ return dependency_.Mutable(index);
+}
+inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
+ dependency_.Mutable(index)->assign(value);
+}
+inline void FileDescriptorProto::set_dependency(int index, const char* value) {
+ dependency_.Mutable(index)->assign(value);
+}
+inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) {
+ dependency_.Mutable(index)->assign(
+ reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FileDescriptorProto::add_dependency() {
+ return dependency_.Add();
+}
+inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
+ dependency_.Add()->assign(value);
+}
+inline void FileDescriptorProto::add_dependency(const char* value) {
+ dependency_.Add()->assign(value);
+}
+inline void FileDescriptorProto::add_dependency(const char* value, size_t size) {
+ dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+FileDescriptorProto::dependency() const {
+ return dependency_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+FileDescriptorProto::mutable_dependency() {
+ return &dependency_;
+}
+
+// repeated .google.protobuf.DescriptorProto message_type = 4;
+inline int FileDescriptorProto::message_type_size() const {
+ return message_type_.size();
+}
+inline void FileDescriptorProto::clear_message_type() {
+ message_type_.Clear();
+}
+inline const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
+ return message_type_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
+ return message_type_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
+ return message_type_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+FileDescriptorProto::message_type() const {
+ return message_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+FileDescriptorProto::mutable_message_type() {
+ return &message_type_;
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+inline int FileDescriptorProto::enum_type_size() const {
+ return enum_type_.size();
+}
+inline void FileDescriptorProto::clear_enum_type() {
+ enum_type_.Clear();
+}
+inline const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
+ return enum_type_.Get(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
+ return enum_type_.Mutable(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
+ return enum_type_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+FileDescriptorProto::enum_type() const {
+ return enum_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+FileDescriptorProto::mutable_enum_type() {
+ return &enum_type_;
+}
+
+// repeated .google.protobuf.ServiceDescriptorProto service = 6;
+inline int FileDescriptorProto::service_size() const {
+ return service_.size();
+}
+inline void FileDescriptorProto::clear_service() {
+ service_.Clear();
+}
+inline const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
+ return service_.Get(index);
+}
+inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
+ return service_.Mutable(index);
+}
+inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
+ return service_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+FileDescriptorProto::service() const {
+ return service_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
+FileDescriptorProto::mutable_service() {
+ return &service_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 7;
+inline int FileDescriptorProto::extension_size() const {
+ return extension_.size();
+}
+inline void FileDescriptorProto::clear_extension() {
+ extension_.Clear();
+}
+inline const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
+ return extension_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
+ return extension_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
+ return extension_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+FileDescriptorProto::extension() const {
+ return extension_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+FileDescriptorProto::mutable_extension() {
+ return &extension_;
+}
+
+// optional .google.protobuf.FileOptions options = 8;
+inline bool FileDescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FileDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void FileDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000080u;
+}
+inline void FileDescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
+ clear_has_options();
+}
+inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) options_ = new ::google::protobuf::FileOptions;
+ return options_;
+}
+inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::FileOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+
+// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+inline bool FileDescriptorProto::has_source_code_info() const {
+ return (_has_bits_[0] & 0x00000100u) != 0;
+}
+inline void FileDescriptorProto::set_has_source_code_info() {
+ _has_bits_[0] |= 0x00000100u;
+}
+inline void FileDescriptorProto::clear_has_source_code_info() {
+ _has_bits_[0] &= ~0x00000100u;
+}
+inline void FileDescriptorProto::clear_source_code_info() {
+ if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+ clear_has_source_code_info();
+}
+inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
+ return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_;
+}
+inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
+ set_has_source_code_info();
+ if (source_code_info_ == NULL) source_code_info_ = new ::google::protobuf::SourceCodeInfo;
+ return source_code_info_;
+}
+inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+ clear_has_source_code_info();
+ ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
+ source_code_info_ = NULL;
+ return temp;
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto_ExtensionRange
+
+// optional int32 start = 1;
+inline bool DescriptorProto_ExtensionRange::has_start() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void DescriptorProto_ExtensionRange::set_has_start() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void DescriptorProto_ExtensionRange::clear_has_start() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void DescriptorProto_ExtensionRange::clear_start() {
+ start_ = 0;
+ clear_has_start();
+}
+inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
+ return start_;
+}
+inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
+ set_has_start();
+ start_ = value;
+}
+
+// optional int32 end = 2;
+inline bool DescriptorProto_ExtensionRange::has_end() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void DescriptorProto_ExtensionRange::set_has_end() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void DescriptorProto_ExtensionRange::clear_has_end() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void DescriptorProto_ExtensionRange::clear_end() {
+ end_ = 0;
+ clear_has_end();
+}
+inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
+ return end_;
+}
+inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
+ set_has_end();
+ end_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto
+
+// optional string name = 1;
+inline bool DescriptorProto::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void DescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void DescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void DescriptorProto::clear_name() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& DescriptorProto::name() const {
+ return *name_;
+}
+inline void DescriptorProto::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void DescriptorProto::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void DescriptorProto::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* DescriptorProto::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ return name_;
+}
+inline ::std::string* DescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// repeated .google.protobuf.FieldDescriptorProto field = 2;
+inline int DescriptorProto::field_size() const {
+ return field_.size();
+}
+inline void DescriptorProto::clear_field() {
+ field_.Clear();
+}
+inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const {
+ return field_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
+ return field_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
+ return field_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::field() const {
+ return field_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+DescriptorProto::mutable_field() {
+ return &field_;
+}
+
+// repeated .google.protobuf.FieldDescriptorProto extension = 6;
+inline int DescriptorProto::extension_size() const {
+ return extension_.size();
+}
+inline void DescriptorProto::clear_extension() {
+ extension_.Clear();
+}
+inline const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const {
+ return extension_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
+ return extension_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
+ return extension_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::extension() const {
+ return extension_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+DescriptorProto::mutable_extension() {
+ return &extension_;
+}
+
+// repeated .google.protobuf.DescriptorProto nested_type = 3;
+inline int DescriptorProto::nested_type_size() const {
+ return nested_type_.size();
+}
+inline void DescriptorProto::clear_nested_type() {
+ nested_type_.Clear();
+}
+inline const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const {
+ return nested_type_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
+ return nested_type_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
+ return nested_type_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+DescriptorProto::nested_type() const {
+ return nested_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+DescriptorProto::mutable_nested_type() {
+ return &nested_type_;
+}
+
+// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+inline int DescriptorProto::enum_type_size() const {
+ return enum_type_.size();
+}
+inline void DescriptorProto::clear_enum_type() {
+ enum_type_.Clear();
+}
+inline const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
+ return enum_type_.Get(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
+ return enum_type_.Mutable(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
+ return enum_type_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+DescriptorProto::enum_type() const {
+ return enum_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+DescriptorProto::mutable_enum_type() {
+ return &enum_type_;
+}
+
+// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+inline int DescriptorProto::extension_range_size() const {
+ return extension_range_.size();
+}
+inline void DescriptorProto::clear_extension_range() {
+ extension_range_.Clear();
+}
+inline const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
+ return extension_range_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
+ return extension_range_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
+ return extension_range_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+DescriptorProto::extension_range() const {
+ return extension_range_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
+DescriptorProto::mutable_extension_range() {
+ return &extension_range_;
+}
+
+// optional .google.protobuf.MessageOptions options = 7;
+inline bool DescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void DescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void DescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline void DescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
+ clear_has_options();
+}
+inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions;
+ return options_;
+}
+inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::MessageOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+
+// -------------------------------------------------------------------
+
+// FieldDescriptorProto
+
+// optional string name = 1;
+inline bool FieldDescriptorProto::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void FieldDescriptorProto::clear_name() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& FieldDescriptorProto::name() const {
+ return *name_;
+}
+inline void FieldDescriptorProto::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void FieldDescriptorProto::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void FieldDescriptorProto::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FieldDescriptorProto::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ return name_;
+}
+inline ::std::string* FieldDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional int32 number = 3;
+inline bool FieldDescriptorProto::has_number() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldDescriptorProto::set_has_number() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldDescriptorProto::clear_has_number() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void FieldDescriptorProto::clear_number() {
+ number_ = 0;
+ clear_has_number();
+}
+inline ::google::protobuf::int32 FieldDescriptorProto::number() const {
+ return number_;
+}
+inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
+ set_has_number();
+ number_ = value;
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+inline bool FieldDescriptorProto::has_label() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldDescriptorProto::set_has_label() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldDescriptorProto::clear_has_label() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void FieldDescriptorProto::clear_label() {
+ label_ = 1;
+ clear_has_label();
+}
+inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
+ return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
+}
+inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
+ GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
+ set_has_label();
+ label_ = value;
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+inline bool FieldDescriptorProto::has_type() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldDescriptorProto::set_has_type() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldDescriptorProto::clear_has_type() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void FieldDescriptorProto::clear_type() {
+ type_ = 1;
+ clear_has_type();
+}
+inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
+ return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
+}
+inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
+ GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
+ set_has_type();
+ type_ = value;
+}
+
+// optional string type_name = 6;
+inline bool FieldDescriptorProto::has_type_name() const {
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FieldDescriptorProto::set_has_type_name() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void FieldDescriptorProto::clear_has_type_name() {
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline void FieldDescriptorProto::clear_type_name() {
+ if (type_name_ != &::google::protobuf::internal::kEmptyString) {
+ type_name_->clear();
+ }
+ clear_has_type_name();
+}
+inline const ::std::string& FieldDescriptorProto::type_name() const {
+ return *type_name_;
+}
+inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
+ type_name_ = new ::std::string;
+ }
+ type_name_->assign(value);
+}
+inline void FieldDescriptorProto::set_type_name(const char* value) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
+ type_name_ = new ::std::string;
+ }
+ type_name_->assign(value);
+}
+inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
+ type_name_ = new ::std::string;
+ }
+ type_name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FieldDescriptorProto::mutable_type_name() {
+ set_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
+ type_name_ = new ::std::string;
+ }
+ return type_name_;
+}
+inline ::std::string* FieldDescriptorProto::release_type_name() {
+ clear_has_type_name();
+ if (type_name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = type_name_;
+ type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string extendee = 2;
+inline bool FieldDescriptorProto::has_extendee() const {
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FieldDescriptorProto::set_has_extendee() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void FieldDescriptorProto::clear_has_extendee() {
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline void FieldDescriptorProto::clear_extendee() {
+ if (extendee_ != &::google::protobuf::internal::kEmptyString) {
+ extendee_->clear();
+ }
+ clear_has_extendee();
+}
+inline const ::std::string& FieldDescriptorProto::extendee() const {
+ return *extendee_;
+}
+inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
+ extendee_ = new ::std::string;
+ }
+ extendee_->assign(value);
+}
+inline void FieldDescriptorProto::set_extendee(const char* value) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
+ extendee_ = new ::std::string;
+ }
+ extendee_->assign(value);
+}
+inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
+ extendee_ = new ::std::string;
+ }
+ extendee_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FieldDescriptorProto::mutable_extendee() {
+ set_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
+ extendee_ = new ::std::string;
+ }
+ return extendee_;
+}
+inline ::std::string* FieldDescriptorProto::release_extendee() {
+ clear_has_extendee();
+ if (extendee_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = extendee_;
+ extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string default_value = 7;
+inline bool FieldDescriptorProto::has_default_value() const {
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void FieldDescriptorProto::set_has_default_value() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void FieldDescriptorProto::clear_has_default_value() {
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline void FieldDescriptorProto::clear_default_value() {
+ if (default_value_ != &::google::protobuf::internal::kEmptyString) {
+ default_value_->clear();
+ }
+ clear_has_default_value();
+}
+inline const ::std::string& FieldDescriptorProto::default_value() const {
+ return *default_value_;
+}
+inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
+ default_value_ = new ::std::string;
+ }
+ default_value_->assign(value);
+}
+inline void FieldDescriptorProto::set_default_value(const char* value) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
+ default_value_ = new ::std::string;
+ }
+ default_value_->assign(value);
+}
+inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
+ default_value_ = new ::std::string;
+ }
+ default_value_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FieldDescriptorProto::mutable_default_value() {
+ set_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
+ default_value_ = new ::std::string;
+ }
+ return default_value_;
+}
+inline ::std::string* FieldDescriptorProto::release_default_value() {
+ clear_has_default_value();
+ if (default_value_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = default_value_;
+ default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional .google.protobuf.FieldOptions options = 8;
+inline bool FieldDescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FieldDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void FieldDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000080u;
+}
+inline void FieldDescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
+ clear_has_options();
+}
+inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions;
+ return options_;
+}
+inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::FieldOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+
+// -------------------------------------------------------------------
+
+// EnumDescriptorProto
+
+// optional string name = 1;
+inline bool EnumDescriptorProto::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void EnumDescriptorProto::clear_name() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& EnumDescriptorProto::name() const {
+ return *name_;
+}
+inline void EnumDescriptorProto::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void EnumDescriptorProto::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void EnumDescriptorProto::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* EnumDescriptorProto::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ return name_;
+}
+inline ::std::string* EnumDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+inline int EnumDescriptorProto::value_size() const {
+ return value_.size();
+}
+inline void EnumDescriptorProto::clear_value() {
+ value_.Clear();
+}
+inline const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
+ return value_.Get(index);
+}
+inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
+ return value_.Mutable(index);
+}
+inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
+ return value_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+EnumDescriptorProto::value() const {
+ return value_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
+EnumDescriptorProto::mutable_value() {
+ return &value_;
+}
+
+// optional .google.protobuf.EnumOptions options = 3;
+inline bool EnumDescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void EnumDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void EnumDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void EnumDescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
+ clear_has_options();
+}
+inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions;
+ return options_;
+}
+inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::EnumOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueDescriptorProto
+
+// optional string name = 1;
+inline bool EnumValueDescriptorProto::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumValueDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void EnumValueDescriptorProto::clear_name() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& EnumValueDescriptorProto::name() const {
+ return *name_;
+}
+inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void EnumValueDescriptorProto::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* EnumValueDescriptorProto::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ return name_;
+}
+inline ::std::string* EnumValueDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional int32 number = 2;
+inline bool EnumValueDescriptorProto::has_number() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_number() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void EnumValueDescriptorProto::clear_has_number() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void EnumValueDescriptorProto::clear_number() {
+ number_ = 0;
+ clear_has_number();
+}
+inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
+ return number_;
+}
+inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
+ set_has_number();
+ number_ = value;
+}
+
+// optional .google.protobuf.EnumValueOptions options = 3;
+inline bool EnumValueDescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void EnumValueDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void EnumValueDescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
+ clear_has_options();
+}
+inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions;
+ return options_;
+}
+inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::EnumValueOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+
+// -------------------------------------------------------------------
+
+// ServiceDescriptorProto
+
+// optional string name = 1;
+inline bool ServiceDescriptorProto::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void ServiceDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void ServiceDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void ServiceDescriptorProto::clear_name() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& ServiceDescriptorProto::name() const {
+ return *name_;
+}
+inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void ServiceDescriptorProto::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void ServiceDescriptorProto::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* ServiceDescriptorProto::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ return name_;
+}
+inline ::std::string* ServiceDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// repeated .google.protobuf.MethodDescriptorProto method = 2;
+inline int ServiceDescriptorProto::method_size() const {
+ return method_.size();
+}
+inline void ServiceDescriptorProto::clear_method() {
+ method_.Clear();
+}
+inline const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
+ return method_.Get(index);
+}
+inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
+ return method_.Mutable(index);
+}
+inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
+ return method_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+ServiceDescriptorProto::method() const {
+ return method_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
+ServiceDescriptorProto::mutable_method() {
+ return &method_;
+}
+
+// optional .google.protobuf.ServiceOptions options = 3;
+inline bool ServiceDescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void ServiceDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void ServiceDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void ServiceDescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
+ clear_has_options();
+}
+inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions;
+ return options_;
+}
+inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::ServiceOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+
+// -------------------------------------------------------------------
+
+// MethodDescriptorProto
+
+// optional string name = 1;
+inline bool MethodDescriptorProto::has_name() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MethodDescriptorProto::set_has_name() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void MethodDescriptorProto::clear_has_name() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void MethodDescriptorProto::clear_name() {
+ if (name_ != &::google::protobuf::internal::kEmptyString) {
+ name_->clear();
+ }
+ clear_has_name();
+}
+inline const ::std::string& MethodDescriptorProto::name() const {
+ return *name_;
+}
+inline void MethodDescriptorProto::set_name(const ::std::string& value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void MethodDescriptorProto::set_name(const char* value) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(value);
+}
+inline void MethodDescriptorProto::set_name(const char* value, size_t size) {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ name_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* MethodDescriptorProto::mutable_name() {
+ set_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ name_ = new ::std::string;
+ }
+ return name_;
+}
+inline ::std::string* MethodDescriptorProto::release_name() {
+ clear_has_name();
+ if (name_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_;
+ name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string input_type = 2;
+inline bool MethodDescriptorProto::has_input_type() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MethodDescriptorProto::set_has_input_type() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void MethodDescriptorProto::clear_has_input_type() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void MethodDescriptorProto::clear_input_type() {
+ if (input_type_ != &::google::protobuf::internal::kEmptyString) {
+ input_type_->clear();
+ }
+ clear_has_input_type();
+}
+inline const ::std::string& MethodDescriptorProto::input_type() const {
+ return *input_type_;
+}
+inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
+ input_type_ = new ::std::string;
+ }
+ input_type_->assign(value);
+}
+inline void MethodDescriptorProto::set_input_type(const char* value) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
+ input_type_ = new ::std::string;
+ }
+ input_type_->assign(value);
+}
+inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
+ input_type_ = new ::std::string;
+ }
+ input_type_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* MethodDescriptorProto::mutable_input_type() {
+ set_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
+ input_type_ = new ::std::string;
+ }
+ return input_type_;
+}
+inline ::std::string* MethodDescriptorProto::release_input_type() {
+ clear_has_input_type();
+ if (input_type_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = input_type_;
+ input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string output_type = 3;
+inline bool MethodDescriptorProto::has_output_type() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void MethodDescriptorProto::set_has_output_type() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void MethodDescriptorProto::clear_has_output_type() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void MethodDescriptorProto::clear_output_type() {
+ if (output_type_ != &::google::protobuf::internal::kEmptyString) {
+ output_type_->clear();
+ }
+ clear_has_output_type();
+}
+inline const ::std::string& MethodDescriptorProto::output_type() const {
+ return *output_type_;
+}
+inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
+ output_type_ = new ::std::string;
+ }
+ output_type_->assign(value);
+}
+inline void MethodDescriptorProto::set_output_type(const char* value) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
+ output_type_ = new ::std::string;
+ }
+ output_type_->assign(value);
+}
+inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
+ output_type_ = new ::std::string;
+ }
+ output_type_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* MethodDescriptorProto::mutable_output_type() {
+ set_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
+ output_type_ = new ::std::string;
+ }
+ return output_type_;
+}
+inline ::std::string* MethodDescriptorProto::release_output_type() {
+ clear_has_output_type();
+ if (output_type_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = output_type_;
+ output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional .google.protobuf.MethodOptions options = 4;
+inline bool MethodDescriptorProto::has_options() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void MethodDescriptorProto::set_has_options() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void MethodDescriptorProto::clear_has_options() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void MethodDescriptorProto::clear_options() {
+ if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
+ clear_has_options();
+}
+inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
+ return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
+ set_has_options();
+ if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions;
+ return options_;
+}
+inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
+ clear_has_options();
+ ::google::protobuf::MethodOptions* temp = options_;
+ options_ = NULL;
+ return temp;
+}
+
+// -------------------------------------------------------------------
+
+// FileOptions
+
+// optional string java_package = 1;
+inline bool FileOptions::has_java_package() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FileOptions::set_has_java_package() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FileOptions::clear_has_java_package() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void FileOptions::clear_java_package() {
+ if (java_package_ != &::google::protobuf::internal::kEmptyString) {
+ java_package_->clear();
+ }
+ clear_has_java_package();
+}
+inline const ::std::string& FileOptions::java_package() const {
+ return *java_package_;
+}
+inline void FileOptions::set_java_package(const ::std::string& value) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
+ java_package_ = new ::std::string;
+ }
+ java_package_->assign(value);
+}
+inline void FileOptions::set_java_package(const char* value) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
+ java_package_ = new ::std::string;
+ }
+ java_package_->assign(value);
+}
+inline void FileOptions::set_java_package(const char* value, size_t size) {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
+ java_package_ = new ::std::string;
+ }
+ java_package_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FileOptions::mutable_java_package() {
+ set_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
+ java_package_ = new ::std::string;
+ }
+ return java_package_;
+}
+inline ::std::string* FileOptions::release_java_package() {
+ clear_has_java_package();
+ if (java_package_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = java_package_;
+ java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string java_outer_classname = 8;
+inline bool FileOptions::has_java_outer_classname() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FileOptions::set_has_java_outer_classname() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FileOptions::clear_has_java_outer_classname() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void FileOptions::clear_java_outer_classname() {
+ if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
+ java_outer_classname_->clear();
+ }
+ clear_has_java_outer_classname();
+}
+inline const ::std::string& FileOptions::java_outer_classname() const {
+ return *java_outer_classname_;
+}
+inline void FileOptions::set_java_outer_classname(const ::std::string& value) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
+ java_outer_classname_ = new ::std::string;
+ }
+ java_outer_classname_->assign(value);
+}
+inline void FileOptions::set_java_outer_classname(const char* value) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
+ java_outer_classname_ = new ::std::string;
+ }
+ java_outer_classname_->assign(value);
+}
+inline void FileOptions::set_java_outer_classname(const char* value, size_t size) {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
+ java_outer_classname_ = new ::std::string;
+ }
+ java_outer_classname_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FileOptions::mutable_java_outer_classname() {
+ set_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
+ java_outer_classname_ = new ::std::string;
+ }
+ return java_outer_classname_;
+}
+inline ::std::string* FileOptions::release_java_outer_classname() {
+ clear_has_java_outer_classname();
+ if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = java_outer_classname_;
+ java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional bool java_multiple_files = 10 [default = false];
+inline bool FileOptions::has_java_multiple_files() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FileOptions::set_has_java_multiple_files() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FileOptions::clear_has_java_multiple_files() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void FileOptions::clear_java_multiple_files() {
+ java_multiple_files_ = false;
+ clear_has_java_multiple_files();
+}
+inline bool FileOptions::java_multiple_files() const {
+ return java_multiple_files_;
+}
+inline void FileOptions::set_java_multiple_files(bool value) {
+ set_has_java_multiple_files();
+ java_multiple_files_ = value;
+}
+
+// optional bool retain_unknown_fields = 11 [default = false];
+inline bool FileOptions::has_retain_unknown_fields() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FileOptions::set_has_retain_unknown_fields() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FileOptions::clear_has_retain_unknown_fields() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void FileOptions::clear_retain_unknown_fields() {
+ retain_unknown_fields_ = false;
+ clear_has_retain_unknown_fields();
+}
+inline bool FileOptions::retain_unknown_fields() const {
+ return retain_unknown_fields_;
+}
+inline void FileOptions::set_retain_unknown_fields(bool value) {
+ set_has_retain_unknown_fields();
+ retain_unknown_fields_ = value;
+}
+
+// optional bool java_generate_equals_and_hash = 20 [default = false];
+inline bool FileOptions::has_java_generate_equals_and_hash() const {
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FileOptions::set_has_java_generate_equals_and_hash() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void FileOptions::clear_has_java_generate_equals_and_hash() {
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline void FileOptions::clear_java_generate_equals_and_hash() {
+ java_generate_equals_and_hash_ = false;
+ clear_has_java_generate_equals_and_hash();
+}
+inline bool FileOptions::java_generate_equals_and_hash() const {
+ return java_generate_equals_and_hash_;
+}
+inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
+ set_has_java_generate_equals_and_hash();
+ java_generate_equals_and_hash_ = value;
+}
+
+// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+inline bool FileOptions::has_optimize_for() const {
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FileOptions::set_has_optimize_for() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void FileOptions::clear_has_optimize_for() {
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline void FileOptions::clear_optimize_for() {
+ optimize_for_ = 1;
+ clear_has_optimize_for();
+}
+inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
+ return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_);
+}
+inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
+ GOOGLE_DCHECK(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
+ set_has_optimize_for();
+ optimize_for_ = value;
+}
+
+// optional bool cc_generic_services = 16 [default = false];
+inline bool FileOptions::has_cc_generic_services() const {
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void FileOptions::set_has_cc_generic_services() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void FileOptions::clear_has_cc_generic_services() {
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline void FileOptions::clear_cc_generic_services() {
+ cc_generic_services_ = false;
+ clear_has_cc_generic_services();
+}
+inline bool FileOptions::cc_generic_services() const {
+ return cc_generic_services_;
+}
+inline void FileOptions::set_cc_generic_services(bool value) {
+ set_has_cc_generic_services();
+ cc_generic_services_ = value;
+}
+
+// optional bool java_generic_services = 17 [default = false];
+inline bool FileOptions::has_java_generic_services() const {
+ return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FileOptions::set_has_java_generic_services() {
+ _has_bits_[0] |= 0x00000080u;
+}
+inline void FileOptions::clear_has_java_generic_services() {
+ _has_bits_[0] &= ~0x00000080u;
+}
+inline void FileOptions::clear_java_generic_services() {
+ java_generic_services_ = false;
+ clear_has_java_generic_services();
+}
+inline bool FileOptions::java_generic_services() const {
+ return java_generic_services_;
+}
+inline void FileOptions::set_java_generic_services(bool value) {
+ set_has_java_generic_services();
+ java_generic_services_ = value;
+}
+
+// optional bool py_generic_services = 18 [default = false];
+inline bool FileOptions::has_py_generic_services() const {
+ return (_has_bits_[0] & 0x00000100u) != 0;
+}
+inline void FileOptions::set_has_py_generic_services() {
+ _has_bits_[0] |= 0x00000100u;
+}
+inline void FileOptions::clear_has_py_generic_services() {
+ _has_bits_[0] &= ~0x00000100u;
+}
+inline void FileOptions::clear_py_generic_services() {
+ py_generic_services_ = false;
+ clear_has_py_generic_services();
+}
+inline bool FileOptions::py_generic_services() const {
+ return py_generic_services_;
+}
+inline void FileOptions::set_py_generic_services(bool value) {
+ set_has_py_generic_services();
+ py_generic_services_ = value;
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int FileOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline void FileOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FileOptions::uninterpreted_option() const {
+ return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+FileOptions::mutable_uninterpreted_option() {
+ return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// MessageOptions
+
+// optional bool message_set_wire_format = 1 [default = false];
+inline bool MessageOptions::has_message_set_wire_format() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MessageOptions::set_has_message_set_wire_format() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void MessageOptions::clear_has_message_set_wire_format() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void MessageOptions::clear_message_set_wire_format() {
+ message_set_wire_format_ = false;
+ clear_has_message_set_wire_format();
+}
+inline bool MessageOptions::message_set_wire_format() const {
+ return message_set_wire_format_;
+}
+inline void MessageOptions::set_message_set_wire_format(bool value) {
+ set_has_message_set_wire_format();
+ message_set_wire_format_ = value;
+}
+
+// optional bool no_standard_descriptor_accessor = 2 [default = false];
+inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MessageOptions::set_has_no_standard_descriptor_accessor() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void MessageOptions::clear_has_no_standard_descriptor_accessor() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void MessageOptions::clear_no_standard_descriptor_accessor() {
+ no_standard_descriptor_accessor_ = false;
+ clear_has_no_standard_descriptor_accessor();
+}
+inline bool MessageOptions::no_standard_descriptor_accessor() const {
+ return no_standard_descriptor_accessor_;
+}
+inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
+ set_has_no_standard_descriptor_accessor();
+ no_standard_descriptor_accessor_ = value;
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int MessageOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline void MessageOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MessageOptions::uninterpreted_option() const {
+ return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+MessageOptions::mutable_uninterpreted_option() {
+ return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// FieldOptions
+
+// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+inline bool FieldOptions::has_ctype() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldOptions::set_has_ctype() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldOptions::clear_has_ctype() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void FieldOptions::clear_ctype() {
+ ctype_ = 0;
+ clear_has_ctype();
+}
+inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
+ return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
+}
+inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
+ GOOGLE_DCHECK(::google::protobuf::FieldOptions_CType_IsValid(value));
+ set_has_ctype();
+ ctype_ = value;
+}
+
+// optional bool packed = 2;
+inline bool FieldOptions::has_packed() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldOptions::set_has_packed() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldOptions::clear_has_packed() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void FieldOptions::clear_packed() {
+ packed_ = false;
+ clear_has_packed();
+}
+inline bool FieldOptions::packed() const {
+ return packed_;
+}
+inline void FieldOptions::set_packed(bool value) {
+ set_has_packed();
+ packed_ = value;
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool FieldOptions::has_deprecated() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldOptions::set_has_deprecated() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldOptions::clear_has_deprecated() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void FieldOptions::clear_deprecated() {
+ deprecated_ = false;
+ clear_has_deprecated();
+}
+inline bool FieldOptions::deprecated() const {
+ return deprecated_;
+}
+inline void FieldOptions::set_deprecated(bool value) {
+ set_has_deprecated();
+ deprecated_ = value;
+}
+
+// optional string experimental_map_key = 9;
+inline bool FieldOptions::has_experimental_map_key() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldOptions::set_has_experimental_map_key() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldOptions::clear_has_experimental_map_key() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void FieldOptions::clear_experimental_map_key() {
+ if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
+ experimental_map_key_->clear();
+ }
+ clear_has_experimental_map_key();
+}
+inline const ::std::string& FieldOptions::experimental_map_key() const {
+ return *experimental_map_key_;
+}
+inline void FieldOptions::set_experimental_map_key(const ::std::string& value) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
+ experimental_map_key_ = new ::std::string;
+ }
+ experimental_map_key_->assign(value);
+}
+inline void FieldOptions::set_experimental_map_key(const char* value) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
+ experimental_map_key_ = new ::std::string;
+ }
+ experimental_map_key_->assign(value);
+}
+inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
+ experimental_map_key_ = new ::std::string;
+ }
+ experimental_map_key_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* FieldOptions::mutable_experimental_map_key() {
+ set_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
+ experimental_map_key_ = new ::std::string;
+ }
+ return experimental_map_key_;
+}
+inline ::std::string* FieldOptions::release_experimental_map_key() {
+ clear_has_experimental_map_key();
+ if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = experimental_map_key_;
+ experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int FieldOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline void FieldOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FieldOptions::uninterpreted_option() const {
+ return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+FieldOptions::mutable_uninterpreted_option() {
+ return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int EnumOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline void EnumOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumOptions::uninterpreted_option() const {
+ return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+EnumOptions::mutable_uninterpreted_option() {
+ return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int EnumValueOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline void EnumValueOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumValueOptions::uninterpreted_option() const {
+ return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+EnumValueOptions::mutable_uninterpreted_option() {
+ return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// ServiceOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int ServiceOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline void ServiceOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ServiceOptions::uninterpreted_option() const {
+ return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ServiceOptions::mutable_uninterpreted_option() {
+ return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// MethodOptions
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int MethodOptions::uninterpreted_option_size() const {
+ return uninterpreted_option_.size();
+}
+inline void MethodOptions::clear_uninterpreted_option() {
+ uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
+ return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
+ return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
+ return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MethodOptions::uninterpreted_option() const {
+ return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+MethodOptions::mutable_uninterpreted_option() {
+ return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// UninterpretedOption_NamePart
+
+// required string name_part = 1;
+inline bool UninterpretedOption_NamePart::has_name_part() const {
+ return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void UninterpretedOption_NamePart::set_has_name_part() {
+ _has_bits_[0] |= 0x00000001u;
+}
+inline void UninterpretedOption_NamePart::clear_has_name_part() {
+ _has_bits_[0] &= ~0x00000001u;
+}
+inline void UninterpretedOption_NamePart::clear_name_part() {
+ if (name_part_ != &::google::protobuf::internal::kEmptyString) {
+ name_part_->clear();
+ }
+ clear_has_name_part();
+}
+inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
+ return *name_part_;
+}
+inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
+ name_part_ = new ::std::string;
+ }
+ name_part_->assign(value);
+}
+inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
+ name_part_ = new ::std::string;
+ }
+ name_part_->assign(value);
+}
+inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
+ name_part_ = new ::std::string;
+ }
+ name_part_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
+ set_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
+ name_part_ = new ::std::string;
+ }
+ return name_part_;
+}
+inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
+ clear_has_name_part();
+ if (name_part_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = name_part_;
+ name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// required bool is_extension = 2;
+inline bool UninterpretedOption_NamePart::has_is_extension() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void UninterpretedOption_NamePart::set_has_is_extension() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void UninterpretedOption_NamePart::clear_has_is_extension() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void UninterpretedOption_NamePart::clear_is_extension() {
+ is_extension_ = false;
+ clear_has_is_extension();
+}
+inline bool UninterpretedOption_NamePart::is_extension() const {
+ return is_extension_;
+}
+inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
+ set_has_is_extension();
+ is_extension_ = value;
+}
+
+// -------------------------------------------------------------------
+
+// UninterpretedOption
+
+// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+inline int UninterpretedOption::name_size() const {
+ return name_.size();
+}
+inline void UninterpretedOption::clear_name() {
+ name_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
+ return name_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
+ return name_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
+ return name_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+UninterpretedOption::name() const {
+ return name_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
+UninterpretedOption::mutable_name() {
+ return &name_;
+}
+
+// optional string identifier_value = 3;
+inline bool UninterpretedOption::has_identifier_value() const {
+ return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void UninterpretedOption::set_has_identifier_value() {
+ _has_bits_[0] |= 0x00000002u;
+}
+inline void UninterpretedOption::clear_has_identifier_value() {
+ _has_bits_[0] &= ~0x00000002u;
+}
+inline void UninterpretedOption::clear_identifier_value() {
+ if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
+ identifier_value_->clear();
+ }
+ clear_has_identifier_value();
+}
+inline const ::std::string& UninterpretedOption::identifier_value() const {
+ return *identifier_value_;
+}
+inline void UninterpretedOption::set_identifier_value(const ::std::string& value) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
+ identifier_value_ = new ::std::string;
+ }
+ identifier_value_->assign(value);
+}
+inline void UninterpretedOption::set_identifier_value(const char* value) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
+ identifier_value_ = new ::std::string;
+ }
+ identifier_value_->assign(value);
+}
+inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
+ identifier_value_ = new ::std::string;
+ }
+ identifier_value_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* UninterpretedOption::mutable_identifier_value() {
+ set_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
+ identifier_value_ = new ::std::string;
+ }
+ return identifier_value_;
+}
+inline ::std::string* UninterpretedOption::release_identifier_value() {
+ clear_has_identifier_value();
+ if (identifier_value_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = identifier_value_;
+ identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional uint64 positive_int_value = 4;
+inline bool UninterpretedOption::has_positive_int_value() const {
+ return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void UninterpretedOption::set_has_positive_int_value() {
+ _has_bits_[0] |= 0x00000004u;
+}
+inline void UninterpretedOption::clear_has_positive_int_value() {
+ _has_bits_[0] &= ~0x00000004u;
+}
+inline void UninterpretedOption::clear_positive_int_value() {
+ positive_int_value_ = GOOGLE_ULONGLONG(0);
+ clear_has_positive_int_value();
+}
+inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const {
+ return positive_int_value_;
+}
+inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
+ set_has_positive_int_value();
+ positive_int_value_ = value;
+}
+
+// optional int64 negative_int_value = 5;
+inline bool UninterpretedOption::has_negative_int_value() const {
+ return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void UninterpretedOption::set_has_negative_int_value() {
+ _has_bits_[0] |= 0x00000008u;
+}
+inline void UninterpretedOption::clear_has_negative_int_value() {
+ _has_bits_[0] &= ~0x00000008u;
+}
+inline void UninterpretedOption::clear_negative_int_value() {
+ negative_int_value_ = GOOGLE_LONGLONG(0);
+ clear_has_negative_int_value();
+}
+inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const {
+ return negative_int_value_;
+}
+inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
+ set_has_negative_int_value();
+ negative_int_value_ = value;
+}
+
+// optional double double_value = 6;
+inline bool UninterpretedOption::has_double_value() const {
+ return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void UninterpretedOption::set_has_double_value() {
+ _has_bits_[0] |= 0x00000010u;
+}
+inline void UninterpretedOption::clear_has_double_value() {
+ _has_bits_[0] &= ~0x00000010u;
+}
+inline void UninterpretedOption::clear_double_value() {
+ double_value_ = 0;
+ clear_has_double_value();
+}
+inline double UninterpretedOption::double_value() const {
+ return double_value_;
+}
+inline void UninterpretedOption::set_double_value(double value) {
+ set_has_double_value();
+ double_value_ = value;
+}
+
+// optional bytes string_value = 7;
+inline bool UninterpretedOption::has_string_value() const {
+ return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void UninterpretedOption::set_has_string_value() {
+ _has_bits_[0] |= 0x00000020u;
+}
+inline void UninterpretedOption::clear_has_string_value() {
+ _has_bits_[0] &= ~0x00000020u;
+}
+inline void UninterpretedOption::clear_string_value() {
+ if (string_value_ != &::google::protobuf::internal::kEmptyString) {
+ string_value_->clear();
+ }
+ clear_has_string_value();
+}
+inline const ::std::string& UninterpretedOption::string_value() const {
+ return *string_value_;
+}
+inline void UninterpretedOption::set_string_value(const ::std::string& value) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
+ string_value_ = new ::std::string;
+ }
+ string_value_->assign(value);
+}
+inline void UninterpretedOption::set_string_value(const char* value) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
+ string_value_ = new ::std::string;
+ }
+ string_value_->assign(value);
+}
+inline void UninterpretedOption::set_string_value(const void* value, size_t size) {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
+ string_value_ = new ::std::string;
+ }
+ string_value_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* UninterpretedOption::mutable_string_value() {
+ set_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
+ string_value_ = new ::std::string;
+ }
+ return string_value_;
+}
+inline ::std::string* UninterpretedOption::release_string_value() {
+ clear_has_string_value();
+ if (string_value_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = string_value_;
+ string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// optional string aggregate_value = 8;
+inline bool UninterpretedOption::has_aggregate_value() const {
+ return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void UninterpretedOption::set_has_aggregate_value() {
+ _has_bits_[0] |= 0x00000040u;
+}
+inline void UninterpretedOption::clear_has_aggregate_value() {
+ _has_bits_[0] &= ~0x00000040u;
+}
+inline void UninterpretedOption::clear_aggregate_value() {
+ if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_->clear();
+ }
+ clear_has_aggregate_value();
+}
+inline const ::std::string& UninterpretedOption::aggregate_value() const {
+ return *aggregate_value_;
+}
+inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(value);
+}
+inline void UninterpretedOption::set_aggregate_value(const char* value) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(value);
+}
+inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_ = new ::std::string;
+ }
+ aggregate_value_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
+ set_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ aggregate_value_ = new ::std::string;
+ }
+ return aggregate_value_;
+}
+inline ::std::string* UninterpretedOption::release_aggregate_value() {
+ clear_has_aggregate_value();
+ if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) {
+ return NULL;
+ } else {
+ ::std::string* temp = aggregate_value_;
+ aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+ return temp;
+ }
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo_Location
+
+// repeated int32 path = 1 [packed = true];
+inline int SourceCodeInfo_Location::path_size() const {
+ return path_.size();
+}
+inline void SourceCodeInfo_Location::clear_path() {
+ path_.Clear();
+}
+inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const {
+ return path_.Get(index);
+}
+inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) {
+ path_.Set(index, value);
+}
+inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) {
+ path_.Add(value);
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::path() const {
+ return path_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_path() {
+ return &path_;
+}
+
+// repeated int32 span = 2 [packed = true];
+inline int SourceCodeInfo_Location::span_size() const {
+ return span_.size();
+}
+inline void SourceCodeInfo_Location::clear_span() {
+ span_.Clear();
+}
+inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const {
+ return span_.Get(index);
+}
+inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) {
+ span_.Set(index, value);
+}
+inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) {
+ span_.Add(value);
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::span() const {
+ return span_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_span() {
+ return &span_;
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo
+
+// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+inline int SourceCodeInfo::location_size() const {
+ return location_.size();
+}
+inline void SourceCodeInfo::clear_location() {
+ location_.Clear();
+}
+inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
+ return location_.Get(index);
+}
+inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
+ return location_.Mutable(index);
+}
+inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
+ return location_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+SourceCodeInfo::location() const {
+ return location_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+SourceCodeInfo::mutable_location() {
+ return &location_;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace protobuf
+} // namespace google
+
+#ifndef SWIG
+namespace google {
+namespace protobuf {
+
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() {
+ return ::google::protobuf::FieldDescriptorProto_Type_descriptor();
+}
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() {
+ return ::google::protobuf::FieldDescriptorProto_Label_descriptor();
+}
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() {
+ return ::google::protobuf::FileOptions_OptimizeMode_descriptor();
+}
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() {
+ return ::google::protobuf::FieldOptions_CType_descriptor();
+}
+
+} // namespace google
+} // namespace protobuf
+#endif // SWIG
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor.proto b/src/third_party/protobuf/src/google/protobuf/descriptor.proto
new file mode 100644
index 0000000..bd3cb96
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor.proto
@@ -0,0 +1,544 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// The messages in this file describe the definitions found in .proto files.
+// A valid .proto file can be translated directly to a FileDescriptorProto
+// without any other information (e.g. without reading its imports).
+
+
+
+package google.protobuf;
+option java_package = "com.google.protobuf";
+option java_outer_classname = "DescriptorProtos";
+
+// descriptor.proto must be optimized for speed because reflection-based
+// algorithms don't work during bootstrapping.
+option optimize_for = SPEED;
+
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+ repeated FileDescriptorProto file = 1;
+}
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+ optional string name = 1; // file name, relative to root of source tree
+ optional string package = 2; // e.g. "foo", "foo.bar", etc.
+
+ // Names of files imported by this file.
+ repeated string dependency = 3;
+
+ // All top-level definitions in this file.
+ repeated DescriptorProto message_type = 4;
+ repeated EnumDescriptorProto enum_type = 5;
+ repeated ServiceDescriptorProto service = 6;
+ repeated FieldDescriptorProto extension = 7;
+
+ optional FileOptions options = 8;
+
+ // This field contains optional information about the original source code.
+ // You may safely remove this entire field whithout harming runtime
+ // functionality of the descriptors -- the information is needed only by
+ // development tools.
+ optional SourceCodeInfo source_code_info = 9;
+}
+
+// Describes a message type.
+message DescriptorProto {
+ optional string name = 1;
+
+ repeated FieldDescriptorProto field = 2;
+ repeated FieldDescriptorProto extension = 6;
+
+ repeated DescriptorProto nested_type = 3;
+ repeated EnumDescriptorProto enum_type = 4;
+
+ message ExtensionRange {
+ optional int32 start = 1;
+ optional int32 end = 2;
+ }
+ repeated ExtensionRange extension_range = 5;
+
+ optional MessageOptions options = 7;
+}
+
+// Describes a field within a message.
+message FieldDescriptorProto {
+ enum Type {
+ // 0 is reserved for errors.
+ // Order is weird for historical reasons.
+ TYPE_DOUBLE = 1;
+ TYPE_FLOAT = 2;
+ TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers
+ // take 10 bytes. Use TYPE_SINT64 if negative
+ // values are likely.
+ TYPE_UINT64 = 4;
+ TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers
+ // take 10 bytes. Use TYPE_SINT32 if negative
+ // values are likely.
+ TYPE_FIXED64 = 6;
+ TYPE_FIXED32 = 7;
+ TYPE_BOOL = 8;
+ TYPE_STRING = 9;
+ TYPE_GROUP = 10; // Tag-delimited aggregate.
+ TYPE_MESSAGE = 11; // Length-delimited aggregate.
+
+ // New in version 2.
+ TYPE_BYTES = 12;
+ TYPE_UINT32 = 13;
+ TYPE_ENUM = 14;
+ TYPE_SFIXED32 = 15;
+ TYPE_SFIXED64 = 16;
+ TYPE_SINT32 = 17; // Uses ZigZag encoding.
+ TYPE_SINT64 = 18; // Uses ZigZag encoding.
+ };
+
+ enum Label {
+ // 0 is reserved for errors
+ LABEL_OPTIONAL = 1;
+ LABEL_REQUIRED = 2;
+ LABEL_REPEATED = 3;
+ // TODO(sanjay): Should we add LABEL_MAP?
+ };
+
+ optional string name = 1;
+ optional int32 number = 3;
+ optional Label label = 4;
+
+ // If type_name is set, this need not be set. If both this and type_name
+ // are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
+ optional Type type = 5;
+
+ // For message and enum types, this is the name of the type. If the name
+ // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
+ // rules are used to find the type (i.e. first the nested types within this
+ // message are searched, then within the parent, on up to the root
+ // namespace).
+ optional string type_name = 6;
+
+ // For extensions, this is the name of the type being extended. It is
+ // resolved in the same manner as type_name.
+ optional string extendee = 2;
+
+ // For numeric types, contains the original text representation of the value.
+ // For booleans, "true" or "false".
+ // For strings, contains the default text contents (not escaped in any way).
+ // For bytes, contains the C escaped value. All bytes >= 128 are escaped.
+ // TODO(kenton): Base-64 encode?
+ optional string default_value = 7;
+
+ optional FieldOptions options = 8;
+}
+
+// Describes an enum type.
+message EnumDescriptorProto {
+ optional string name = 1;
+
+ repeated EnumValueDescriptorProto value = 2;
+
+ optional EnumOptions options = 3;
+}
+
+// Describes a value within an enum.
+message EnumValueDescriptorProto {
+ optional string name = 1;
+ optional int32 number = 2;
+
+ optional EnumValueOptions options = 3;
+}
+
+// Describes a service.
+message ServiceDescriptorProto {
+ optional string name = 1;
+ repeated MethodDescriptorProto method = 2;
+
+ optional ServiceOptions options = 3;
+}
+
+// Describes a method of a service.
+message MethodDescriptorProto {
+ optional string name = 1;
+
+ // Input and output type names. These are resolved in the same way as
+ // FieldDescriptorProto.type_name, but must refer to a message type.
+ optional string input_type = 2;
+ optional string output_type = 3;
+
+ optional MethodOptions options = 4;
+}
+
+// ===================================================================
+// Options
+
+// Each of the definitions above may have "options" attached. These are
+// just annotations which may cause code to be generated slightly differently
+// or may contain hints for code that manipulates protocol messages.
+//
+// Clients may define custom options as extensions of the *Options messages.
+// These extensions may not yet be known at parsing time, so the parser cannot
+// store the values in them. Instead it stores them in a field in the *Options
+// message called uninterpreted_option. This field must have the same name
+// across all *Options messages. We then use this field to populate the
+// extensions when we build a descriptor, at which point all protos have been
+// parsed and so all extensions are known.
+//
+// Extension numbers for custom options may be chosen as follows:
+// * For options which will only be used within a single application or
+// organization, or for experimental options, use field numbers 50000
+// through 99999. It is up to you to ensure that you do not use the
+// same number for multiple options.
+// * For options which will be published and used publicly by multiple
+// independent entities, e-mail protobuf-global-extension-registry@google.com
+// to reserve extension numbers. Simply provide your project name (e.g.
+// Object-C plugin) and your porject website (if available) -- there's no need
+// to explain how you intend to use them. Usually you only need one extension
+// number. You can declare multiple options with only one extension number by
+// putting them in a sub-message. See the Custom Options section of the docs
+// for examples:
+// http://code.google.com/apis/protocolbuffers/docs/proto.html#options
+// If this turns out to be popular, a web service will be set up
+// to automatically assign option numbers.
+
+
+message FileOptions {
+
+ // Sets the Java package where classes generated from this .proto will be
+ // placed. By default, the proto package is used, but this is often
+ // inappropriate because proto packages do not normally start with backwards
+ // domain names.
+ optional string java_package = 1;
+
+
+ // If set, all the classes from the .proto file are wrapped in a single
+ // outer class with the given name. This applies to both Proto1
+ // (equivalent to the old "--one_java_file" option) and Proto2 (where
+ // a .proto always translates to a single class, but you may want to
+ // explicitly choose the class name).
+ optional string java_outer_classname = 8;
+
+ // If set true, then the Java code generator will generate a separate .java
+ // file for each top-level message, enum, and service defined in the .proto
+ // file. Thus, these types will *not* be nested inside the outer class
+ // named by java_outer_classname. However, the outer class will still be
+ // generated to contain the file's getDescriptor() method as well as any
+ // top-level extensions defined in the file.
+ optional bool java_multiple_files = 10 [default=false];
+
+ // If set true, then code generators will store unknown fields so that
+ // reserializing a message will retain them. This is the default behaviour
+ // unless LITE_RUNTIME is specified. Therefore, this option only makes sense
+ // when LITE_RUNTIME is in use.
+ optional bool retain_unknown_fields = 11 [default=false];
+
+ // If set true, then the Java code generator will generate equals() and
+ // hashCode() methods for all messages defined in the .proto file. This is
+ // purely a speed optimization, as the AbstractMessage base class includes
+ // reflection-based implementations of these methods.
+ optional bool java_generate_equals_and_hash = 20 [default=false];
+
+ // Generated classes can be optimized for speed or code size.
+ enum OptimizeMode {
+ SPEED = 1; // Generate complete code for parsing, serialization,
+ // etc.
+ CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
+ LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
+ }
+ optional OptimizeMode optimize_for = 9 [default=SPEED];
+
+
+
+
+ // Should generic services be generated in each language? "Generic" services
+ // are not specific to any particular RPC system. They are generated by the
+ // main code generators in each language (without additional plugins).
+ // Generic services were the only kind of service generation supported by
+ // early versions of proto2.
+ //
+ // Generic services are now considered deprecated in favor of using plugins
+ // that generate code specific to your particular RPC system. Therefore,
+ // these default to false. Old code which depends on generic services should
+ // explicitly set them to true.
+ optional bool cc_generic_services = 16 [default=false];
+ optional bool java_generic_services = 17 [default=false];
+ optional bool py_generic_services = 18 [default=false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message MessageOptions {
+ // Set true to use the old proto1 MessageSet wire format for extensions.
+ // This is provided for backwards-compatibility with the MessageSet wire
+ // format. You should not use this for any other reason: It's less
+ // efficient, has fewer features, and is more complicated.
+ //
+ // The message must be defined exactly as follows:
+ // message Foo {
+ // option message_set_wire_format = true;
+ // extensions 4 to max;
+ // }
+ // Note that the message cannot have any defined fields; MessageSets only
+ // have extensions.
+ //
+ // All extensions of your type must be singular messages; e.g. they cannot
+ // be int32s, enums, or repeated messages.
+ //
+ // Because this is an option, the above two restrictions are not enforced by
+ // the protocol compiler.
+ optional bool message_set_wire_format = 1 [default=false];
+
+ // Disables the generation of the standard "descriptor()" accessor, which can
+ // conflict with a field of the same name. This is meant to make migration
+ // from proto1 easier; new code should avoid fields named "descriptor".
+ optional bool no_standard_descriptor_accessor = 2 [default=false];
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message FieldOptions {
+ // The ctype option instructs the C++ code generator to use a different
+ // representation of the field than it normally would. See the specific
+ // options below. This option is not yet implemented in the open source
+ // release -- sorry, we'll try to include it in a future version!
+ optional CType ctype = 1 [default = STRING];
+ enum CType {
+ // Default mode.
+ STRING = 0;
+
+ CORD = 1;
+
+ STRING_PIECE = 2;
+ }
+ // The packed option can be enabled for repeated primitive fields to enable
+ // a more efficient representation on the wire. Rather than repeatedly
+ // writing the tag and type for each element, the entire array is encoded as
+ // a single length-delimited blob.
+ optional bool packed = 2;
+
+
+ // Is this field deprecated?
+ // Depending on the target platform, this can emit Deprecated annotations
+ // for accessors, or it will be completely ignored; in the very least, this
+ // is a formalization for deprecating fields.
+ optional bool deprecated = 3 [default=false];
+
+ // EXPERIMENTAL. DO NOT USE.
+ // For "map" fields, the name of the field in the enclosed type that
+ // is the key for this map. For example, suppose we have:
+ // message Item {
+ // required string name = 1;
+ // required string value = 2;
+ // }
+ // message Config {
+ // repeated Item items = 1 [experimental_map_key="name"];
+ // }
+ // In this situation, the map key for Item will be set to "name".
+ // TODO: Fully-implement this, then remove the "experimental_" prefix.
+ optional string experimental_map_key = 9;
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message EnumOptions {
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message EnumValueOptions {
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message ServiceOptions {
+
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
+ // framework. We apologize for hoarding these numbers to ourselves, but
+ // we were already using them long before we decided to release Protocol
+ // Buffers.
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+message MethodOptions {
+
+ // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
+ // framework. We apologize for hoarding these numbers to ourselves, but
+ // we were already using them long before we decided to release Protocol
+ // Buffers.
+
+ // The parser stores options it doesn't recognize here. See above.
+ repeated UninterpretedOption uninterpreted_option = 999;
+
+ // Clients can define custom options in extensions of this message. See above.
+ extensions 1000 to max;
+}
+
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
+message UninterpretedOption {
+ // The name of the uninterpreted option. Each string represents a segment in
+ // a dot-separated name. is_extension is true iff a segment represents an
+ // extension (denoted with parentheses in options specs in .proto files).
+ // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+ // "foo.(bar.baz).qux".
+ message NamePart {
+ required string name_part = 1;
+ required bool is_extension = 2;
+ }
+ repeated NamePart name = 2;
+
+ // The value of the uninterpreted option, in whatever type the tokenizer
+ // identified it as during parsing. Exactly one of these should be set.
+ optional string identifier_value = 3;
+ optional uint64 positive_int_value = 4;
+ optional int64 negative_int_value = 5;
+ optional double double_value = 6;
+ optional bytes string_value = 7;
+ optional string aggregate_value = 8;
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+ // A Location identifies a piece of source code in a .proto file which
+ // corresponds to a particular definition. This information is intended
+ // to be useful to IDEs, code indexers, documentation generators, and similar
+ // tools.
+ //
+ // For example, say we have a file like:
+ // message Foo {
+ // optional string foo = 1;
+ // }
+ // Let's look at just the field definition:
+ // optional string foo = 1;
+ // ^ ^^ ^^ ^ ^^^
+ // a bc de f ghi
+ // We have the following locations:
+ // span path represents
+ // [a,i) [ 4, 0, 2, 0 ] The whole field definition.
+ // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
+ // [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
+ // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
+ // [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
+ //
+ // Notes:
+ // - A location may refer to a repeated field itself (i.e. not to any
+ // particular index within it). This is used whenever a set of elements are
+ // logically enclosed in a single code segment. For example, an entire
+ // extend block (possibly containing multiple extension definitions) will
+ // have an outer location whose path refers to the "extensions" repeated
+ // field without an index.
+ // - Multiple locations may have the same path. This happens when a single
+ // logical declaration is spread out across multiple places. The most
+ // obvious example is the "extend" block again -- there may be multiple
+ // extend blocks in the same scope, each of which will have the same path.
+ // - A location's span is not always a subset of its parent's span. For
+ // example, the "extendee" of an extension declaration appears at the
+ // beginning of the "extend" block and is shared by all extensions within
+ // the block.
+ // - Just because a location's span is a subset of some other location's span
+ // does not mean that it is a descendent. For example, a "group" defines
+ // both a type and a field in a single declaration. Thus, the locations
+ // corresponding to the type and field and their components will overlap.
+ // - Code which tries to interpret locations should probably be designed to
+ // ignore those that it doesn't understand, as more types of locations could
+ // be recorded in the future.
+ repeated Location location = 1;
+ message Location {
+ // Identifies which part of the FileDescriptorProto was defined at this
+ // location.
+ //
+ // Each element is a field number or an index. They form a path from
+ // the root FileDescriptorProto to the place where the definition. For
+ // example, this path:
+ // [ 4, 3, 2, 7, 1 ]
+ // refers to:
+ // file.message_type(3) // 4, 3
+ // .field(7) // 2, 7
+ // .name() // 1
+ // This is because FileDescriptorProto.message_type has field number 4:
+ // repeated DescriptorProto message_type = 4;
+ // and DescriptorProto.field has field number 2:
+ // repeated FieldDescriptorProto field = 2;
+ // and FieldDescriptorProto.name has field number 1:
+ // optional string name = 1;
+ //
+ // Thus, the above path gives the location of a field name. If we removed
+ // the last element:
+ // [ 4, 3, 2, 7 ]
+ // this path refers to the whole field declaration (from the beginning
+ // of the label to the terminating semicolon).
+ repeated int32 path = 1 [packed=true];
+
+ // Always has exactly three or four elements: start line, start column,
+ // end line (optional, otherwise assumed same as start line), end column.
+ // These are packed into a single field for efficiency. Note that line
+ // and column numbers are zero-based -- typically you will want to add
+ // 1 to each before displaying to a user.
+ repeated int32 span = 2 [packed=true];
+
+ // TODO(kenton): Record comments appearing before and after the
+ // declaration.
+ }
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor_database.cc b/src/third_party/protobuf/src/google/protobuf/descriptor_database.cc
new file mode 100644
index 0000000..23e48a6
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor_database.cc
@@ -0,0 +1,541 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/descriptor_database.h>
+
+#include <set>
+
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/stubs/map-util.h>
+
+namespace google {
+namespace protobuf {
+
+DescriptorDatabase::~DescriptorDatabase() {}
+
+// ===================================================================
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddFile(
+ const FileDescriptorProto& file,
+ Value value) {
+ if (!InsertIfNotPresent(&by_name_, file.name(), value)) {
+ GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name();
+ return false;
+ }
+
+ // We must be careful here -- calling file.package() if file.has_package() is
+ // false could access an uninitialized static-storage variable if we are being
+ // run at startup time.
+ string path = file.has_package() ? file.package() : string();
+ if (!path.empty()) path += '.';
+
+ for (int i = 0; i < file.message_type_size(); i++) {
+ if (!AddSymbol(path + file.message_type(i).name(), value)) return false;
+ if (!AddNestedExtensions(file.message_type(i), value)) return false;
+ }
+ for (int i = 0; i < file.enum_type_size(); i++) {
+ if (!AddSymbol(path + file.enum_type(i).name(), value)) return false;
+ }
+ for (int i = 0; i < file.extension_size(); i++) {
+ if (!AddSymbol(path + file.extension(i).name(), value)) return false;
+ if (!AddExtension(file.extension(i), value)) return false;
+ }
+ for (int i = 0; i < file.service_size(); i++) {
+ if (!AddSymbol(path + file.service(i).name(), value)) return false;
+ }
+
+ return true;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol(
+ const string& name, Value value) {
+ // We need to make sure not to violate our map invariant.
+
+ // If the symbol name is invalid it could break our lookup algorithm (which
+ // relies on the fact that '.' sorts before all other characters that are
+ // valid in symbol names).
+ if (!ValidateSymbolName(name)) {
+ GOOGLE_LOG(ERROR) << "Invalid symbol name: " << name;
+ return false;
+ }
+
+ // Try to look up the symbol to make sure a super-symbol doesn't already
+ // exist.
+ typename map<string, Value>::iterator iter = FindLastLessOrEqual(name);
+
+ if (iter == by_symbol_.end()) {
+ // Apparently the map is currently empty. Just insert and be done with it.
+ by_symbol_.insert(typename map<string, Value>::value_type(name, value));
+ return true;
+ }
+
+ if (IsSubSymbol(iter->first, name)) {
+ GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing "
+ "symbol \"" << iter->first << "\".";
+ return false;
+ }
+
+ // OK, that worked. Now we have to make sure that no symbol in the map is
+ // a sub-symbol of the one we are inserting. The only symbol which could
+ // be so is the first symbol that is greater than the new symbol. Since
+ // |iter| points at the last symbol that is less than or equal, we just have
+ // to increment it.
+ ++iter;
+
+ if (iter != by_symbol_.end() && IsSubSymbol(name, iter->first)) {
+ GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing "
+ "symbol \"" << iter->first << "\".";
+ return false;
+ }
+
+ // OK, no conflicts.
+
+ // Insert the new symbol using the iterator as a hint, the new entry will
+ // appear immediately before the one the iterator is pointing at.
+ by_symbol_.insert(iter, typename map<string, Value>::value_type(name, value));
+
+ return true;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddNestedExtensions(
+ const DescriptorProto& message_type,
+ Value value) {
+ for (int i = 0; i < message_type.nested_type_size(); i++) {
+ if (!AddNestedExtensions(message_type.nested_type(i), value)) return false;
+ }
+ for (int i = 0; i < message_type.extension_size(); i++) {
+ if (!AddExtension(message_type.extension(i), value)) return false;
+ }
+ return true;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddExtension(
+ const FieldDescriptorProto& field,
+ Value value) {
+ if (!field.extendee().empty() && field.extendee()[0] == '.') {
+ // The extension is fully-qualified. We can use it as a lookup key in
+ // the by_symbol_ table.
+ if (!InsertIfNotPresent(&by_extension_,
+ make_pair(field.extendee().substr(1),
+ field.number()),
+ value)) {
+ GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: "
+ "extend " << field.extendee() << " { "
+ << field.name() << " = " << field.number() << " }";
+ return false;
+ }
+ } else {
+ // Not fully-qualified. We can't really do anything here, unfortunately.
+ // We don't consider this an error, though, because the descriptor is
+ // valid.
+ }
+ return true;
+}
+
+template <typename Value>
+Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindFile(
+ const string& filename) {
+ return FindWithDefault(by_name_, filename, Value());
+}
+
+template <typename Value>
+Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindSymbol(
+ const string& name) {
+ typename map<string, Value>::iterator iter = FindLastLessOrEqual(name);
+
+ return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) ?
+ iter->second : Value();
+}
+
+template <typename Value>
+Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindExtension(
+ const string& containing_type,
+ int field_number) {
+ return FindWithDefault(by_extension_,
+ make_pair(containing_type, field_number),
+ Value());
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers(
+ const string& containing_type,
+ vector<int>* output) {
+ typename map<pair<string, int>, Value >::const_iterator it =
+ by_extension_.lower_bound(make_pair(containing_type, 0));
+ bool success = false;
+
+ for (; it != by_extension_.end() && it->first.first == containing_type;
+ ++it) {
+ output->push_back(it->first.second);
+ success = true;
+ }
+
+ return success;
+}
+
+template <typename Value>
+typename map<string, Value>::iterator
+SimpleDescriptorDatabase::DescriptorIndex<Value>::FindLastLessOrEqual(
+ const string& name) {
+ // Find the last key in the map which sorts less than or equal to the
+ // symbol name. Since upper_bound() returns the *first* key that sorts
+ // *greater* than the input, we want the element immediately before that.
+ typename map<string, Value>::iterator iter = by_symbol_.upper_bound(name);
+ if (iter != by_symbol_.begin()) --iter;
+ return iter;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::IsSubSymbol(
+ const string& sub_symbol, const string& super_symbol) {
+ return sub_symbol == super_symbol ||
+ (HasPrefixString(super_symbol, sub_symbol) &&
+ super_symbol[sub_symbol.size()] == '.');
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::ValidateSymbolName(
+ const string& name) {
+ for (int i = 0; i < name.size(); i++) {
+ // I don't trust ctype.h due to locales. :(
+ if (name[i] != '.' && name[i] != '_' &&
+ (name[i] < '0' || name[i] > '9') &&
+ (name[i] < 'A' || name[i] > 'Z') &&
+ (name[i] < 'a' || name[i] > 'z')) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// -------------------------------------------------------------------
+
+SimpleDescriptorDatabase::SimpleDescriptorDatabase() {}
+SimpleDescriptorDatabase::~SimpleDescriptorDatabase() {
+ STLDeleteElements(&files_to_delete_);
+}
+
+bool SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) {
+ FileDescriptorProto* new_file = new FileDescriptorProto;
+ new_file->CopyFrom(file);
+ return AddAndOwn(new_file);
+}
+
+bool SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) {
+ files_to_delete_.push_back(file);
+ return index_.AddFile(*file, file);
+}
+
+bool SimpleDescriptorDatabase::FindFileByName(
+ const string& filename,
+ FileDescriptorProto* output) {
+ return MaybeCopy(index_.FindFile(filename), output);
+}
+
+bool SimpleDescriptorDatabase::FindFileContainingSymbol(
+ const string& symbol_name,
+ FileDescriptorProto* output) {
+ return MaybeCopy(index_.FindSymbol(symbol_name), output);
+}
+
+bool SimpleDescriptorDatabase::FindFileContainingExtension(
+ const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) {
+ return MaybeCopy(index_.FindExtension(containing_type, field_number), output);
+}
+
+bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
+ const string& extendee_type,
+ vector<int>* output) {
+ return index_.FindAllExtensionNumbers(extendee_type, output);
+}
+
+bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file,
+ FileDescriptorProto* output) {
+ if (file == NULL) return false;
+ output->CopyFrom(*file);
+ return true;
+}
+
+// -------------------------------------------------------------------
+
+EncodedDescriptorDatabase::EncodedDescriptorDatabase() {}
+EncodedDescriptorDatabase::~EncodedDescriptorDatabase() {
+ for (int i = 0; i < files_to_delete_.size(); i++) {
+ operator delete(files_to_delete_[i]);
+ }
+}
+
+bool EncodedDescriptorDatabase::Add(
+ const void* encoded_file_descriptor, int size) {
+ FileDescriptorProto file;
+ if (file.ParseFromArray(encoded_file_descriptor, size)) {
+ return index_.AddFile(file, make_pair(encoded_file_descriptor, size));
+ } else {
+ GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to "
+ "EncodedDescriptorDatabase::Add().";
+ return false;
+ }
+}
+
+bool EncodedDescriptorDatabase::AddCopy(
+ const void* encoded_file_descriptor, int size) {
+ void* copy = operator new(size);
+ memcpy(copy, encoded_file_descriptor, size);
+ files_to_delete_.push_back(copy);
+ return Add(copy, size);
+}
+
+bool EncodedDescriptorDatabase::FindFileByName(
+ const string& filename,
+ FileDescriptorProto* output) {
+ return MaybeParse(index_.FindFile(filename), output);
+}
+
+bool EncodedDescriptorDatabase::FindFileContainingSymbol(
+ const string& symbol_name,
+ FileDescriptorProto* output) {
+ return MaybeParse(index_.FindSymbol(symbol_name), output);
+}
+
+bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol(
+ const string& symbol_name,
+ string* output) {
+ pair<const void*, int> encoded_file = index_.FindSymbol(symbol_name);
+ if (encoded_file.first == NULL) return false;
+
+ // Optimization: The name should be the first field in the encoded message.
+ // Try to just read it directly.
+ io::CodedInputStream input(reinterpret_cast<const uint8*>(encoded_file.first),
+ encoded_file.second);
+
+ const uint32 kNameTag = internal::WireFormatLite::MakeTag(
+ FileDescriptorProto::kNameFieldNumber,
+ internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+
+ if (input.ReadTag() == kNameTag) {
+ // Success!
+ return internal::WireFormatLite::ReadString(&input, output);
+ } else {
+ // Slow path. Parse whole message.
+ FileDescriptorProto file_proto;
+ if (!file_proto.ParseFromArray(encoded_file.first, encoded_file.second)) {
+ return false;
+ }
+ *output = file_proto.name();
+ return true;
+ }
+}
+
+bool EncodedDescriptorDatabase::FindFileContainingExtension(
+ const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) {
+ return MaybeParse(index_.FindExtension(containing_type, field_number),
+ output);
+}
+
+bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
+ const string& extendee_type,
+ vector<int>* output) {
+ return index_.FindAllExtensionNumbers(extendee_type, output);
+}
+
+bool EncodedDescriptorDatabase::MaybeParse(
+ pair<const void*, int> encoded_file,
+ FileDescriptorProto* output) {
+ if (encoded_file.first == NULL) return false;
+ return output->ParseFromArray(encoded_file.first, encoded_file.second);
+}
+
+// ===================================================================
+
+DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool)
+ : pool_(pool) {}
+DescriptorPoolDatabase::~DescriptorPoolDatabase() {}
+
+bool DescriptorPoolDatabase::FindFileByName(
+ const string& filename,
+ FileDescriptorProto* output) {
+ const FileDescriptor* file = pool_.FindFileByName(filename);
+ if (file == NULL) return false;
+ output->Clear();
+ file->CopyTo(output);
+ return true;
+}
+
+bool DescriptorPoolDatabase::FindFileContainingSymbol(
+ const string& symbol_name,
+ FileDescriptorProto* output) {
+ const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name);
+ if (file == NULL) return false;
+ output->Clear();
+ file->CopyTo(output);
+ return true;
+}
+
+bool DescriptorPoolDatabase::FindFileContainingExtension(
+ const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) {
+ const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type);
+ if (extendee == NULL) return false;
+
+ const FieldDescriptor* extension =
+ pool_.FindExtensionByNumber(extendee, field_number);
+ if (extension == NULL) return false;
+
+ output->Clear();
+ extension->file()->CopyTo(output);
+ return true;
+}
+
+bool DescriptorPoolDatabase::FindAllExtensionNumbers(
+ const string& extendee_type,
+ vector<int>* output) {
+ const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type);
+ if (extendee == NULL) return false;
+
+ vector<const FieldDescriptor*> extensions;
+ pool_.FindAllExtensions(extendee, &extensions);
+
+ for (int i = 0; i < extensions.size(); ++i) {
+ output->push_back(extensions[i]->number());
+ }
+
+ return true;
+}
+
+// ===================================================================
+
+MergedDescriptorDatabase::MergedDescriptorDatabase(
+ DescriptorDatabase* source1,
+ DescriptorDatabase* source2) {
+ sources_.push_back(source1);
+ sources_.push_back(source2);
+}
+MergedDescriptorDatabase::MergedDescriptorDatabase(
+ const vector<DescriptorDatabase*>& sources)
+ : sources_(sources) {}
+MergedDescriptorDatabase::~MergedDescriptorDatabase() {}
+
+bool MergedDescriptorDatabase::FindFileByName(
+ const string& filename,
+ FileDescriptorProto* output) {
+ for (int i = 0; i < sources_.size(); i++) {
+ if (sources_[i]->FindFileByName(filename, output)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool MergedDescriptorDatabase::FindFileContainingSymbol(
+ const string& symbol_name,
+ FileDescriptorProto* output) {
+ for (int i = 0; i < sources_.size(); i++) {
+ if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) {
+ // The symbol was found in source i. However, if one of the previous
+ // sources defines a file with the same name (which presumably doesn't
+ // contain the symbol, since it wasn't found in that source), then we
+ // must hide it from the caller.
+ FileDescriptorProto temp;
+ for (int j = 0; j < i; j++) {
+ if (sources_[j]->FindFileByName(output->name(), &temp)) {
+ // Found conflicting file in a previous source.
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool MergedDescriptorDatabase::FindFileContainingExtension(
+ const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) {
+ for (int i = 0; i < sources_.size(); i++) {
+ if (sources_[i]->FindFileContainingExtension(
+ containing_type, field_number, output)) {
+ // The symbol was found in source i. However, if one of the previous
+ // sources defines a file with the same name (which presumably doesn't
+ // contain the symbol, since it wasn't found in that source), then we
+ // must hide it from the caller.
+ FileDescriptorProto temp;
+ for (int j = 0; j < i; j++) {
+ if (sources_[j]->FindFileByName(output->name(), &temp)) {
+ // Found conflicting file in a previous source.
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool MergedDescriptorDatabase::FindAllExtensionNumbers(
+ const string& extendee_type,
+ vector<int>* output) {
+ set<int> merged_results;
+ vector<int> results;
+ bool success = false;
+
+ for (int i = 0; i < sources_.size(); i++) {
+ if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) {
+ copy(results.begin(), results.end(),
+ insert_iterator<set<int> >(merged_results, merged_results.begin()));
+ success = true;
+ }
+ results.clear();
+ }
+
+ copy(merged_results.begin(), merged_results.end(),
+ insert_iterator<vector<int> >(*output, output->end()));
+
+ return success;
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor_database.h b/src/third_party/protobuf/src/google/protobuf/descriptor_database.h
new file mode 100644
index 0000000..f32b1db
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor_database.h
@@ -0,0 +1,366 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Interface for manipulating databases of descriptors.
+
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
+#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class DescriptorDatabase;
+class SimpleDescriptorDatabase;
+class EncodedDescriptorDatabase;
+class DescriptorPoolDatabase;
+class MergedDescriptorDatabase;
+
+// Abstract interface for a database of descriptors.
+//
+// This is useful if you want to create a DescriptorPool which loads
+// descriptors on-demand from some sort of large database. If the database
+// is large, it may be inefficient to enumerate every .proto file inside it
+// calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool
+// can be created which wraps a DescriptorDatabase and only builds particular
+// descriptors when they are needed.
+class LIBPROTOBUF_EXPORT DescriptorDatabase {
+ public:
+ inline DescriptorDatabase() {}
+ virtual ~DescriptorDatabase();
+
+ // Find a file by file name. Fills in in *output and returns true if found.
+ // Otherwise, returns false, leaving the contents of *output undefined.
+ virtual bool FindFileByName(const string& filename,
+ FileDescriptorProto* output) = 0;
+
+ // Find the file that declares the given fully-qualified symbol name.
+ // If found, fills in *output and returns true, otherwise returns false
+ // and leaves *output undefined.
+ virtual bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output) = 0;
+
+ // Find the file which defines an extension extending the given message type
+ // with the given field number. If found, fills in *output and returns true,
+ // otherwise returns false and leaves *output undefined. containing_type
+ // must be a fully-qualified type name.
+ virtual bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) = 0;
+
+ // Finds the tag numbers used by all known extensions of
+ // extendee_type, and appends them to output in an undefined
+ // order. This method is best-effort: it's not guaranteed that the
+ // database will find all extensions, and it's not guaranteed that
+ // FindFileContainingExtension will return true on all of the found
+ // numbers. Returns true if the search was successful, otherwise
+ // returns false and leaves output unchanged.
+ //
+ // This method has a default implementation that always returns
+ // false.
+ virtual bool FindAllExtensionNumbers(const string& extendee_type,
+ vector<int>* output) {
+ return false;
+ }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase);
+};
+
+// A DescriptorDatabase into which you can insert files manually.
+//
+// FindFileContainingSymbol() is fully-implemented. When you add a file, its
+// symbols will be indexed for this purpose. Note that the implementation
+// may return false positives, but only if it isn't possible for the symbol
+// to be defined in any other file. In particular, if a file defines a symbol
+// "Foo", then searching for "Foo.[anything]" will match that file. This way,
+// the database does not need to aggressively index all children of a symbol.
+//
+// FindFileContainingExtension() is mostly-implemented. It works if and only
+// if the original FieldDescriptorProto defining the extension has a
+// fully-qualified type name in its "extendee" field (i.e. starts with a '.').
+// If the extendee is a relative name, SimpleDescriptorDatabase will not
+// attempt to resolve the type, so it will not know what type the extension is
+// extending. Therefore, calling FindFileContainingExtension() with the
+// extension's containing type will never actually find that extension. Note
+// that this is an unlikely problem, as all FileDescriptorProtos created by the
+// protocol compiler (as well as ones created by calling
+// FileDescriptor::CopyTo()) will always use fully-qualified names for all
+// types. You only need to worry if you are constructing FileDescriptorProtos
+// yourself, or are calling compiler::Parser directly.
+class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
+ public:
+ SimpleDescriptorDatabase();
+ ~SimpleDescriptorDatabase();
+
+ // Adds the FileDescriptorProto to the database, making a copy. The object
+ // can be deleted after Add() returns. Returns false if the file conflicted
+ // with a file already in the database, in which case an error will have
+ // been written to GOOGLE_LOG(ERROR).
+ bool Add(const FileDescriptorProto& file);
+
+ // Adds the FileDescriptorProto to the database and takes ownership of it.
+ bool AddAndOwn(const FileDescriptorProto* file);
+
+ // implements DescriptorDatabase -----------------------------------
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output);
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output);
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output);
+ bool FindAllExtensionNumbers(const string& extendee_type,
+ vector<int>* output);
+
+ private:
+ // So that it can use DescriptorIndex.
+ friend class EncodedDescriptorDatabase;
+
+ // An index mapping file names, symbol names, and extension numbers to
+ // some sort of values.
+ template <typename Value>
+ class DescriptorIndex {
+ public:
+ // Helpers to recursively add particular descriptors and all their contents
+ // to the index.
+ bool AddFile(const FileDescriptorProto& file,
+ Value value);
+ bool AddSymbol(const string& name, Value value);
+ bool AddNestedExtensions(const DescriptorProto& message_type,
+ Value value);
+ bool AddExtension(const FieldDescriptorProto& field,
+ Value value);
+
+ Value FindFile(const string& filename);
+ Value FindSymbol(const string& name);
+ Value FindExtension(const string& containing_type, int field_number);
+ bool FindAllExtensionNumbers(const string& containing_type,
+ vector<int>* output);
+
+ private:
+ map<string, Value> by_name_;
+ map<string, Value> by_symbol_;
+ map<pair<string, int>, Value> by_extension_;
+
+ // Invariant: The by_symbol_ map does not contain any symbols which are
+ // prefixes of other symbols in the map. For example, "foo.bar" is a
+ // prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz").
+ //
+ // This invariant is important because it means that given a symbol name,
+ // we can find a key in the map which is a prefix of the symbol in O(lg n)
+ // time, and we know that there is at most one such key.
+ //
+ // The prefix lookup algorithm works like so:
+ // 1) Find the last key in the map which is less than or equal to the
+ // search key.
+ // 2) If the found key is a prefix of the search key, then return it.
+ // Otherwise, there is no match.
+ //
+ // I am sure this algorithm has been described elsewhere, but since I
+ // wasn't able to find it quickly I will instead prove that it works
+ // myself. The key to the algorithm is that if a match exists, step (1)
+ // will find it. Proof:
+ // 1) Define the "search key" to be the key we are looking for, the "found
+ // key" to be the key found in step (1), and the "match key" to be the
+ // key which actually matches the serach key (i.e. the key we're trying
+ // to find).
+ // 2) The found key must be less than or equal to the search key by
+ // definition.
+ // 3) The match key must also be less than or equal to the search key
+ // (because it is a prefix).
+ // 4) The match key cannot be greater than the found key, because if it
+ // were, then step (1) of the algorithm would have returned the match
+ // key instead (since it finds the *greatest* key which is less than or
+ // equal to the search key).
+ // 5) Therefore, the found key must be between the match key and the search
+ // key, inclusive.
+ // 6) Since the search key must be a sub-symbol of the match key, if it is
+ // not equal to the match key, then search_key[match_key.size()] must
+ // be '.'.
+ // 7) Since '.' sorts before any other character that is valid in a symbol
+ // name, then if the found key is not equal to the match key, then
+ // found_key[match_key.size()] must also be '.', because any other value
+ // would make it sort after the search key.
+ // 8) Therefore, if the found key is not equal to the match key, then the
+ // found key must be a sub-symbol of the match key. However, this would
+ // contradict our map invariant which says that no symbol in the map is
+ // a sub-symbol of any other.
+ // 9) Therefore, the found key must match the match key.
+ //
+ // The above proof assumes the match key exists. In the case that the
+ // match key does not exist, then step (1) will return some other symbol.
+ // That symbol cannot be a super-symbol of the search key since if it were,
+ // then it would be a match, and we're assuming the match key doesn't exist.
+ // Therefore, step 2 will correctly return no match.
+
+ // Find the last entry in the by_symbol_ map whose key is less than or
+ // equal to the given name.
+ typename map<string, Value>::iterator FindLastLessOrEqual(
+ const string& name);
+
+ // True if either the arguments are equal or super_symbol identifies a
+ // parent symbol of sub_symbol (e.g. "foo.bar" is a parent of
+ // "foo.bar.baz", but not a parent of "foo.barbaz").
+ bool IsSubSymbol(const string& sub_symbol, const string& super_symbol);
+
+ // Returns true if and only if all characters in the name are alphanumerics,
+ // underscores, or periods.
+ bool ValidateSymbolName(const string& name);
+ };
+
+
+ DescriptorIndex<const FileDescriptorProto*> index_;
+ vector<const FileDescriptorProto*> files_to_delete_;
+
+ // If file is non-NULL, copy it into *output and return true, otherwise
+ // return false.
+ bool MaybeCopy(const FileDescriptorProto* file,
+ FileDescriptorProto* output);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase);
+};
+
+// Very similar to SimpleDescriptorDatabase, but stores all the descriptors
+// as raw bytes and generally tries to use as little memory as possible.
+//
+// The same caveats regarding FindFileContainingExtension() apply as with
+// SimpleDescriptorDatabase.
+class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
+ public:
+ EncodedDescriptorDatabase();
+ ~EncodedDescriptorDatabase();
+
+ // Adds the FileDescriptorProto to the database. The descriptor is provided
+ // in encoded form. The database does not make a copy of the bytes, nor
+ // does it take ownership; it's up to the caller to make sure the bytes
+ // remain valid for the life of the database. Returns false and logs an error
+ // if the bytes are not a valid FileDescriptorProto or if the file conflicted
+ // with a file already in the database.
+ bool Add(const void* encoded_file_descriptor, int size);
+
+ // Like Add(), but makes a copy of the data, so that the caller does not
+ // need to keep it around.
+ bool AddCopy(const void* encoded_file_descriptor, int size);
+
+ // Like FindFileContainingSymbol but returns only the name of the file.
+ bool FindNameOfFileContainingSymbol(const string& symbol_name,
+ string* output);
+
+ // implements DescriptorDatabase -----------------------------------
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output);
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output);
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output);
+ bool FindAllExtensionNumbers(const string& extendee_type,
+ vector<int>* output);
+
+ private:
+ SimpleDescriptorDatabase::DescriptorIndex<pair<const void*, int> > index_;
+ vector<void*> files_to_delete_;
+
+ // If encoded_file.first is non-NULL, parse the data into *output and return
+ // true, otherwise return false.
+ bool MaybeParse(pair<const void*, int> encoded_file,
+ FileDescriptorProto* output);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase);
+};
+
+// A DescriptorDatabase that fetches files from a given pool.
+class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
+ public:
+ DescriptorPoolDatabase(const DescriptorPool& pool);
+ ~DescriptorPoolDatabase();
+
+ // implements DescriptorDatabase -----------------------------------
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output);
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output);
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output);
+ bool FindAllExtensionNumbers(const string& extendee_type,
+ vector<int>* output);
+
+ private:
+ const DescriptorPool& pool_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase);
+};
+
+// A DescriptorDatabase that wraps two or more others. It first searches the
+// first database and, if that fails, tries the second, and so on.
+class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
+ public:
+ // Merge just two databases. The sources remain property of the caller.
+ MergedDescriptorDatabase(DescriptorDatabase* source1,
+ DescriptorDatabase* source2);
+ // Merge more than two databases. The sources remain property of the caller.
+ // The vector may be deleted after the constructor returns but the
+ // DescriptorDatabases need to stick around.
+ MergedDescriptorDatabase(const vector<DescriptorDatabase*>& sources);
+ ~MergedDescriptorDatabase();
+
+ // implements DescriptorDatabase -----------------------------------
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output);
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output);
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output);
+ // Merges the results of calling all databases. Returns true iff any
+ // of the databases returned true.
+ bool FindAllExtensionNumbers(const string& extendee_type,
+ vector<int>* output);
+
+ private:
+ vector<DescriptorDatabase*> sources_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase);
+};
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor_database_unittest.cc b/src/third_party/protobuf/src/google/protobuf/descriptor_database_unittest.cc
new file mode 100644
index 0000000..ac72ddc
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor_database_unittest.cc
@@ -0,0 +1,748 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file makes extensive use of RFC 3092. :)
+
+#include <algorithm>
+
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/stubs/strutil.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+static void AddToDatabase(SimpleDescriptorDatabase* database,
+ const char* file_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+ database->Add(file_proto);
+}
+
+static void ExpectContainsType(const FileDescriptorProto& proto,
+ const string& type_name) {
+ for (int i = 0; i < proto.message_type_size(); i++) {
+ if (proto.message_type(i).name() == type_name) return;
+ }
+ ADD_FAILURE() << "\"" << proto.name()
+ << "\" did not contain expected type \""
+ << type_name << "\".";
+}
+
+// ===================================================================
+
+#if GTEST_HAS_PARAM_TEST
+
+// SimpleDescriptorDatabase, EncodedDescriptorDatabase, and
+// DescriptorPoolDatabase call for very similar tests. Instead of writing
+// three nearly-identical sets of tests, we use parameterized tests to apply
+// the same code to all three.
+
+// The parameterized test runs against a DescriptarDatabaseTestCase. We have
+// implementations for each of the three classes we want to test.
+class DescriptorDatabaseTestCase {
+ public:
+ virtual ~DescriptorDatabaseTestCase() {}
+
+ virtual DescriptorDatabase* GetDatabase() = 0;
+ virtual bool AddToDatabase(const FileDescriptorProto& file) = 0;
+};
+
+// Factory function type.
+typedef DescriptorDatabaseTestCase* DescriptorDatabaseTestCaseFactory();
+
+// Specialization for SimpleDescriptorDatabase.
+class SimpleDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+ static DescriptorDatabaseTestCase* New() {
+ return new SimpleDescriptorDatabaseTestCase;
+ }
+
+ virtual ~SimpleDescriptorDatabaseTestCase() {}
+
+ virtual DescriptorDatabase* GetDatabase() {
+ return &database_;
+ }
+ virtual bool AddToDatabase(const FileDescriptorProto& file) {
+ return database_.Add(file);
+ }
+
+ private:
+ SimpleDescriptorDatabase database_;
+};
+
+// Specialization for EncodedDescriptorDatabase.
+class EncodedDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+ static DescriptorDatabaseTestCase* New() {
+ return new EncodedDescriptorDatabaseTestCase;
+ }
+
+ virtual ~EncodedDescriptorDatabaseTestCase() {}
+
+ virtual DescriptorDatabase* GetDatabase() {
+ return &database_;
+ }
+ virtual bool AddToDatabase(const FileDescriptorProto& file) {
+ string data;
+ file.SerializeToString(&data);
+ return database_.AddCopy(data.data(), data.size());
+ }
+
+ private:
+ EncodedDescriptorDatabase database_;
+};
+
+// Specialization for DescriptorPoolDatabase.
+class DescriptorPoolDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+ static DescriptorDatabaseTestCase* New() {
+ return new EncodedDescriptorDatabaseTestCase;
+ }
+
+ DescriptorPoolDatabaseTestCase() : database_(pool_) {}
+ virtual ~DescriptorPoolDatabaseTestCase() {}
+
+ virtual DescriptorDatabase* GetDatabase() {
+ return &database_;
+ }
+ virtual bool AddToDatabase(const FileDescriptorProto& file) {
+ return pool_.BuildFile(file);
+ }
+
+ private:
+ DescriptorPool pool_;
+ DescriptorPoolDatabase database_;
+};
+
+// -------------------------------------------------------------------
+
+class DescriptorDatabaseTest
+ : public testing::TestWithParam<DescriptorDatabaseTestCaseFactory*> {
+ protected:
+ virtual void SetUp() {
+ test_case_.reset(GetParam()());
+ database_ = test_case_->GetDatabase();
+ }
+
+ void AddToDatabase(const char* file_descriptor_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto));
+ EXPECT_TRUE(test_case_->AddToDatabase(file_proto));
+ }
+
+ void AddToDatabaseWithError(const char* file_descriptor_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto));
+ EXPECT_FALSE(test_case_->AddToDatabase(file_proto));
+ }
+
+ scoped_ptr<DescriptorDatabaseTestCase> test_case_;
+ DescriptorDatabase* database_;
+};
+
+TEST_P(DescriptorDatabaseTest, FindFileByName) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { name:\"Foo\" }");
+ AddToDatabase(
+ "name: \"bar.proto\" "
+ "message_type { name:\"Bar\" }");
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileByName("foo.proto", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ ExpectContainsType(file, "Foo");
+ }
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileByName("bar.proto", &file));
+ EXPECT_EQ("bar.proto", file.name());
+ ExpectContainsType(file, "Bar");
+ }
+
+ {
+ // Fails to find undefined files.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileByName("baz.proto", &file));
+ }
+}
+
+TEST_P(DescriptorDatabaseTest, FindFileContainingSymbol) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " field { name:\"qux\" }"
+ " nested_type { name: \"Grault\" } "
+ " enum_type { name: \"Garply\" } "
+ "} "
+ "enum_type { "
+ " name: \"Waldo\" "
+ " value { name:\"FRED\" } "
+ "} "
+ "extension { name: \"plugh\" } "
+ "service { "
+ " name: \"Xyzzy\" "
+ " method { name: \"Thud\" } "
+ "}"
+ );
+ AddToDatabase(
+ "name: \"bar.proto\" "
+ "package: \"corge\" "
+ "message_type { name: \"Bar\" }");
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Foo", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find fields.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.qux", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find nested types.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Grault", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find nested enums.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Foo.Garply", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find enum types.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find enum values.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Waldo.FRED", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find extensions.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("plugh", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find services.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find methods.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("Xyzzy.Thud", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ // Can find things in packages.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingSymbol("corge.Bar", &file));
+ EXPECT_EQ("bar.proto", file.name());
+ }
+
+ {
+ // Fails to find undefined symbols.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingSymbol("Baz", &file));
+ }
+
+ {
+ // Names must be fully-qualified.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingSymbol("Bar", &file));
+ }
+}
+
+TEST_P(DescriptorDatabaseTest, FindFileContainingExtension) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " extension_range { start: 1 end: 1000 } "
+ " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+ " extendee: \".Foo\" }"
+ "}");
+ AddToDatabase(
+ "name: \"bar.proto\" "
+ "package: \"corge\" "
+ "dependency: \"foo.proto\" "
+ "message_type { "
+ " name: \"Bar\" "
+ " extension_range { start: 1 end: 1000 } "
+ "} "
+ "extension { name:\"grault\" extendee: \".Foo\" number:32 } "
+ "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } "
+ "extension { name:\"waldo\" extendee: \"Bar\" number:56 } ");
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 5, &file));
+ EXPECT_EQ("foo.proto", file.name());
+ }
+
+ {
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingExtension("Foo", 32, &file));
+ EXPECT_EQ("bar.proto", file.name());
+ }
+
+ {
+ // Can find extensions for qualified type names.
+ FileDescriptorProto file;
+ EXPECT_TRUE(database_->FindFileContainingExtension("corge.Bar", 70, &file));
+ EXPECT_EQ("bar.proto", file.name());
+ }
+
+ {
+ // Can't find extensions whose extendee was not fully-qualified in the
+ // FileDescriptorProto.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 56, &file));
+ EXPECT_FALSE(
+ database_->FindFileContainingExtension("corge.Bar", 56, &file));
+ }
+
+ {
+ // Can't find non-existent extension numbers.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingExtension("Foo", 12, &file));
+ }
+
+ {
+ // Can't find extensions for non-existent types.
+ FileDescriptorProto file;
+ EXPECT_FALSE(
+ database_->FindFileContainingExtension("NoSuchType", 5, &file));
+ }
+
+ {
+ // Can't find extensions for unqualified type names.
+ FileDescriptorProto file;
+ EXPECT_FALSE(database_->FindFileContainingExtension("Bar", 70, &file));
+ }
+}
+
+TEST_P(DescriptorDatabaseTest, FindAllExtensionNumbers) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " extension_range { start: 1 end: 1000 } "
+ " extension { name:\"qux\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+ " extendee: \".Foo\" }"
+ "}");
+ AddToDatabase(
+ "name: \"bar.proto\" "
+ "package: \"corge\" "
+ "dependency: \"foo.proto\" "
+ "message_type { "
+ " name: \"Bar\" "
+ " extension_range { start: 1 end: 1000 } "
+ "} "
+ "extension { name:\"grault\" extendee: \".Foo\" number:32 } "
+ "extension { name:\"garply\" extendee: \".corge.Bar\" number:70 } "
+ "extension { name:\"waldo\" extendee: \"Bar\" number:56 } ");
+
+ {
+ vector<int> numbers;
+ EXPECT_TRUE(database_->FindAllExtensionNumbers("Foo", &numbers));
+ ASSERT_EQ(2, numbers.size());
+ sort(numbers.begin(), numbers.end());
+ EXPECT_EQ(5, numbers[0]);
+ EXPECT_EQ(32, numbers[1]);
+ }
+
+ {
+ vector<int> numbers;
+ EXPECT_TRUE(database_->FindAllExtensionNumbers("corge.Bar", &numbers));
+ // Note: won't find extension 56 due to the name not being fully qualified.
+ ASSERT_EQ(1, numbers.size());
+ EXPECT_EQ(70, numbers[0]);
+ }
+
+ {
+ // Can't find extensions for non-existent types.
+ vector<int> numbers;
+ EXPECT_FALSE(database_->FindAllExtensionNumbers("NoSuchType", &numbers));
+ }
+
+ {
+ // Can't find extensions for unqualified types.
+ vector<int> numbers;
+ EXPECT_FALSE(database_->FindAllExtensionNumbers("Bar", &numbers));
+ }
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingFileError) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ "}");
+ AddToDatabaseWithError(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Bar\" "
+ "}");
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingTypeError) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ "}");
+ AddToDatabaseWithError(
+ "name: \"bar.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ "}");
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingExtensionError) {
+ AddToDatabase(
+ "name: \"foo.proto\" "
+ "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+ " extendee: \".Foo\" }");
+ AddToDatabaseWithError(
+ "name: \"bar.proto\" "
+ "extension { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+ " extendee: \".Foo\" }");
+}
+
+INSTANTIATE_TEST_CASE_P(Simple, DescriptorDatabaseTest,
+ testing::Values(&SimpleDescriptorDatabaseTestCase::New));
+INSTANTIATE_TEST_CASE_P(MemoryConserving, DescriptorDatabaseTest,
+ testing::Values(&EncodedDescriptorDatabaseTestCase::New));
+INSTANTIATE_TEST_CASE_P(Pool, DescriptorDatabaseTest,
+ testing::Values(&DescriptorPoolDatabaseTestCase::New));
+
+#endif // GTEST_HAS_PARAM_TEST
+
+TEST(EncodedDescriptorDatabaseExtraTest, FindNameOfFileContainingSymbol) {
+ // Create two files, one of which is in two parts.
+ FileDescriptorProto file1, file2a, file2b;
+ file1.set_name("foo.proto");
+ file1.set_package("foo");
+ file1.add_message_type()->set_name("Foo");
+ file2a.set_name("bar.proto");
+ file2b.set_package("bar");
+ file2b.add_message_type()->set_name("Bar");
+
+ // Normal serialization allows our optimization to kick in.
+ string data1 = file1.SerializeAsString();
+
+ // Force out-of-order serialization to test slow path.
+ string data2 = file2b.SerializeAsString() + file2a.SerializeAsString();
+
+ // Create EncodedDescriptorDatabase containing both files.
+ EncodedDescriptorDatabase db;
+ db.Add(data1.data(), data1.size());
+ db.Add(data2.data(), data2.size());
+
+ // Test!
+ string filename;
+ EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo", &filename));
+ EXPECT_EQ("foo.proto", filename);
+ EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo.Blah", &filename));
+ EXPECT_EQ("foo.proto", filename);
+ EXPECT_TRUE(db.FindNameOfFileContainingSymbol("bar.Bar", &filename));
+ EXPECT_EQ("bar.proto", filename);
+ EXPECT_FALSE(db.FindNameOfFileContainingSymbol("foo", &filename));
+ EXPECT_FALSE(db.FindNameOfFileContainingSymbol("bar", &filename));
+ EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename));
+}
+
+// ===================================================================
+
+class MergedDescriptorDatabaseTest : public testing::Test {
+ protected:
+ MergedDescriptorDatabaseTest()
+ : forward_merged_(&database1_, &database2_),
+ reverse_merged_(&database2_, &database1_) {}
+
+ virtual void SetUp() {
+ AddToDatabase(&database1_,
+ "name: \"foo.proto\" "
+ "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
+ "extension { name:\"foo_ext\" extendee: \".Foo\" number:3 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ AddToDatabase(&database2_,
+ "name: \"bar.proto\" "
+ "message_type { name:\"Bar\" extension_range { start: 1 end: 100 } } "
+ "extension { name:\"bar_ext\" extendee: \".Bar\" number:5 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+
+ // baz.proto exists in both pools, with different definitions.
+ AddToDatabase(&database1_,
+ "name: \"baz.proto\" "
+ "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } "
+ "message_type { name:\"FromPool1\" } "
+ "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } "
+ "extension { name:\"database1_only_ext\" extendee: \".Baz\" number:13 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ AddToDatabase(&database2_,
+ "name: \"baz.proto\" "
+ "message_type { name:\"Baz\" extension_range { start: 1 end: 100 } } "
+ "message_type { name:\"FromPool2\" } "
+ "extension { name:\"baz_ext\" extendee: \".Baz\" number:12 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ }
+
+ SimpleDescriptorDatabase database1_;
+ SimpleDescriptorDatabase database2_;
+
+ MergedDescriptorDatabase forward_merged_;
+ MergedDescriptorDatabase reverse_merged_;
+};
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileByName) {
+ {
+ // Can find file that is only in database1_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileByName("foo.proto", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ ExpectContainsType(file, "Foo");
+ }
+
+ {
+ // Can find file that is only in database2_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileByName("bar.proto", &file));
+ EXPECT_EQ("bar.proto", file.name());
+ ExpectContainsType(file, "Bar");
+ }
+
+ {
+ // In forward_merged_, database1_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileByName("baz.proto", &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool1");
+ }
+
+ {
+ // In reverse_merged_, database2_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(reverse_merged_.FindFileByName("baz.proto", &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool2");
+ }
+
+ {
+ // Can't find non-existent file.
+ FileDescriptorProto file;
+ EXPECT_FALSE(forward_merged_.FindFileByName("no_such.proto", &file));
+ }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileContainingSymbol) {
+ {
+ // Can find file that is only in database1_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Foo", &file));
+ EXPECT_EQ("foo.proto", file.name());
+ ExpectContainsType(file, "Foo");
+ }
+
+ {
+ // Can find file that is only in database2_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Bar", &file));
+ EXPECT_EQ("bar.proto", file.name());
+ ExpectContainsType(file, "Bar");
+ }
+
+ {
+ // In forward_merged_, database1_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("Baz", &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool1");
+ }
+
+ {
+ // In reverse_merged_, database2_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(reverse_merged_.FindFileContainingSymbol("Baz", &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool2");
+ }
+
+ {
+ // FromPool1 only shows up in forward_merged_ because it is masked by
+ // database2_'s baz.proto in reverse_merged_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingSymbol("FromPool1", &file));
+ EXPECT_FALSE(reverse_merged_.FindFileContainingSymbol("FromPool1", &file));
+ }
+
+ {
+ // Can't find non-existent symbol.
+ FileDescriptorProto file;
+ EXPECT_FALSE(
+ forward_merged_.FindFileContainingSymbol("NoSuchType", &file));
+ }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindFileContainingExtension) {
+ {
+ // Can find file that is only in database1_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(
+ forward_merged_.FindFileContainingExtension("Foo", 3, &file));
+ EXPECT_EQ("foo.proto", file.name());
+ ExpectContainsType(file, "Foo");
+ }
+
+ {
+ // Can find file that is only in database2_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(
+ forward_merged_.FindFileContainingExtension("Bar", 5, &file));
+ EXPECT_EQ("bar.proto", file.name());
+ ExpectContainsType(file, "Bar");
+ }
+
+ {
+ // In forward_merged_, database1_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(
+ forward_merged_.FindFileContainingExtension("Baz", 12, &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool1");
+ }
+
+ {
+ // In reverse_merged_, database2_'s baz.proto takes precedence.
+ FileDescriptorProto file;
+ EXPECT_TRUE(
+ reverse_merged_.FindFileContainingExtension("Baz", 12, &file));
+ EXPECT_EQ("baz.proto", file.name());
+ ExpectContainsType(file, "FromPool2");
+ }
+
+ {
+ // Baz's extension 13 only shows up in forward_merged_ because it is
+ // masked by database2_'s baz.proto in reverse_merged_.
+ FileDescriptorProto file;
+ EXPECT_TRUE(forward_merged_.FindFileContainingExtension("Baz", 13, &file));
+ EXPECT_FALSE(reverse_merged_.FindFileContainingExtension("Baz", 13, &file));
+ }
+
+ {
+ // Can't find non-existent extension.
+ FileDescriptorProto file;
+ EXPECT_FALSE(
+ forward_merged_.FindFileContainingExtension("Foo", 6, &file));
+ }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindAllExtensionNumbers) {
+ {
+ // Message only has extension in database1_
+ vector<int> numbers;
+ EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Foo", &numbers));
+ ASSERT_EQ(1, numbers.size());
+ EXPECT_EQ(3, numbers[0]);
+ }
+
+ {
+ // Message only has extension in database2_
+ vector<int> numbers;
+ EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Bar", &numbers));
+ ASSERT_EQ(1, numbers.size());
+ EXPECT_EQ(5, numbers[0]);
+ }
+
+ {
+ // Merge results from the two databases.
+ vector<int> numbers;
+ EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Baz", &numbers));
+ ASSERT_EQ(2, numbers.size());
+ sort(numbers.begin(), numbers.end());
+ EXPECT_EQ(12, numbers[0]);
+ EXPECT_EQ(13, numbers[1]);
+ }
+
+ {
+ vector<int> numbers;
+ EXPECT_TRUE(reverse_merged_.FindAllExtensionNumbers("Baz", &numbers));
+ ASSERT_EQ(2, numbers.size());
+ sort(numbers.begin(), numbers.end());
+ EXPECT_EQ(12, numbers[0]);
+ EXPECT_EQ(13, numbers[1]);
+ }
+
+ {
+ // Can't find extensions for a non-existent message.
+ vector<int> numbers;
+ EXPECT_FALSE(reverse_merged_.FindAllExtensionNumbers("Blah", &numbers));
+ }
+}
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc b/src/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc
new file mode 100644
index 0000000..55aebfd
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc
@@ -0,0 +1,4034 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file makes extensive use of RFC 3092. :)
+
+#include <vector>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_custom_options.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace descriptor_unittest {
+
+// Some helpers to make assembling descriptors faster.
+DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) {
+ DescriptorProto* result = file->add_message_type();
+ result->set_name(name);
+ return result;
+}
+
+DescriptorProto* AddNestedMessage(DescriptorProto* parent, const string& name) {
+ DescriptorProto* result = parent->add_nested_type();
+ result->set_name(name);
+ return result;
+}
+
+EnumDescriptorProto* AddEnum(FileDescriptorProto* file, const string& name) {
+ EnumDescriptorProto* result = file->add_enum_type();
+ result->set_name(name);
+ return result;
+}
+
+EnumDescriptorProto* AddNestedEnum(DescriptorProto* parent,
+ const string& name) {
+ EnumDescriptorProto* result = parent->add_enum_type();
+ result->set_name(name);
+ return result;
+}
+
+ServiceDescriptorProto* AddService(FileDescriptorProto* file,
+ const string& name) {
+ ServiceDescriptorProto* result = file->add_service();
+ result->set_name(name);
+ return result;
+}
+
+FieldDescriptorProto* AddField(DescriptorProto* parent,
+ const string& name, int number,
+ FieldDescriptorProto::Label label,
+ FieldDescriptorProto::Type type) {
+ FieldDescriptorProto* result = parent->add_field();
+ result->set_name(name);
+ result->set_number(number);
+ result->set_label(label);
+ result->set_type(type);
+ return result;
+}
+
+FieldDescriptorProto* AddExtension(FileDescriptorProto* file,
+ const string& extendee,
+ const string& name, int number,
+ FieldDescriptorProto::Label label,
+ FieldDescriptorProto::Type type) {
+ FieldDescriptorProto* result = file->add_extension();
+ result->set_name(name);
+ result->set_number(number);
+ result->set_label(label);
+ result->set_type(type);
+ result->set_extendee(extendee);
+ return result;
+}
+
+FieldDescriptorProto* AddNestedExtension(DescriptorProto* parent,
+ const string& extendee,
+ const string& name, int number,
+ FieldDescriptorProto::Label label,
+ FieldDescriptorProto::Type type) {
+ FieldDescriptorProto* result = parent->add_extension();
+ result->set_name(name);
+ result->set_number(number);
+ result->set_label(label);
+ result->set_type(type);
+ result->set_extendee(extendee);
+ return result;
+}
+
+DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent,
+ int start, int end) {
+ DescriptorProto::ExtensionRange* result = parent->add_extension_range();
+ result->set_start(start);
+ result->set_end(end);
+ return result;
+}
+
+EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto,
+ const string& name, int number) {
+ EnumValueDescriptorProto* result = enum_proto->add_value();
+ result->set_name(name);
+ result->set_number(number);
+ return result;
+}
+
+MethodDescriptorProto* AddMethod(ServiceDescriptorProto* service,
+ const string& name,
+ const string& input_type,
+ const string& output_type) {
+ MethodDescriptorProto* result = service->add_method();
+ result->set_name(name);
+ result->set_input_type(input_type);
+ result->set_output_type(output_type);
+ return result;
+}
+
+// Empty enums technically aren't allowed. We need to insert a dummy value
+// into them.
+void AddEmptyEnum(FileDescriptorProto* file, const string& name) {
+ AddEnumValue(AddEnum(file, name), name + "_DUMMY", 1);
+}
+
+// ===================================================================
+
+// Test simple files.
+class FileDescriptorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Build descriptors for the following definitions:
+ //
+ // // in "foo.proto"
+ // message FooMessage { extensions 1; }
+ // enum FooEnum {FOO_ENUM_VALUE = 1;}
+ // service FooService {}
+ // extend FooMessage { optional int32 foo_extension = 1; }
+ //
+ // // in "bar.proto"
+ // package bar_package;
+ // message BarMessage { extensions 1; }
+ // enum BarEnum {BAR_ENUM_VALUE = 1;}
+ // service BarService {}
+ // extend BarMessage { optional int32 bar_extension = 1; }
+ //
+ // Also, we have an empty file "baz.proto". This file's purpose is to
+ // make sure that even though it has the same package as foo.proto,
+ // searching it for members of foo.proto won't work.
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+ AddExtensionRange(AddMessage(&foo_file, "FooMessage"), 1, 2);
+ AddEnumValue(AddEnum(&foo_file, "FooEnum"), "FOO_ENUM_VALUE", 1);
+ AddService(&foo_file, "FooService");
+ AddExtension(&foo_file, "FooMessage", "foo_extension", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("bar_package");
+ bar_file.add_dependency("foo.proto");
+ AddExtensionRange(AddMessage(&bar_file, "BarMessage"), 1, 2);
+ AddEnumValue(AddEnum(&bar_file, "BarEnum"), "BAR_ENUM_VALUE", 1);
+ AddService(&bar_file, "BarService");
+ AddExtension(&bar_file, "bar_package.BarMessage", "bar_extension", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ FileDescriptorProto baz_file;
+ baz_file.set_name("baz.proto");
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != NULL);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != NULL);
+
+ baz_file_ = pool_.BuildFile(baz_file);
+ ASSERT_TRUE(baz_file_ != NULL);
+
+ ASSERT_EQ(1, foo_file_->message_type_count());
+ foo_message_ = foo_file_->message_type(0);
+ ASSERT_EQ(1, foo_file_->enum_type_count());
+ foo_enum_ = foo_file_->enum_type(0);
+ ASSERT_EQ(1, foo_enum_->value_count());
+ foo_enum_value_ = foo_enum_->value(0);
+ ASSERT_EQ(1, foo_file_->service_count());
+ foo_service_ = foo_file_->service(0);
+ ASSERT_EQ(1, foo_file_->extension_count());
+ foo_extension_ = foo_file_->extension(0);
+
+ ASSERT_EQ(1, bar_file_->message_type_count());
+ bar_message_ = bar_file_->message_type(0);
+ ASSERT_EQ(1, bar_file_->enum_type_count());
+ bar_enum_ = bar_file_->enum_type(0);
+ ASSERT_EQ(1, bar_enum_->value_count());
+ bar_enum_value_ = bar_enum_->value(0);
+ ASSERT_EQ(1, bar_file_->service_count());
+ bar_service_ = bar_file_->service(0);
+ ASSERT_EQ(1, bar_file_->extension_count());
+ bar_extension_ = bar_file_->extension(0);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+ const FileDescriptor* baz_file_;
+
+ const Descriptor* foo_message_;
+ const EnumDescriptor* foo_enum_;
+ const EnumValueDescriptor* foo_enum_value_;
+ const ServiceDescriptor* foo_service_;
+ const FieldDescriptor* foo_extension_;
+
+ const Descriptor* bar_message_;
+ const EnumDescriptor* bar_enum_;
+ const EnumValueDescriptor* bar_enum_value_;
+ const ServiceDescriptor* bar_service_;
+ const FieldDescriptor* bar_extension_;
+};
+
+TEST_F(FileDescriptorTest, Name) {
+ EXPECT_EQ("foo.proto", foo_file_->name());
+ EXPECT_EQ("bar.proto", bar_file_->name());
+ EXPECT_EQ("baz.proto", baz_file_->name());
+}
+
+TEST_F(FileDescriptorTest, Package) {
+ EXPECT_EQ("", foo_file_->package());
+ EXPECT_EQ("bar_package", bar_file_->package());
+}
+
+TEST_F(FileDescriptorTest, Dependencies) {
+ EXPECT_EQ(0, foo_file_->dependency_count());
+ EXPECT_EQ(1, bar_file_->dependency_count());
+ EXPECT_EQ(foo_file_, bar_file_->dependency(0));
+}
+
+TEST_F(FileDescriptorTest, FindMessageTypeByName) {
+ EXPECT_EQ(foo_message_, foo_file_->FindMessageTypeByName("FooMessage"));
+ EXPECT_EQ(bar_message_, bar_file_->FindMessageTypeByName("BarMessage"));
+
+ EXPECT_TRUE(foo_file_->FindMessageTypeByName("BarMessage") == NULL);
+ EXPECT_TRUE(bar_file_->FindMessageTypeByName("FooMessage") == NULL);
+ EXPECT_TRUE(baz_file_->FindMessageTypeByName("FooMessage") == NULL);
+
+ EXPECT_TRUE(foo_file_->FindMessageTypeByName("NoSuchMessage") == NULL);
+ EXPECT_TRUE(foo_file_->FindMessageTypeByName("FooEnum") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindEnumTypeByName) {
+ EXPECT_EQ(foo_enum_, foo_file_->FindEnumTypeByName("FooEnum"));
+ EXPECT_EQ(bar_enum_, bar_file_->FindEnumTypeByName("BarEnum"));
+
+ EXPECT_TRUE(foo_file_->FindEnumTypeByName("BarEnum") == NULL);
+ EXPECT_TRUE(bar_file_->FindEnumTypeByName("FooEnum") == NULL);
+ EXPECT_TRUE(baz_file_->FindEnumTypeByName("FooEnum") == NULL);
+
+ EXPECT_TRUE(foo_file_->FindEnumTypeByName("NoSuchEnum") == NULL);
+ EXPECT_TRUE(foo_file_->FindEnumTypeByName("FooMessage") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindEnumValueByName) {
+ EXPECT_EQ(foo_enum_value_, foo_file_->FindEnumValueByName("FOO_ENUM_VALUE"));
+ EXPECT_EQ(bar_enum_value_, bar_file_->FindEnumValueByName("BAR_ENUM_VALUE"));
+
+ EXPECT_TRUE(foo_file_->FindEnumValueByName("BAR_ENUM_VALUE") == NULL);
+ EXPECT_TRUE(bar_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
+ EXPECT_TRUE(baz_file_->FindEnumValueByName("FOO_ENUM_VALUE") == NULL);
+
+ EXPECT_TRUE(foo_file_->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
+ EXPECT_TRUE(foo_file_->FindEnumValueByName("FooMessage") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindServiceByName) {
+ EXPECT_EQ(foo_service_, foo_file_->FindServiceByName("FooService"));
+ EXPECT_EQ(bar_service_, bar_file_->FindServiceByName("BarService"));
+
+ EXPECT_TRUE(foo_file_->FindServiceByName("BarService") == NULL);
+ EXPECT_TRUE(bar_file_->FindServiceByName("FooService") == NULL);
+ EXPECT_TRUE(baz_file_->FindServiceByName("FooService") == NULL);
+
+ EXPECT_TRUE(foo_file_->FindServiceByName("NoSuchService") == NULL);
+ EXPECT_TRUE(foo_file_->FindServiceByName("FooMessage") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindExtensionByName) {
+ EXPECT_EQ(foo_extension_, foo_file_->FindExtensionByName("foo_extension"));
+ EXPECT_EQ(bar_extension_, bar_file_->FindExtensionByName("bar_extension"));
+
+ EXPECT_TRUE(foo_file_->FindExtensionByName("bar_extension") == NULL);
+ EXPECT_TRUE(bar_file_->FindExtensionByName("foo_extension") == NULL);
+ EXPECT_TRUE(baz_file_->FindExtensionByName("foo_extension") == NULL);
+
+ EXPECT_TRUE(foo_file_->FindExtensionByName("no_such_extension") == NULL);
+ EXPECT_TRUE(foo_file_->FindExtensionByName("FooMessage") == NULL);
+}
+
+TEST_F(FileDescriptorTest, FindExtensionByNumber) {
+ EXPECT_EQ(foo_extension_, pool_.FindExtensionByNumber(foo_message_, 1));
+ EXPECT_EQ(bar_extension_, pool_.FindExtensionByNumber(bar_message_, 1));
+
+ EXPECT_TRUE(pool_.FindExtensionByNumber(foo_message_, 2) == NULL);
+}
+
+TEST_F(FileDescriptorTest, BuildAgain) {
+ // Test that if te call BuildFile again on the same input we get the same
+ // FileDescriptor back.
+ FileDescriptorProto file;
+ foo_file_->CopyTo(&file);
+ EXPECT_EQ(foo_file_, pool_.BuildFile(file));
+
+ // But if we change the file then it won't work.
+ file.set_package("some.other.package");
+ EXPECT_TRUE(pool_.BuildFile(file) == NULL);
+}
+
+// ===================================================================
+
+// Test simple flat messages and fields.
+class DescriptorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Build descriptors for the following definitions:
+ //
+ // // in "foo.proto"
+ // message TestForeign {}
+ // enum TestEnum {}
+ //
+ // message TestMessage {
+ // required string foo = 1;
+ // optional TestEnum bar = 6;
+ // repeated TestForeign baz = 500000000;
+ // optional group qux = 15 {}
+ // }
+ //
+ // // in "bar.proto"
+ // package corge.grault;
+ // message TestMessage2 {
+ // required string foo = 1;
+ // required string bar = 2;
+ // required string quux = 6;
+ // }
+ //
+ // We cheat and use TestForeign as the type for qux rather than create
+ // an actual nested type.
+ //
+ // Since all primitive types (including string) use the same building
+ // code, there's no need to test each one individually.
+ //
+ // TestMessage2 is primarily here to test FindFieldByName and friends.
+ // All messages created from the same DescriptorPool share the same lookup
+ // table, so we need to insure that they don't interfere.
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+ AddMessage(&foo_file, "TestForeign");
+ AddEmptyEnum(&foo_file, "TestEnum");
+
+ DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
+ AddField(message, "foo", 1,
+ FieldDescriptorProto::LABEL_REQUIRED,
+ FieldDescriptorProto::TYPE_STRING);
+ AddField(message, "bar", 6,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_ENUM)
+ ->set_type_name("TestEnum");
+ AddField(message, "baz", 500000000,
+ FieldDescriptorProto::LABEL_REPEATED,
+ FieldDescriptorProto::TYPE_MESSAGE)
+ ->set_type_name("TestForeign");
+ AddField(message, "qux", 15,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_GROUP)
+ ->set_type_name("TestForeign");
+
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("corge.grault");
+
+ DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
+ AddField(message2, "foo", 1,
+ FieldDescriptorProto::LABEL_REQUIRED,
+ FieldDescriptorProto::TYPE_STRING);
+ AddField(message2, "bar", 2,
+ FieldDescriptorProto::LABEL_REQUIRED,
+ FieldDescriptorProto::TYPE_STRING);
+ AddField(message2, "quux", 6,
+ FieldDescriptorProto::LABEL_REQUIRED,
+ FieldDescriptorProto::TYPE_STRING);
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != NULL);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != NULL);
+
+ ASSERT_EQ(1, foo_file_->enum_type_count());
+ enum_ = foo_file_->enum_type(0);
+
+ ASSERT_EQ(2, foo_file_->message_type_count());
+ foreign_ = foo_file_->message_type(0);
+ message_ = foo_file_->message_type(1);
+
+ ASSERT_EQ(4, message_->field_count());
+ foo_ = message_->field(0);
+ bar_ = message_->field(1);
+ baz_ = message_->field(2);
+ qux_ = message_->field(3);
+
+ ASSERT_EQ(1, bar_file_->message_type_count());
+ message2_ = bar_file_->message_type(0);
+
+ ASSERT_EQ(3, message2_->field_count());
+ foo2_ = message2_->field(0);
+ bar2_ = message2_->field(1);
+ quux2_ = message2_->field(2);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+
+ const Descriptor* message_;
+ const Descriptor* message2_;
+ const Descriptor* foreign_;
+ const EnumDescriptor* enum_;
+
+ const FieldDescriptor* foo_;
+ const FieldDescriptor* bar_;
+ const FieldDescriptor* baz_;
+ const FieldDescriptor* qux_;
+
+ const FieldDescriptor* foo2_;
+ const FieldDescriptor* bar2_;
+ const FieldDescriptor* quux2_;
+};
+
+TEST_F(DescriptorTest, Name) {
+ EXPECT_EQ("TestMessage", message_->name());
+ EXPECT_EQ("TestMessage", message_->full_name());
+ EXPECT_EQ(foo_file_, message_->file());
+
+ EXPECT_EQ("TestMessage2", message2_->name());
+ EXPECT_EQ("corge.grault.TestMessage2", message2_->full_name());
+ EXPECT_EQ(bar_file_, message2_->file());
+}
+
+TEST_F(DescriptorTest, ContainingType) {
+ EXPECT_TRUE(message_->containing_type() == NULL);
+ EXPECT_TRUE(message2_->containing_type() == NULL);
+}
+
+TEST_F(DescriptorTest, FieldsByIndex) {
+ ASSERT_EQ(4, message_->field_count());
+ EXPECT_EQ(foo_, message_->field(0));
+ EXPECT_EQ(bar_, message_->field(1));
+ EXPECT_EQ(baz_, message_->field(2));
+ EXPECT_EQ(qux_, message_->field(3));
+}
+
+TEST_F(DescriptorTest, FindFieldByName) {
+ // All messages in the same DescriptorPool share a single lookup table for
+ // fields. So, in addition to testing that FindFieldByName finds the fields
+ // of the message, we need to test that it does *not* find the fields of
+ // *other* messages.
+
+ EXPECT_EQ(foo_, message_->FindFieldByName("foo"));
+ EXPECT_EQ(bar_, message_->FindFieldByName("bar"));
+ EXPECT_EQ(baz_, message_->FindFieldByName("baz"));
+ EXPECT_EQ(qux_, message_->FindFieldByName("qux"));
+ EXPECT_TRUE(message_->FindFieldByName("no_such_field") == NULL);
+ EXPECT_TRUE(message_->FindFieldByName("quux") == NULL);
+
+ EXPECT_EQ(foo2_ , message2_->FindFieldByName("foo" ));
+ EXPECT_EQ(bar2_ , message2_->FindFieldByName("bar" ));
+ EXPECT_EQ(quux2_, message2_->FindFieldByName("quux"));
+ EXPECT_TRUE(message2_->FindFieldByName("baz") == NULL);
+ EXPECT_TRUE(message2_->FindFieldByName("qux") == NULL);
+}
+
+TEST_F(DescriptorTest, FindFieldByNumber) {
+ EXPECT_EQ(foo_, message_->FindFieldByNumber(1));
+ EXPECT_EQ(bar_, message_->FindFieldByNumber(6));
+ EXPECT_EQ(baz_, message_->FindFieldByNumber(500000000));
+ EXPECT_EQ(qux_, message_->FindFieldByNumber(15));
+ EXPECT_TRUE(message_->FindFieldByNumber(837592) == NULL);
+ EXPECT_TRUE(message_->FindFieldByNumber(2) == NULL);
+
+ EXPECT_EQ(foo2_ , message2_->FindFieldByNumber(1));
+ EXPECT_EQ(bar2_ , message2_->FindFieldByNumber(2));
+ EXPECT_EQ(quux2_, message2_->FindFieldByNumber(6));
+ EXPECT_TRUE(message2_->FindFieldByNumber(15) == NULL);
+ EXPECT_TRUE(message2_->FindFieldByNumber(500000000) == NULL);
+}
+
+TEST_F(DescriptorTest, FieldName) {
+ EXPECT_EQ("foo", foo_->name());
+ EXPECT_EQ("bar", bar_->name());
+ EXPECT_EQ("baz", baz_->name());
+ EXPECT_EQ("qux", qux_->name());
+}
+
+TEST_F(DescriptorTest, FieldFullName) {
+ EXPECT_EQ("TestMessage.foo", foo_->full_name());
+ EXPECT_EQ("TestMessage.bar", bar_->full_name());
+ EXPECT_EQ("TestMessage.baz", baz_->full_name());
+ EXPECT_EQ("TestMessage.qux", qux_->full_name());
+
+ EXPECT_EQ("corge.grault.TestMessage2.foo", foo2_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.bar", bar2_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.quux", quux2_->full_name());
+}
+
+TEST_F(DescriptorTest, FieldFile) {
+ EXPECT_EQ(foo_file_, foo_->file());
+ EXPECT_EQ(foo_file_, bar_->file());
+ EXPECT_EQ(foo_file_, baz_->file());
+ EXPECT_EQ(foo_file_, qux_->file());
+
+ EXPECT_EQ(bar_file_, foo2_->file());
+ EXPECT_EQ(bar_file_, bar2_->file());
+ EXPECT_EQ(bar_file_, quux2_->file());
+}
+
+TEST_F(DescriptorTest, FieldIndex) {
+ EXPECT_EQ(0, foo_->index());
+ EXPECT_EQ(1, bar_->index());
+ EXPECT_EQ(2, baz_->index());
+ EXPECT_EQ(3, qux_->index());
+}
+
+TEST_F(DescriptorTest, FieldNumber) {
+ EXPECT_EQ( 1, foo_->number());
+ EXPECT_EQ( 6, bar_->number());
+ EXPECT_EQ(500000000, baz_->number());
+ EXPECT_EQ( 15, qux_->number());
+}
+
+TEST_F(DescriptorTest, FieldType) {
+ EXPECT_EQ(FieldDescriptor::TYPE_STRING , foo_->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_ENUM , bar_->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_GROUP , qux_->type());
+}
+
+TEST_F(DescriptorTest, FieldLabel) {
+ EXPECT_EQ(FieldDescriptor::LABEL_REQUIRED, foo_->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, baz_->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, qux_->label());
+
+ EXPECT_TRUE (foo_->is_required());
+ EXPECT_FALSE(foo_->is_optional());
+ EXPECT_FALSE(foo_->is_repeated());
+
+ EXPECT_FALSE(bar_->is_required());
+ EXPECT_TRUE (bar_->is_optional());
+ EXPECT_FALSE(bar_->is_repeated());
+
+ EXPECT_FALSE(baz_->is_required());
+ EXPECT_FALSE(baz_->is_optional());
+ EXPECT_TRUE (baz_->is_repeated());
+}
+
+TEST_F(DescriptorTest, FieldHasDefault) {
+ EXPECT_FALSE(foo_->has_default_value());
+ EXPECT_FALSE(bar_->has_default_value());
+ EXPECT_FALSE(baz_->has_default_value());
+ EXPECT_FALSE(qux_->has_default_value());
+}
+
+TEST_F(DescriptorTest, FieldContainingType) {
+ EXPECT_EQ(message_, foo_->containing_type());
+ EXPECT_EQ(message_, bar_->containing_type());
+ EXPECT_EQ(message_, baz_->containing_type());
+ EXPECT_EQ(message_, qux_->containing_type());
+
+ EXPECT_EQ(message2_, foo2_ ->containing_type());
+ EXPECT_EQ(message2_, bar2_ ->containing_type());
+ EXPECT_EQ(message2_, quux2_->containing_type());
+}
+
+TEST_F(DescriptorTest, FieldMessageType) {
+ EXPECT_TRUE(foo_->message_type() == NULL);
+ EXPECT_TRUE(bar_->message_type() == NULL);
+
+ EXPECT_EQ(foreign_, baz_->message_type());
+ EXPECT_EQ(foreign_, qux_->message_type());
+}
+
+TEST_F(DescriptorTest, FieldEnumType) {
+ EXPECT_TRUE(foo_->enum_type() == NULL);
+ EXPECT_TRUE(baz_->enum_type() == NULL);
+ EXPECT_TRUE(qux_->enum_type() == NULL);
+
+ EXPECT_EQ(enum_, bar_->enum_type());
+}
+
+// ===================================================================
+
+class StylizedFieldNamesTest : public testing::Test {
+ protected:
+ void SetUp() {
+ FileDescriptorProto file;
+ file.set_name("foo.proto");
+
+ AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
+
+ DescriptorProto* message = AddMessage(&file, "TestMessage");
+ AddField(message, "foo_foo", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "FooBar", 2,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "fooBaz", 3,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "fooFoo", 4, // Camel-case conflict with foo_foo.
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddField(message, "foobar", 5, // Lower-case conflict with FooBar.
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "barFoo", 4, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddNestedExtension(message, "ExtendableMessage", "barbar", 5, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "BazBar", 12,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "bazFoo", 14, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&file, "ExtendableMessage", "bazbar", 15, // Conflict
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ file_ = pool_.BuildFile(file);
+ ASSERT_TRUE(file_ != NULL);
+ ASSERT_EQ(2, file_->message_type_count());
+ message_ = file_->message_type(1);
+ ASSERT_EQ("TestMessage", message_->name());
+ ASSERT_EQ(5, message_->field_count());
+ ASSERT_EQ(5, message_->extension_count());
+ ASSERT_EQ(5, file_->extension_count());
+ }
+
+ DescriptorPool pool_;
+ const FileDescriptor* file_;
+ const Descriptor* message_;
+};
+
+TEST_F(StylizedFieldNamesTest, LowercaseName) {
+ EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
+ EXPECT_EQ("foobar" , message_->field(1)->lowercase_name());
+ EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name());
+ EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name());
+ EXPECT_EQ("foobar" , message_->field(4)->lowercase_name());
+
+ EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
+ EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name());
+ EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name());
+ EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name());
+ EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name());
+
+ EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
+ EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name());
+ EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name());
+ EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name());
+ EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name());
+}
+
+TEST_F(StylizedFieldNamesTest, CamelcaseName) {
+ EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
+ EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
+ EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
+ EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
+ EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
+
+ EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
+ EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
+ EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
+ EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
+ EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
+
+ EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
+ EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
+ EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
+ EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
+ EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
+}
+
+TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
+ EXPECT_EQ(message_->field(0),
+ message_->FindFieldByLowercaseName("foo_foo"));
+ EXPECT_EQ(message_->field(1),
+ message_->FindFieldByLowercaseName("foobar"));
+ EXPECT_EQ(message_->field(2),
+ message_->FindFieldByLowercaseName("foobaz"));
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL);
+ EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL);
+
+ EXPECT_EQ(message_->extension(0),
+ message_->FindExtensionByLowercaseName("bar_foo"));
+ EXPECT_EQ(message_->extension(1),
+ message_->FindExtensionByLowercaseName("barbar"));
+ EXPECT_EQ(message_->extension(2),
+ message_->FindExtensionByLowercaseName("barbaz"));
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL);
+
+ EXPECT_EQ(file_->extension(0),
+ file_->FindExtensionByLowercaseName("baz_foo"));
+ EXPECT_EQ(file_->extension(1),
+ file_->FindExtensionByLowercaseName("bazbar"));
+ EXPECT_EQ(file_->extension(2),
+ file_->FindExtensionByLowercaseName("bazbaz"));
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL);
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL);
+ EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL);
+}
+
+TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
+ EXPECT_EQ(message_->field(0),
+ message_->FindFieldByCamelcaseName("fooFoo"));
+ EXPECT_EQ(message_->field(1),
+ message_->FindFieldByCamelcaseName("fooBar"));
+ EXPECT_EQ(message_->field(2),
+ message_->FindFieldByCamelcaseName("fooBaz"));
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL);
+ EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL);
+
+ EXPECT_EQ(message_->extension(0),
+ message_->FindExtensionByCamelcaseName("barFoo"));
+ EXPECT_EQ(message_->extension(1),
+ message_->FindExtensionByCamelcaseName("barBar"));
+ EXPECT_EQ(message_->extension(2),
+ message_->FindExtensionByCamelcaseName("barBaz"));
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
+
+ EXPECT_EQ(file_->extension(0),
+ file_->FindExtensionByCamelcaseName("bazFoo"));
+ EXPECT_EQ(file_->extension(1),
+ file_->FindExtensionByCamelcaseName("bazBar"));
+ EXPECT_EQ(file_->extension(2),
+ file_->FindExtensionByCamelcaseName("bazBaz"));
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL);
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL);
+ EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
+}
+
+// ===================================================================
+
+// Test enum descriptors.
+class EnumDescriptorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Build descriptors for the following definitions:
+ //
+ // // in "foo.proto"
+ // enum TestEnum {
+ // FOO = 1;
+ // BAR = 2;
+ // }
+ //
+ // // in "bar.proto"
+ // package corge.grault;
+ // enum TestEnum2 {
+ // FOO = 1;
+ // BAZ = 3;
+ // }
+ //
+ // TestEnum2 is primarily here to test FindValueByName and friends.
+ // All enums created from the same DescriptorPool share the same lookup
+ // table, so we need to insure that they don't interfere.
+
+ // TestEnum
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ EnumDescriptorProto* enum_proto = AddEnum(&foo_file, "TestEnum");
+ AddEnumValue(enum_proto, "FOO", 1);
+ AddEnumValue(enum_proto, "BAR", 2);
+
+ // TestEnum2
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("corge.grault");
+
+ EnumDescriptorProto* enum2_proto = AddEnum(&bar_file, "TestEnum2");
+ AddEnumValue(enum2_proto, "FOO", 1);
+ AddEnumValue(enum2_proto, "BAZ", 3);
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != NULL);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != NULL);
+
+ ASSERT_EQ(1, foo_file_->enum_type_count());
+ enum_ = foo_file_->enum_type(0);
+
+ ASSERT_EQ(2, enum_->value_count());
+ foo_ = enum_->value(0);
+ bar_ = enum_->value(1);
+
+ ASSERT_EQ(1, bar_file_->enum_type_count());
+ enum2_ = bar_file_->enum_type(0);
+
+ ASSERT_EQ(2, enum2_->value_count());
+ foo2_ = enum2_->value(0);
+ baz2_ = enum2_->value(1);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+
+ const EnumDescriptor* enum_;
+ const EnumDescriptor* enum2_;
+
+ const EnumValueDescriptor* foo_;
+ const EnumValueDescriptor* bar_;
+
+ const EnumValueDescriptor* foo2_;
+ const EnumValueDescriptor* baz2_;
+};
+
+TEST_F(EnumDescriptorTest, Name) {
+ EXPECT_EQ("TestEnum", enum_->name());
+ EXPECT_EQ("TestEnum", enum_->full_name());
+ EXPECT_EQ(foo_file_, enum_->file());
+
+ EXPECT_EQ("TestEnum2", enum2_->name());
+ EXPECT_EQ("corge.grault.TestEnum2", enum2_->full_name());
+ EXPECT_EQ(bar_file_, enum2_->file());
+}
+
+TEST_F(EnumDescriptorTest, ContainingType) {
+ EXPECT_TRUE(enum_->containing_type() == NULL);
+ EXPECT_TRUE(enum2_->containing_type() == NULL);
+}
+
+TEST_F(EnumDescriptorTest, ValuesByIndex) {
+ ASSERT_EQ(2, enum_->value_count());
+ EXPECT_EQ(foo_, enum_->value(0));
+ EXPECT_EQ(bar_, enum_->value(1));
+}
+
+TEST_F(EnumDescriptorTest, FindValueByName) {
+ EXPECT_EQ(foo_ , enum_ ->FindValueByName("FOO"));
+ EXPECT_EQ(bar_ , enum_ ->FindValueByName("BAR"));
+ EXPECT_EQ(foo2_, enum2_->FindValueByName("FOO"));
+ EXPECT_EQ(baz2_, enum2_->FindValueByName("BAZ"));
+
+ EXPECT_TRUE(enum_ ->FindValueByName("NO_SUCH_VALUE") == NULL);
+ EXPECT_TRUE(enum_ ->FindValueByName("BAZ" ) == NULL);
+ EXPECT_TRUE(enum2_->FindValueByName("BAR" ) == NULL);
+}
+
+TEST_F(EnumDescriptorTest, FindValueByNumber) {
+ EXPECT_EQ(foo_ , enum_ ->FindValueByNumber(1));
+ EXPECT_EQ(bar_ , enum_ ->FindValueByNumber(2));
+ EXPECT_EQ(foo2_, enum2_->FindValueByNumber(1));
+ EXPECT_EQ(baz2_, enum2_->FindValueByNumber(3));
+
+ EXPECT_TRUE(enum_ ->FindValueByNumber(416) == NULL);
+ EXPECT_TRUE(enum_ ->FindValueByNumber(3) == NULL);
+ EXPECT_TRUE(enum2_->FindValueByNumber(2) == NULL);
+}
+
+TEST_F(EnumDescriptorTest, ValueName) {
+ EXPECT_EQ("FOO", foo_->name());
+ EXPECT_EQ("BAR", bar_->name());
+}
+
+TEST_F(EnumDescriptorTest, ValueFullName) {
+ EXPECT_EQ("FOO", foo_->full_name());
+ EXPECT_EQ("BAR", bar_->full_name());
+ EXPECT_EQ("corge.grault.FOO", foo2_->full_name());
+ EXPECT_EQ("corge.grault.BAZ", baz2_->full_name());
+}
+
+TEST_F(EnumDescriptorTest, ValueIndex) {
+ EXPECT_EQ(0, foo_->index());
+ EXPECT_EQ(1, bar_->index());
+}
+
+TEST_F(EnumDescriptorTest, ValueNumber) {
+ EXPECT_EQ(1, foo_->number());
+ EXPECT_EQ(2, bar_->number());
+}
+
+TEST_F(EnumDescriptorTest, ValueType) {
+ EXPECT_EQ(enum_ , foo_ ->type());
+ EXPECT_EQ(enum_ , bar_ ->type());
+ EXPECT_EQ(enum2_, foo2_->type());
+ EXPECT_EQ(enum2_, baz2_->type());
+}
+
+// ===================================================================
+
+// Test service descriptors.
+class ServiceDescriptorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Build descriptors for the following messages and service:
+ // // in "foo.proto"
+ // message FooRequest {}
+ // message FooResponse {}
+ // message BarRequest {}
+ // message BarResponse {}
+ // message BazRequest {}
+ // message BazResponse {}
+ //
+ // service TestService {
+ // rpc Foo(FooRequest) returns (FooResponse);
+ // rpc Bar(BarRequest) returns (BarResponse);
+ // }
+ //
+ // // in "bar.proto"
+ // package corge.grault
+ // service TestService2 {
+ // rpc Foo(FooRequest) returns (FooResponse);
+ // rpc Baz(BazRequest) returns (BazResponse);
+ // }
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ AddMessage(&foo_file, "FooRequest");
+ AddMessage(&foo_file, "FooResponse");
+ AddMessage(&foo_file, "BarRequest");
+ AddMessage(&foo_file, "BarResponse");
+ AddMessage(&foo_file, "BazRequest");
+ AddMessage(&foo_file, "BazResponse");
+
+ ServiceDescriptorProto* service = AddService(&foo_file, "TestService");
+ AddMethod(service, "Foo", "FooRequest", "FooResponse");
+ AddMethod(service, "Bar", "BarRequest", "BarResponse");
+
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("corge.grault");
+ bar_file.add_dependency("foo.proto");
+
+ ServiceDescriptorProto* service2 = AddService(&bar_file, "TestService2");
+ AddMethod(service2, "Foo", "FooRequest", "FooResponse");
+ AddMethod(service2, "Baz", "BazRequest", "BazResponse");
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != NULL);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != NULL);
+
+ ASSERT_EQ(6, foo_file_->message_type_count());
+ foo_request_ = foo_file_->message_type(0);
+ foo_response_ = foo_file_->message_type(1);
+ bar_request_ = foo_file_->message_type(2);
+ bar_response_ = foo_file_->message_type(3);
+ baz_request_ = foo_file_->message_type(4);
+ baz_response_ = foo_file_->message_type(5);
+
+ ASSERT_EQ(1, foo_file_->service_count());
+ service_ = foo_file_->service(0);
+
+ ASSERT_EQ(2, service_->method_count());
+ foo_ = service_->method(0);
+ bar_ = service_->method(1);
+
+ ASSERT_EQ(1, bar_file_->service_count());
+ service2_ = bar_file_->service(0);
+
+ ASSERT_EQ(2, service2_->method_count());
+ foo2_ = service2_->method(0);
+ baz2_ = service2_->method(1);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+
+ const Descriptor* foo_request_;
+ const Descriptor* foo_response_;
+ const Descriptor* bar_request_;
+ const Descriptor* bar_response_;
+ const Descriptor* baz_request_;
+ const Descriptor* baz_response_;
+
+ const ServiceDescriptor* service_;
+ const ServiceDescriptor* service2_;
+
+ const MethodDescriptor* foo_;
+ const MethodDescriptor* bar_;
+
+ const MethodDescriptor* foo2_;
+ const MethodDescriptor* baz2_;
+};
+
+TEST_F(ServiceDescriptorTest, Name) {
+ EXPECT_EQ("TestService", service_->name());
+ EXPECT_EQ("TestService", service_->full_name());
+ EXPECT_EQ(foo_file_, service_->file());
+
+ EXPECT_EQ("TestService2", service2_->name());
+ EXPECT_EQ("corge.grault.TestService2", service2_->full_name());
+ EXPECT_EQ(bar_file_, service2_->file());
+}
+
+TEST_F(ServiceDescriptorTest, MethodsByIndex) {
+ ASSERT_EQ(2, service_->method_count());
+ EXPECT_EQ(foo_, service_->method(0));
+ EXPECT_EQ(bar_, service_->method(1));
+}
+
+TEST_F(ServiceDescriptorTest, FindMethodByName) {
+ EXPECT_EQ(foo_ , service_ ->FindMethodByName("Foo"));
+ EXPECT_EQ(bar_ , service_ ->FindMethodByName("Bar"));
+ EXPECT_EQ(foo2_, service2_->FindMethodByName("Foo"));
+ EXPECT_EQ(baz2_, service2_->FindMethodByName("Baz"));
+
+ EXPECT_TRUE(service_ ->FindMethodByName("NoSuchMethod") == NULL);
+ EXPECT_TRUE(service_ ->FindMethodByName("Baz" ) == NULL);
+ EXPECT_TRUE(service2_->FindMethodByName("Bar" ) == NULL);
+}
+
+TEST_F(ServiceDescriptorTest, MethodName) {
+ EXPECT_EQ("Foo", foo_->name());
+ EXPECT_EQ("Bar", bar_->name());
+}
+
+TEST_F(ServiceDescriptorTest, MethodFullName) {
+ EXPECT_EQ("TestService.Foo", foo_->full_name());
+ EXPECT_EQ("TestService.Bar", bar_->full_name());
+ EXPECT_EQ("corge.grault.TestService2.Foo", foo2_->full_name());
+ EXPECT_EQ("corge.grault.TestService2.Baz", baz2_->full_name());
+}
+
+TEST_F(ServiceDescriptorTest, MethodIndex) {
+ EXPECT_EQ(0, foo_->index());
+ EXPECT_EQ(1, bar_->index());
+}
+
+TEST_F(ServiceDescriptorTest, MethodParent) {
+ EXPECT_EQ(service_, foo_->service());
+ EXPECT_EQ(service_, bar_->service());
+}
+
+TEST_F(ServiceDescriptorTest, MethodInputType) {
+ EXPECT_EQ(foo_request_, foo_->input_type());
+ EXPECT_EQ(bar_request_, bar_->input_type());
+}
+
+TEST_F(ServiceDescriptorTest, MethodOutputType) {
+ EXPECT_EQ(foo_response_, foo_->output_type());
+ EXPECT_EQ(bar_response_, bar_->output_type());
+}
+
+// ===================================================================
+
+// Test nested types.
+class NestedDescriptorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Build descriptors for the following definitions:
+ //
+ // // in "foo.proto"
+ // message TestMessage {
+ // message Foo {}
+ // message Bar {}
+ // enum Baz { A = 1; }
+ // enum Qux { B = 1; }
+ // }
+ //
+ // // in "bar.proto"
+ // package corge.grault;
+ // message TestMessage2 {
+ // message Foo {}
+ // message Baz {}
+ // enum Qux { A = 1; }
+ // enum Quux { C = 1; }
+ // }
+ //
+ // TestMessage2 is primarily here to test FindNestedTypeByName and friends.
+ // All messages created from the same DescriptorPool share the same lookup
+ // table, so we need to insure that they don't interfere.
+ //
+ // We add enum values to the enums in order to test searching for enum
+ // values across a message's scope.
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ DescriptorProto* message = AddMessage(&foo_file, "TestMessage");
+ AddNestedMessage(message, "Foo");
+ AddNestedMessage(message, "Bar");
+ EnumDescriptorProto* baz = AddNestedEnum(message, "Baz");
+ AddEnumValue(baz, "A", 1);
+ EnumDescriptorProto* qux = AddNestedEnum(message, "Qux");
+ AddEnumValue(qux, "B", 1);
+
+ FileDescriptorProto bar_file;
+ bar_file.set_name("bar.proto");
+ bar_file.set_package("corge.grault");
+
+ DescriptorProto* message2 = AddMessage(&bar_file, "TestMessage2");
+ AddNestedMessage(message2, "Foo");
+ AddNestedMessage(message2, "Baz");
+ EnumDescriptorProto* qux2 = AddNestedEnum(message2, "Qux");
+ AddEnumValue(qux2, "A", 1);
+ EnumDescriptorProto* quux2 = AddNestedEnum(message2, "Quux");
+ AddEnumValue(quux2, "C", 1);
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != NULL);
+
+ bar_file_ = pool_.BuildFile(bar_file);
+ ASSERT_TRUE(bar_file_ != NULL);
+
+ ASSERT_EQ(1, foo_file_->message_type_count());
+ message_ = foo_file_->message_type(0);
+
+ ASSERT_EQ(2, message_->nested_type_count());
+ foo_ = message_->nested_type(0);
+ bar_ = message_->nested_type(1);
+
+ ASSERT_EQ(2, message_->enum_type_count());
+ baz_ = message_->enum_type(0);
+ qux_ = message_->enum_type(1);
+
+ ASSERT_EQ(1, baz_->value_count());
+ a_ = baz_->value(0);
+ ASSERT_EQ(1, qux_->value_count());
+ b_ = qux_->value(0);
+
+ ASSERT_EQ(1, bar_file_->message_type_count());
+ message2_ = bar_file_->message_type(0);
+
+ ASSERT_EQ(2, message2_->nested_type_count());
+ foo2_ = message2_->nested_type(0);
+ baz2_ = message2_->nested_type(1);
+
+ ASSERT_EQ(2, message2_->enum_type_count());
+ qux2_ = message2_->enum_type(0);
+ quux2_ = message2_->enum_type(1);
+
+ ASSERT_EQ(1, qux2_->value_count());
+ a2_ = qux2_->value(0);
+ ASSERT_EQ(1, quux2_->value_count());
+ c2_ = quux2_->value(0);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+ const FileDescriptor* bar_file_;
+
+ const Descriptor* message_;
+ const Descriptor* message2_;
+
+ const Descriptor* foo_;
+ const Descriptor* bar_;
+ const EnumDescriptor* baz_;
+ const EnumDescriptor* qux_;
+ const EnumValueDescriptor* a_;
+ const EnumValueDescriptor* b_;
+
+ const Descriptor* foo2_;
+ const Descriptor* baz2_;
+ const EnumDescriptor* qux2_;
+ const EnumDescriptor* quux2_;
+ const EnumValueDescriptor* a2_;
+ const EnumValueDescriptor* c2_;
+};
+
+TEST_F(NestedDescriptorTest, MessageName) {
+ EXPECT_EQ("Foo", foo_ ->name());
+ EXPECT_EQ("Bar", bar_ ->name());
+ EXPECT_EQ("Foo", foo2_->name());
+ EXPECT_EQ("Baz", baz2_->name());
+
+ EXPECT_EQ("TestMessage.Foo", foo_->full_name());
+ EXPECT_EQ("TestMessage.Bar", bar_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.Foo", foo2_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.Baz", baz2_->full_name());
+}
+
+TEST_F(NestedDescriptorTest, MessageContainingType) {
+ EXPECT_EQ(message_ , foo_ ->containing_type());
+ EXPECT_EQ(message_ , bar_ ->containing_type());
+ EXPECT_EQ(message2_, foo2_->containing_type());
+ EXPECT_EQ(message2_, baz2_->containing_type());
+}
+
+TEST_F(NestedDescriptorTest, NestedMessagesByIndex) {
+ ASSERT_EQ(2, message_->nested_type_count());
+ EXPECT_EQ(foo_, message_->nested_type(0));
+ EXPECT_EQ(bar_, message_->nested_type(1));
+}
+
+TEST_F(NestedDescriptorTest, FindFieldByNameDoesntFindNestedTypes) {
+ EXPECT_TRUE(message_->FindFieldByName("Foo") == NULL);
+ EXPECT_TRUE(message_->FindFieldByName("Qux") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByName("Foo") == NULL);
+ EXPECT_TRUE(message_->FindExtensionByName("Qux") == NULL);
+}
+
+TEST_F(NestedDescriptorTest, FindNestedTypeByName) {
+ EXPECT_EQ(foo_ , message_ ->FindNestedTypeByName("Foo"));
+ EXPECT_EQ(bar_ , message_ ->FindNestedTypeByName("Bar"));
+ EXPECT_EQ(foo2_, message2_->FindNestedTypeByName("Foo"));
+ EXPECT_EQ(baz2_, message2_->FindNestedTypeByName("Baz"));
+
+ EXPECT_TRUE(message_ ->FindNestedTypeByName("NoSuchType") == NULL);
+ EXPECT_TRUE(message_ ->FindNestedTypeByName("Baz" ) == NULL);
+ EXPECT_TRUE(message2_->FindNestedTypeByName("Bar" ) == NULL);
+
+ EXPECT_TRUE(message_->FindNestedTypeByName("Qux") == NULL);
+}
+
+TEST_F(NestedDescriptorTest, EnumName) {
+ EXPECT_EQ("Baz" , baz_ ->name());
+ EXPECT_EQ("Qux" , qux_ ->name());
+ EXPECT_EQ("Qux" , qux2_->name());
+ EXPECT_EQ("Quux", quux2_->name());
+
+ EXPECT_EQ("TestMessage.Baz", baz_->full_name());
+ EXPECT_EQ("TestMessage.Qux", qux_->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.Qux" , qux2_ ->full_name());
+ EXPECT_EQ("corge.grault.TestMessage2.Quux", quux2_->full_name());
+}
+
+TEST_F(NestedDescriptorTest, EnumContainingType) {
+ EXPECT_EQ(message_ , baz_ ->containing_type());
+ EXPECT_EQ(message_ , qux_ ->containing_type());
+ EXPECT_EQ(message2_, qux2_ ->containing_type());
+ EXPECT_EQ(message2_, quux2_->containing_type());
+}
+
+TEST_F(NestedDescriptorTest, NestedEnumsByIndex) {
+ ASSERT_EQ(2, message_->nested_type_count());
+ EXPECT_EQ(foo_, message_->nested_type(0));
+ EXPECT_EQ(bar_, message_->nested_type(1));
+}
+
+TEST_F(NestedDescriptorTest, FindEnumTypeByName) {
+ EXPECT_EQ(baz_ , message_ ->FindEnumTypeByName("Baz" ));
+ EXPECT_EQ(qux_ , message_ ->FindEnumTypeByName("Qux" ));
+ EXPECT_EQ(qux2_ , message2_->FindEnumTypeByName("Qux" ));
+ EXPECT_EQ(quux2_, message2_->FindEnumTypeByName("Quux"));
+
+ EXPECT_TRUE(message_ ->FindEnumTypeByName("NoSuchType") == NULL);
+ EXPECT_TRUE(message_ ->FindEnumTypeByName("Quux" ) == NULL);
+ EXPECT_TRUE(message2_->FindEnumTypeByName("Baz" ) == NULL);
+
+ EXPECT_TRUE(message_->FindEnumTypeByName("Foo") == NULL);
+}
+
+TEST_F(NestedDescriptorTest, FindEnumValueByName) {
+ EXPECT_EQ(a_ , message_ ->FindEnumValueByName("A"));
+ EXPECT_EQ(b_ , message_ ->FindEnumValueByName("B"));
+ EXPECT_EQ(a2_, message2_->FindEnumValueByName("A"));
+ EXPECT_EQ(c2_, message2_->FindEnumValueByName("C"));
+
+ EXPECT_TRUE(message_ ->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
+ EXPECT_TRUE(message_ ->FindEnumValueByName("C" ) == NULL);
+ EXPECT_TRUE(message2_->FindEnumValueByName("B" ) == NULL);
+
+ EXPECT_TRUE(message_->FindEnumValueByName("Foo") == NULL);
+}
+
+// ===================================================================
+
+// Test extensions.
+class ExtensionDescriptorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ // Build descriptors for the following definitions:
+ //
+ // enum Baz {}
+ // message Qux {}
+ //
+ // message Foo {
+ // extensions 10 to 19;
+ // extensions 30 to 39;
+ // }
+ // extends Foo with optional int32 foo_int32 = 10;
+ // extends Foo with repeated TestEnum foo_enum = 19;
+ // message Bar {
+ // extends Foo with optional Qux foo_message = 30;
+ // // (using Qux as the group type)
+ // extends Foo with repeated group foo_group = 39;
+ // }
+
+ FileDescriptorProto foo_file;
+ foo_file.set_name("foo.proto");
+
+ AddEmptyEnum(&foo_file, "Baz");
+ AddMessage(&foo_file, "Qux");
+
+ DescriptorProto* foo = AddMessage(&foo_file, "Foo");
+ AddExtensionRange(foo, 10, 20);
+ AddExtensionRange(foo, 30, 40);
+
+ AddExtension(&foo_file, "Foo", "foo_int32", 10,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ AddExtension(&foo_file, "Foo", "foo_enum", 19,
+ FieldDescriptorProto::LABEL_REPEATED,
+ FieldDescriptorProto::TYPE_ENUM)
+ ->set_type_name("Baz");
+
+ DescriptorProto* bar = AddMessage(&foo_file, "Bar");
+ AddNestedExtension(bar, "Foo", "foo_message", 30,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_MESSAGE)
+ ->set_type_name("Qux");
+ AddNestedExtension(bar, "Foo", "foo_group", 39,
+ FieldDescriptorProto::LABEL_REPEATED,
+ FieldDescriptorProto::TYPE_GROUP)
+ ->set_type_name("Qux");
+
+ // Build the descriptors and get the pointers.
+ foo_file_ = pool_.BuildFile(foo_file);
+ ASSERT_TRUE(foo_file_ != NULL);
+
+ ASSERT_EQ(1, foo_file_->enum_type_count());
+ baz_ = foo_file_->enum_type(0);
+
+ ASSERT_EQ(3, foo_file_->message_type_count());
+ qux_ = foo_file_->message_type(0);
+ foo_ = foo_file_->message_type(1);
+ bar_ = foo_file_->message_type(2);
+ }
+
+ DescriptorPool pool_;
+
+ const FileDescriptor* foo_file_;
+
+ const Descriptor* foo_;
+ const Descriptor* bar_;
+ const EnumDescriptor* baz_;
+ const Descriptor* qux_;
+};
+
+TEST_F(ExtensionDescriptorTest, ExtensionRanges) {
+ EXPECT_EQ(0, bar_->extension_range_count());
+ ASSERT_EQ(2, foo_->extension_range_count());
+
+ EXPECT_EQ(10, foo_->extension_range(0)->start);
+ EXPECT_EQ(30, foo_->extension_range(1)->start);
+
+ EXPECT_EQ(20, foo_->extension_range(0)->end);
+ EXPECT_EQ(40, foo_->extension_range(1)->end);
+};
+
+TEST_F(ExtensionDescriptorTest, Extensions) {
+ EXPECT_EQ(0, foo_->extension_count());
+ ASSERT_EQ(2, foo_file_->extension_count());
+ ASSERT_EQ(2, bar_->extension_count());
+
+ EXPECT_TRUE(foo_file_->extension(0)->is_extension());
+ EXPECT_TRUE(foo_file_->extension(1)->is_extension());
+ EXPECT_TRUE(bar_->extension(0)->is_extension());
+ EXPECT_TRUE(bar_->extension(1)->is_extension());
+
+ EXPECT_EQ("foo_int32" , foo_file_->extension(0)->name());
+ EXPECT_EQ("foo_enum" , foo_file_->extension(1)->name());
+ EXPECT_EQ("foo_message", bar_->extension(0)->name());
+ EXPECT_EQ("foo_group" , bar_->extension(1)->name());
+
+ EXPECT_EQ(10, foo_file_->extension(0)->number());
+ EXPECT_EQ(19, foo_file_->extension(1)->number());
+ EXPECT_EQ(30, bar_->extension(0)->number());
+ EXPECT_EQ(39, bar_->extension(1)->number());
+
+ EXPECT_EQ(FieldDescriptor::TYPE_INT32 , foo_file_->extension(0)->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_ENUM , foo_file_->extension(1)->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_->extension(0)->type());
+ EXPECT_EQ(FieldDescriptor::TYPE_GROUP , bar_->extension(1)->type());
+
+ EXPECT_EQ(baz_, foo_file_->extension(1)->enum_type());
+ EXPECT_EQ(qux_, bar_->extension(0)->message_type());
+ EXPECT_EQ(qux_, bar_->extension(1)->message_type());
+
+ EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, foo_file_->extension(0)->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, foo_file_->extension(1)->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_OPTIONAL, bar_->extension(0)->label());
+ EXPECT_EQ(FieldDescriptor::LABEL_REPEATED, bar_->extension(1)->label());
+
+ EXPECT_EQ(foo_, foo_file_->extension(0)->containing_type());
+ EXPECT_EQ(foo_, foo_file_->extension(1)->containing_type());
+ EXPECT_EQ(foo_, bar_->extension(0)->containing_type());
+ EXPECT_EQ(foo_, bar_->extension(1)->containing_type());
+
+ EXPECT_TRUE(foo_file_->extension(0)->extension_scope() == NULL);
+ EXPECT_TRUE(foo_file_->extension(1)->extension_scope() == NULL);
+ EXPECT_EQ(bar_, bar_->extension(0)->extension_scope());
+ EXPECT_EQ(bar_, bar_->extension(1)->extension_scope());
+};
+
+TEST_F(ExtensionDescriptorTest, IsExtensionNumber) {
+ EXPECT_FALSE(foo_->IsExtensionNumber( 9));
+ EXPECT_TRUE (foo_->IsExtensionNumber(10));
+ EXPECT_TRUE (foo_->IsExtensionNumber(19));
+ EXPECT_FALSE(foo_->IsExtensionNumber(20));
+ EXPECT_FALSE(foo_->IsExtensionNumber(29));
+ EXPECT_TRUE (foo_->IsExtensionNumber(30));
+ EXPECT_TRUE (foo_->IsExtensionNumber(39));
+ EXPECT_FALSE(foo_->IsExtensionNumber(40));
+}
+
+TEST_F(ExtensionDescriptorTest, FindExtensionByName) {
+ // Note that FileDescriptor::FindExtensionByName() is tested by
+ // FileDescriptorTest.
+ ASSERT_EQ(2, bar_->extension_count());
+
+ EXPECT_EQ(bar_->extension(0), bar_->FindExtensionByName("foo_message"));
+ EXPECT_EQ(bar_->extension(1), bar_->FindExtensionByName("foo_group" ));
+
+ EXPECT_TRUE(bar_->FindExtensionByName("no_such_extension") == NULL);
+ EXPECT_TRUE(foo_->FindExtensionByName("foo_int32") == NULL);
+ EXPECT_TRUE(foo_->FindExtensionByName("foo_message") == NULL);
+}
+
+TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
+ vector<const FieldDescriptor*> extensions;
+ pool_.FindAllExtensions(foo_, &extensions);
+ ASSERT_EQ(4, extensions.size());
+ EXPECT_EQ(10, extensions[0]->number());
+ EXPECT_EQ(19, extensions[1]->number());
+ EXPECT_EQ(30, extensions[2]->number());
+ EXPECT_EQ(39, extensions[3]->number());
+}
+
+// ===================================================================
+
+class MiscTest : public testing::Test {
+ protected:
+ // Function which makes a field of the given type just to find out what its
+ // cpp_type is.
+ FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
+ FileDescriptorProto file_proto;
+ file_proto.set_name("foo.proto");
+ AddEmptyEnum(&file_proto, "DummyEnum");
+
+ DescriptorProto* message = AddMessage(&file_proto, "TestMessage");
+ FieldDescriptorProto* field =
+ AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL,
+ static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
+
+ if (type == FieldDescriptor::TYPE_MESSAGE ||
+ type == FieldDescriptor::TYPE_GROUP) {
+ field->set_type_name("TestMessage");
+ } else if (type == FieldDescriptor::TYPE_ENUM) {
+ field->set_type_name("DummyEnum");
+ }
+
+ // Build the descriptors and get the pointers.
+ DescriptorPool pool;
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+
+ if (file != NULL &&
+ file->message_type_count() == 1 &&
+ file->message_type(0)->field_count() == 1) {
+ return file->message_type(0)->field(0)->cpp_type();
+ } else {
+ return static_cast<FieldDescriptor::CppType>(0);
+ }
+ }
+};
+
+TEST_F(MiscTest, CppTypes) {
+ // Test that CPP types are assigned correctly.
+
+ typedef FieldDescriptor FD; // avoid ugly line wrapping
+
+ EXPECT_EQ(FD::CPPTYPE_DOUBLE , GetCppTypeForFieldType(FD::TYPE_DOUBLE ));
+ EXPECT_EQ(FD::CPPTYPE_FLOAT , GetCppTypeForFieldType(FD::TYPE_FLOAT ));
+ EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_INT64 ));
+ EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_UINT64 ));
+ EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_INT32 ));
+ EXPECT_EQ(FD::CPPTYPE_UINT64 , GetCppTypeForFieldType(FD::TYPE_FIXED64 ));
+ EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_FIXED32 ));
+ EXPECT_EQ(FD::CPPTYPE_BOOL , GetCppTypeForFieldType(FD::TYPE_BOOL ));
+ EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_STRING ));
+ EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_GROUP ));
+ EXPECT_EQ(FD::CPPTYPE_MESSAGE, GetCppTypeForFieldType(FD::TYPE_MESSAGE ));
+ EXPECT_EQ(FD::CPPTYPE_STRING , GetCppTypeForFieldType(FD::TYPE_BYTES ));
+ EXPECT_EQ(FD::CPPTYPE_UINT32 , GetCppTypeForFieldType(FD::TYPE_UINT32 ));
+ EXPECT_EQ(FD::CPPTYPE_ENUM , GetCppTypeForFieldType(FD::TYPE_ENUM ));
+ EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SFIXED32));
+ EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SFIXED64));
+ EXPECT_EQ(FD::CPPTYPE_INT32 , GetCppTypeForFieldType(FD::TYPE_SINT32 ));
+ EXPECT_EQ(FD::CPPTYPE_INT64 , GetCppTypeForFieldType(FD::TYPE_SINT64 ));
+}
+
+TEST_F(MiscTest, DefaultValues) {
+ // Test that setting default values works.
+ FileDescriptorProto file_proto;
+ file_proto.set_name("foo.proto");
+
+ EnumDescriptorProto* enum_type_proto = AddEnum(&file_proto, "DummyEnum");
+ AddEnumValue(enum_type_proto, "A", 1);
+ AddEnumValue(enum_type_proto, "B", 2);
+
+ DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
+
+ typedef FieldDescriptorProto FD; // avoid ugly line wrapping
+ const FD::Label label = FD::LABEL_OPTIONAL;
+
+ // Create fields of every CPP type with default values.
+ AddField(message_proto, "int32" , 1, label, FD::TYPE_INT32 )
+ ->set_default_value("-1");
+ AddField(message_proto, "int64" , 2, label, FD::TYPE_INT64 )
+ ->set_default_value("-1000000000000");
+ AddField(message_proto, "uint32", 3, label, FD::TYPE_UINT32)
+ ->set_default_value("42");
+ AddField(message_proto, "uint64", 4, label, FD::TYPE_UINT64)
+ ->set_default_value("2000000000000");
+ AddField(message_proto, "float" , 5, label, FD::TYPE_FLOAT )
+ ->set_default_value("4.5");
+ AddField(message_proto, "double", 6, label, FD::TYPE_DOUBLE)
+ ->set_default_value("10e100");
+ AddField(message_proto, "bool" , 7, label, FD::TYPE_BOOL )
+ ->set_default_value("true");
+ AddField(message_proto, "string", 8, label, FD::TYPE_STRING)
+ ->set_default_value("hello");
+ AddField(message_proto, "data" , 9, label, FD::TYPE_BYTES )
+ ->set_default_value("\\001\\002\\003");
+
+ FieldDescriptorProto* enum_field =
+ AddField(message_proto, "enum", 10, label, FD::TYPE_ENUM);
+ enum_field->set_type_name("DummyEnum");
+ enum_field->set_default_value("B");
+
+ // Strings are allowed to have empty defaults. (At one point, due to
+ // a bug, empty defaults for strings were rejected. Oops.)
+ AddField(message_proto, "empty_string", 11, label, FD::TYPE_STRING)
+ ->set_default_value("");
+
+ // Add a second set of fields with implicit defalut values.
+ AddField(message_proto, "implicit_int32" , 21, label, FD::TYPE_INT32 );
+ AddField(message_proto, "implicit_int64" , 22, label, FD::TYPE_INT64 );
+ AddField(message_proto, "implicit_uint32", 23, label, FD::TYPE_UINT32);
+ AddField(message_proto, "implicit_uint64", 24, label, FD::TYPE_UINT64);
+ AddField(message_proto, "implicit_float" , 25, label, FD::TYPE_FLOAT );
+ AddField(message_proto, "implicit_double", 26, label, FD::TYPE_DOUBLE);
+ AddField(message_proto, "implicit_bool" , 27, label, FD::TYPE_BOOL );
+ AddField(message_proto, "implicit_string", 28, label, FD::TYPE_STRING);
+ AddField(message_proto, "implicit_data" , 29, label, FD::TYPE_BYTES );
+ AddField(message_proto, "implicit_enum" , 30, label, FD::TYPE_ENUM)
+ ->set_type_name("DummyEnum");
+
+ // Build it.
+ DescriptorPool pool;
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != NULL);
+
+ ASSERT_EQ(1, file->enum_type_count());
+ const EnumDescriptor* enum_type = file->enum_type(0);
+ ASSERT_EQ(2, enum_type->value_count());
+ const EnumValueDescriptor* enum_value_a = enum_type->value(0);
+ const EnumValueDescriptor* enum_value_b = enum_type->value(1);
+
+ ASSERT_EQ(1, file->message_type_count());
+ const Descriptor* message = file->message_type(0);
+
+ ASSERT_EQ(21, message->field_count());
+
+ // Check the default values.
+ ASSERT_TRUE(message->field(0)->has_default_value());
+ ASSERT_TRUE(message->field(1)->has_default_value());
+ ASSERT_TRUE(message->field(2)->has_default_value());
+ ASSERT_TRUE(message->field(3)->has_default_value());
+ ASSERT_TRUE(message->field(4)->has_default_value());
+ ASSERT_TRUE(message->field(5)->has_default_value());
+ ASSERT_TRUE(message->field(6)->has_default_value());
+ ASSERT_TRUE(message->field(7)->has_default_value());
+ ASSERT_TRUE(message->field(8)->has_default_value());
+ ASSERT_TRUE(message->field(9)->has_default_value());
+ ASSERT_TRUE(message->field(10)->has_default_value());
+
+ EXPECT_EQ(-1 , message->field(0)->default_value_int32 ());
+ EXPECT_EQ(-GOOGLE_ULONGLONG(1000000000000),
+ message->field(1)->default_value_int64 ());
+ EXPECT_EQ(42 , message->field(2)->default_value_uint32());
+ EXPECT_EQ(GOOGLE_ULONGLONG(2000000000000),
+ message->field(3)->default_value_uint64());
+ EXPECT_EQ(4.5 , message->field(4)->default_value_float ());
+ EXPECT_EQ(10e100 , message->field(5)->default_value_double());
+ EXPECT_EQ(true , message->field(6)->default_value_bool ());
+ EXPECT_EQ("hello" , message->field(7)->default_value_string());
+ EXPECT_EQ("\001\002\003" , message->field(8)->default_value_string());
+ EXPECT_EQ(enum_value_b , message->field(9)->default_value_enum ());
+ EXPECT_EQ("" , message->field(10)->default_value_string());
+
+ ASSERT_FALSE(message->field(11)->has_default_value());
+ ASSERT_FALSE(message->field(12)->has_default_value());
+ ASSERT_FALSE(message->field(13)->has_default_value());
+ ASSERT_FALSE(message->field(14)->has_default_value());
+ ASSERT_FALSE(message->field(15)->has_default_value());
+ ASSERT_FALSE(message->field(16)->has_default_value());
+ ASSERT_FALSE(message->field(17)->has_default_value());
+ ASSERT_FALSE(message->field(18)->has_default_value());
+ ASSERT_FALSE(message->field(19)->has_default_value());
+ ASSERT_FALSE(message->field(20)->has_default_value());
+
+ EXPECT_EQ(0 , message->field(11)->default_value_int32 ());
+ EXPECT_EQ(0 , message->field(12)->default_value_int64 ());
+ EXPECT_EQ(0 , message->field(13)->default_value_uint32());
+ EXPECT_EQ(0 , message->field(14)->default_value_uint64());
+ EXPECT_EQ(0.0f , message->field(15)->default_value_float ());
+ EXPECT_EQ(0.0 , message->field(16)->default_value_double());
+ EXPECT_EQ(false, message->field(17)->default_value_bool ());
+ EXPECT_EQ("" , message->field(18)->default_value_string());
+ EXPECT_EQ("" , message->field(19)->default_value_string());
+ EXPECT_EQ(enum_value_a, message->field(20)->default_value_enum());
+}
+
+TEST_F(MiscTest, FieldOptions) {
+ // Try setting field options.
+
+ FileDescriptorProto file_proto;
+ file_proto.set_name("foo.proto");
+
+ DescriptorProto* message_proto = AddMessage(&file_proto, "TestMessage");
+ AddField(message_proto, "foo", 1,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+ FieldDescriptorProto* bar_proto =
+ AddField(message_proto, "bar", 2,
+ FieldDescriptorProto::LABEL_OPTIONAL,
+ FieldDescriptorProto::TYPE_INT32);
+
+ FieldOptions* options = bar_proto->mutable_options();
+ options->set_ctype(FieldOptions::CORD);
+
+ // Build the descriptors and get the pointers.
+ DescriptorPool pool;
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != NULL);
+
+ ASSERT_EQ(1, file->message_type_count());
+ const Descriptor* message = file->message_type(0);
+
+ ASSERT_EQ(2, message->field_count());
+ const FieldDescriptor* foo = message->field(0);
+ const FieldDescriptor* bar = message->field(1);
+
+ // "foo" had no options set, so it should return the default options.
+ EXPECT_EQ(&FieldOptions::default_instance(), &foo->options());
+
+ // "bar" had options set.
+ EXPECT_NE(&FieldOptions::default_instance(), options);
+ EXPECT_TRUE(bar->options().has_ctype());
+ EXPECT_EQ(FieldOptions::CORD, bar->options().ctype());
+}
+
+// ===================================================================
+
+class AllowUnknownDependenciesTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ FileDescriptorProto foo_proto, bar_proto;
+
+ pool_.AllowUnknownDependencies();
+
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: 'foo.proto'"
+ "dependency: 'bar.proto'"
+ "dependency: 'baz.proto'"
+ "message_type {"
+ " name: 'Foo'"
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
+ " field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
+ " field { name:'qux' number:3 label:LABEL_OPTIONAL"
+ " type_name: '.corge.Qux'"
+ " type: TYPE_ENUM"
+ " options {"
+ " uninterpreted_option {"
+ " name {"
+ " name_part: 'grault'"
+ " is_extension: true"
+ " }"
+ " positive_int_value: 1234"
+ " }"
+ " }"
+ " }"
+ "}",
+ &foo_proto));
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: 'bar.proto'"
+ "message_type { name: 'Bar' }",
+ &bar_proto));
+
+ // Collect pointers to stuff.
+ bar_file_ = pool_.BuildFile(bar_proto);
+ ASSERT_TRUE(bar_file_ != NULL);
+
+ ASSERT_EQ(1, bar_file_->message_type_count());
+ bar_type_ = bar_file_->message_type(0);
+
+ foo_file_ = pool_.BuildFile(foo_proto);
+ ASSERT_TRUE(foo_file_ != NULL);
+
+ ASSERT_EQ(1, foo_file_->message_type_count());
+ foo_type_ = foo_file_->message_type(0);
+
+ ASSERT_EQ(3, foo_type_->field_count());
+ bar_field_ = foo_type_->field(0);
+ baz_field_ = foo_type_->field(1);
+ qux_field_ = foo_type_->field(2);
+ }
+
+ const FileDescriptor* bar_file_;
+ const Descriptor* bar_type_;
+ const FileDescriptor* foo_file_;
+ const Descriptor* foo_type_;
+ const FieldDescriptor* bar_field_;
+ const FieldDescriptor* baz_field_;
+ const FieldDescriptor* qux_field_;
+
+ DescriptorPool pool_;
+};
+
+TEST_F(AllowUnknownDependenciesTest, PlaceholderFile) {
+ ASSERT_EQ(2, foo_file_->dependency_count());
+ EXPECT_EQ(bar_file_, foo_file_->dependency(0));
+
+ const FileDescriptor* baz_file = foo_file_->dependency(1);
+ EXPECT_EQ("baz.proto", baz_file->name());
+ EXPECT_EQ(0, baz_file->message_type_count());
+
+ // Placeholder files should not be findable.
+ EXPECT_EQ(bar_file_, pool_.FindFileByName(bar_file_->name()));
+ EXPECT_TRUE(pool_.FindFileByName(baz_file->name()) == NULL);
+}
+
+TEST_F(AllowUnknownDependenciesTest, PlaceholderTypes) {
+ ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
+ EXPECT_EQ(bar_type_, bar_field_->message_type());
+
+ ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
+ const Descriptor* baz_type = baz_field_->message_type();
+ EXPECT_EQ("Baz", baz_type->name());
+ EXPECT_EQ("Baz", baz_type->full_name());
+ EXPECT_EQ("Baz.placeholder.proto", baz_type->file()->name());
+ EXPECT_EQ(0, baz_type->extension_range_count());
+
+ ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
+ const EnumDescriptor* qux_type = qux_field_->enum_type();
+ EXPECT_EQ("Qux", qux_type->name());
+ EXPECT_EQ("corge.Qux", qux_type->full_name());
+ EXPECT_EQ("corge.Qux.placeholder.proto", qux_type->file()->name());
+
+ // Placeholder types should not be findable.
+ EXPECT_EQ(bar_type_, pool_.FindMessageTypeByName(bar_type_->full_name()));
+ EXPECT_TRUE(pool_.FindMessageTypeByName(baz_type->full_name()) == NULL);
+ EXPECT_TRUE(pool_.FindEnumTypeByName(qux_type->full_name()) == NULL);
+}
+
+TEST_F(AllowUnknownDependenciesTest, CopyTo) {
+ // FieldDescriptor::CopyTo() should write non-fully-qualified type names
+ // for placeholder types which were not originally fully-qualified.
+ FieldDescriptorProto proto;
+
+ // Bar is not a placeholder, so it is fully-qualified.
+ bar_field_->CopyTo(&proto);
+ EXPECT_EQ(".Bar", proto.type_name());
+ EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type());
+
+ // Baz is an unqualified placeholder.
+ proto.Clear();
+ baz_field_->CopyTo(&proto);
+ EXPECT_EQ("Baz", proto.type_name());
+ EXPECT_FALSE(proto.has_type());
+
+ // Qux is a fully-qualified placeholder.
+ proto.Clear();
+ qux_field_->CopyTo(&proto);
+ EXPECT_EQ(".corge.Qux", proto.type_name());
+ EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
+}
+
+TEST_F(AllowUnknownDependenciesTest, CustomOptions) {
+ // Qux should still have the uninterpreted option attached.
+ ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
+ const UninterpretedOption& option =
+ qux_field_->options().uninterpreted_option(0);
+ ASSERT_EQ(1, option.name_size());
+ EXPECT_EQ("grault", option.name(0).name_part());
+}
+
+TEST_F(AllowUnknownDependenciesTest, UnknownExtendee) {
+ // Test that we can extend an unknown type. This is slightly tricky because
+ // it means that the placeholder type must have an extension range.
+
+ FileDescriptorProto extension_proto;
+
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: 'extension.proto'"
+ "extension { extendee: 'UnknownType' name:'some_extension' number:123"
+ " label:LABEL_OPTIONAL type:TYPE_INT32 }",
+ &extension_proto));
+ const FileDescriptor* file = pool_.BuildFile(extension_proto);
+
+ ASSERT_TRUE(file != NULL);
+
+ ASSERT_EQ(1, file->extension_count());
+ const Descriptor* extendee = file->extension(0)->containing_type();
+ EXPECT_EQ("UnknownType", extendee->name());
+ ASSERT_EQ(1, extendee->extension_range_count());
+ EXPECT_EQ(1, extendee->extension_range(0)->start);
+ EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
+}
+
+TEST_F(AllowUnknownDependenciesTest, CustomOption) {
+ // Test that we can use a custom option without having parsed
+ // descriptor.proto.
+
+ FileDescriptorProto option_proto;
+
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"unknown_custom_options.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { "
+ " extendee: \"google.protobuf.FileOptions\" "
+ " name: \"some_option\" "
+ " number: 123456 "
+ " label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 "
+ "} "
+ "options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"some_option\" "
+ " is_extension: true "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"unknown_option\" "
+ " is_extension: true "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"optimize_for\" "
+ " is_extension: false "
+ " } "
+ " identifier_value: \"SPEED\" "
+ " } "
+ "}",
+ &option_proto));
+
+ const FileDescriptor* file = pool_.BuildFile(option_proto);
+ ASSERT_TRUE(file != NULL);
+
+ // Verify that no extension options were set, but they were left as
+ // uninterpreted_options.
+ vector<const FieldDescriptor*> fields;
+ file->options().GetReflection()->ListFields(file->options(), &fields);
+ ASSERT_EQ(2, fields.size());
+ EXPECT_TRUE(file->options().has_optimize_for());
+ EXPECT_EQ(2, file->options().uninterpreted_option_size());
+}
+
+// ===================================================================
+
+TEST(CustomOptions, OptionLocations) {
+ const Descriptor* message =
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor();
+ const FileDescriptor* file = message->file();
+ const FieldDescriptor* field = message->FindFieldByName("field1");
+ const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
+ // TODO(benjy): Support EnumValue options, once the compiler does.
+ const ServiceDescriptor* service =
+ file->FindServiceByName("TestServiceWithCustomOptions");
+ const MethodDescriptor* method = service->FindMethodByName("Foo");
+
+ EXPECT_EQ(GOOGLE_LONGLONG(9876543210),
+ file->options().GetExtension(protobuf_unittest::file_opt1));
+ EXPECT_EQ(-56,
+ message->options().GetExtension(protobuf_unittest::message_opt1));
+ EXPECT_EQ(GOOGLE_LONGLONG(8765432109),
+ field->options().GetExtension(protobuf_unittest::field_opt1));
+ EXPECT_EQ(42, // Check that we get the default for an option we don't set.
+ field->options().GetExtension(protobuf_unittest::field_opt2));
+ EXPECT_EQ(-789,
+ enm->options().GetExtension(protobuf_unittest::enum_opt1));
+ EXPECT_EQ(123,
+ enm->value(1)->options().GetExtension(
+ protobuf_unittest::enum_value_opt1));
+ EXPECT_EQ(GOOGLE_LONGLONG(-9876543210),
+ service->options().GetExtension(protobuf_unittest::service_opt1));
+ EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
+ method->options().GetExtension(protobuf_unittest::method_opt1));
+
+ // See that the regular options went through unscathed.
+ EXPECT_TRUE(message->options().has_message_set_wire_format());
+ EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
+}
+
+TEST(CustomOptions, OptionTypes) {
+ const MessageOptions* options = NULL;
+
+ options =
+ &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
+ EXPECT_EQ(false , options->GetExtension(protobuf_unittest::bool_opt));
+ EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
+ EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
+ EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::uint32_opt));
+ EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::uint64_opt));
+ EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
+ EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
+ EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::fixed32_opt));
+ EXPECT_EQ(0 , options->GetExtension(protobuf_unittest::fixed64_opt));
+ EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
+ EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
+
+ options =
+ &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
+ EXPECT_EQ(true , options->GetExtension(protobuf_unittest::bool_opt));
+ EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt));
+ EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt));
+ EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
+ EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
+ EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sint32_opt));
+ EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sint64_opt));
+ EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
+ EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
+ EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sfixed32_opt));
+ EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sfixed64_opt));
+
+ options =
+ &protobuf_unittest::CustomOptionOtherValues::descriptor()->options();
+ EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
+ EXPECT_FLOAT_EQ(12.3456789,
+ options->GetExtension(protobuf_unittest::float_opt));
+ EXPECT_DOUBLE_EQ(1.234567890123456789,
+ options->GetExtension(protobuf_unittest::double_opt));
+ EXPECT_EQ("Hello, \"World\"",
+ options->GetExtension(protobuf_unittest::string_opt));
+
+ EXPECT_EQ(string("Hello\0World", 11),
+ options->GetExtension(protobuf_unittest::bytes_opt));
+
+ EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
+ options->GetExtension(protobuf_unittest::enum_opt));
+
+ options =
+ &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options();
+ EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
+ EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
+
+ options =
+ &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options();
+ EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
+ EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
+}
+
+TEST(CustomOptions, ComplexExtensionOptions) {
+ const MessageOptions* options =
+ &protobuf_unittest::VariousComplexOptions::descriptor()->options();
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
+ GetExtension(protobuf_unittest::quux), 324);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
+ GetExtension(protobuf_unittest::corge).qux(), 876);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+ GetExtension(protobuf_unittest::grault), 654);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
+ 743);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
+ GetExtension(protobuf_unittest::quux), 1999);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
+ GetExtension(protobuf_unittest::corge).qux(), 2008);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+ GetExtension(protobuf_unittest::garply).foo(), 741);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+ GetExtension(protobuf_unittest::garply).
+ GetExtension(protobuf_unittest::quux), 1998);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+ GetExtension(protobuf_unittest::garply).
+ GetExtension(protobuf_unittest::corge).qux(), 2121);
+ EXPECT_EQ(options->GetExtension(
+ protobuf_unittest::ComplexOptionType2::ComplexOptionType4::complex_opt4).
+ waldo(), 1971);
+ EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+ fred().waldo(), 321);
+ EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
+ EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3).
+ complexoptiontype5().plugh());
+ EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
+}
+
+TEST(CustomOptions, OptionsFromOtherFile) {
+ // Test that to use a custom option, we only need to import the file
+ // defining the option; we do not also have to import descriptor.proto.
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+ ->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+ "options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"file_opt1\" "
+ " is_extension: true "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ // Test a non-extension option too. (At one point this failed due to a
+ // bug.)
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"java_package\" "
+ " is_extension: false "
+ " } "
+ " string_value: \"foo\" "
+ " } "
+ // Test that enum-typed options still work too. (At one point this also
+ // failed due to a bug.)
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"optimize_for\" "
+ " is_extension: false "
+ " } "
+ " identifier_value: \"SPEED\" "
+ " } "
+ "}"
+ ,
+ &file_proto));
+
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != NULL);
+ EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
+ EXPECT_TRUE(file->options().has_java_package());
+ EXPECT_EQ("foo", file->options().java_package());
+ EXPECT_TRUE(file->options().has_optimize_for());
+ EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
+}
+
+TEST(CustomOptions, MessageOptionThreeFieldsSet) {
+ // This tests a bug which previously existed in custom options parsing. The
+ // bug occurred when you defined a custom option with message type and then
+ // set three fields of that option on a single definition (see the example
+ // below). The bug is a bit hard to explain, so check the change history if
+ // you want to know more.
+ DescriptorPool pool;
+
+ FileDescriptorProto file_proto;
+ FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+ ->file()->CopyTo(&file_proto);
+ ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+ // The following represents the definition:
+ //
+ // import "google/protobuf/unittest_custom_options.proto"
+ // package protobuf_unittest;
+ // message Foo {
+ // option (complex_opt1).foo = 1234;
+ // option (complex_opt1).foo2 = 1234;
+ // option (complex_opt1).foo3 = 1234;
+ // }
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"custom_options_import.proto\" "
+ "package: \"protobuf_unittest\" "
+ "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+ "message_type { "
+ " name: \"Foo\" "
+ " options { "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo2\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " uninterpreted_option { "
+ " name { "
+ " name_part: \"complex_opt1\" "
+ " is_extension: true "
+ " } "
+ " name { "
+ " name_part: \"foo3\" "
+ " is_extension: false "
+ " } "
+ " positive_int_value: 1234 "
+ " } "
+ " } "
+ "}",
+ &file_proto));
+
+ const FileDescriptor* file = pool.BuildFile(file_proto);
+ ASSERT_TRUE(file != NULL);
+ ASSERT_EQ(1, file->message_type_count());
+
+ const MessageOptions& options = file->message_type(0)->options();
+ EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
+}
+
+// Check that aggregate options were parsed and saved correctly in
+// the appropriate descriptors.
+TEST(CustomOptions, AggregateOptions) {
+ const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
+ const FileDescriptor* file = msg->file();
+ const FieldDescriptor* field = msg->FindFieldByName("fieldname");
+ const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
+ const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
+ const ServiceDescriptor* service = file->FindServiceByName(
+ "AggregateService");
+ const MethodDescriptor* method = service->FindMethodByName("Method");
+
+ // Tests for the different types of data embedded in fileopt
+ const protobuf_unittest::Aggregate& file_options =
+ file->options().GetExtension(protobuf_unittest::fileopt);
+ EXPECT_EQ(100, file_options.i());
+ EXPECT_EQ("FileAnnotation", file_options.s());
+ EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
+ EXPECT_EQ("FileExtensionAnnotation",
+ file_options.file().GetExtension(protobuf_unittest::fileopt).s());
+ EXPECT_EQ("EmbeddedMessageSetElement",
+ file_options.mset().GetExtension(
+ protobuf_unittest::AggregateMessageSetElement
+ ::message_set_extension).s());
+
+ // Simple tests for all the other types of annotations
+ EXPECT_EQ("MessageAnnotation",
+ msg->options().GetExtension(protobuf_unittest::msgopt).s());
+ EXPECT_EQ("FieldAnnotation",
+ field->options().GetExtension(protobuf_unittest::fieldopt).s());
+ EXPECT_EQ("EnumAnnotation",
+ enumd->options().GetExtension(protobuf_unittest::enumopt).s());
+ EXPECT_EQ("EnumValueAnnotation",
+ enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
+ EXPECT_EQ("ServiceAnnotation",
+ service->options().GetExtension(protobuf_unittest::serviceopt).s());
+ EXPECT_EQ("MethodAnnotation",
+ method->options().GetExtension(protobuf_unittest::methodopt).s());
+}
+
+// ===================================================================
+
+// The tests below trigger every unique call to AddError() in descriptor.cc,
+// in the order in which they appear in that file. I'm using TextFormat here
+// to specify the input descriptors because building them using code would
+// be too bulky.
+
+class MockErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(const string& filename,
+ const string& element_name, const Message* descriptor,
+ ErrorLocation location, const string& message) {
+ const char* location_name = NULL;
+ switch (location) {
+ case NAME : location_name = "NAME" ; break;
+ case NUMBER : location_name = "NUMBER" ; break;
+ case TYPE : location_name = "TYPE" ; break;
+ case EXTENDEE : location_name = "EXTENDEE" ; break;
+ case DEFAULT_VALUE: location_name = "DEFAULT_VALUE"; break;
+ case OPTION_NAME : location_name = "OPTION_NAME" ; break;
+ case OPTION_VALUE : location_name = "OPTION_VALUE" ; break;
+ case INPUT_TYPE : location_name = "INPUT_TYPE" ; break;
+ case OUTPUT_TYPE : location_name = "OUTPUT_TYPE" ; break;
+ case OTHER : location_name = "OTHER" ; break;
+ }
+
+ strings::SubstituteAndAppend(
+ &text_, "$0: $1: $2: $3\n",
+ filename, element_name, location_name, message);
+ }
+};
+
+class ValidationErrorTest : public testing::Test {
+ protected:
+ // Parse file_text as a FileDescriptorProto in text format and add it
+ // to the DescriptorPool. Expect no errors.
+ void BuildFile(const string& file_text) {
+ FileDescriptorProto file_proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+ ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
+ }
+
+ // Parse file_text as a FileDescriptorProto in text format and add it
+ // to the DescriptorPool. Expect errors to be produced which match the
+ // given error text.
+ void BuildFileWithErrors(const string& file_text,
+ const string& expected_errors) {
+ FileDescriptorProto file_proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+
+ MockErrorCollector error_collector;
+ EXPECT_TRUE(
+ pool_.BuildFileCollectingErrors(file_proto, &error_collector) == NULL);
+ EXPECT_EQ(expected_errors, error_collector.text_);
+ }
+
+ // Builds some already-parsed file in our test pool.
+ void BuildFileInTestPool(const FileDescriptor* file) {
+ FileDescriptorProto file_proto;
+ file->CopyTo(&file_proto);
+ ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
+ }
+
+ // Build descriptor.proto in our test pool. This allows us to extend it in
+ // the test pool, so we can test custom options.
+ void BuildDescriptorMessagesInTestPool() {
+ BuildFileInTestPool(DescriptorProto::descriptor()->file());
+ }
+
+ DescriptorPool pool_;
+};
+
+TEST_F(ValidationErrorTest, AlreadyDefined) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" }"
+ "message_type { name: \"Foo\" }",
+
+ "foo.proto: Foo: NAME: \"Foo\" is already defined.\n");
+}
+
+TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "package: \"foo.bar\" "
+ "message_type { name: \"Foo\" }"
+ "message_type { name: \"Foo\" }",
+
+ "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in "
+ "\"foo.bar\".\n");
+}
+
+TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" }");
+
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Foo\" }",
+
+ "bar.proto: Foo: NAME: \"Foo\" is already defined in file "
+ "\"foo.proto\".\n");
+}
+
+TEST_F(ValidationErrorTest, PackageAlreadyDefined) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type { name: \"foo\" }");
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "package: \"foo.bar\"",
+
+ "bar.proto: foo: NAME: \"foo\" is already defined (as something other "
+ "than a package) in file \"foo.proto\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
+ "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
+
+ "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
+ "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
+ "meaning that enum values are siblings of their type, not children of "
+ "it. Therefore, \"FOO\" must be unique within the global scope, not "
+ "just within \"Bar\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "package: \"pkg\" "
+ "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
+ "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
+
+ "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
+ "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
+ "meaning that enum values are siblings of their type, not children of "
+ "it. Therefore, \"FOO\" must be unique within \"pkg\", not just within "
+ "\"Bar\".\n");
+}
+
+TEST_F(ValidationErrorTest, MissingName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { }",
+
+ "foo.proto: : NAME: Missing name.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"$\" }",
+
+ "foo.proto: $: NAME: \"$\" is not a valid identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidPackageName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "package: \"foo.$\"",
+
+ "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, MissingFileName) {
+ BuildFileWithErrors(
+ "",
+
+ ": : OTHER: Missing field: FileDescriptorProto.name.\n");
+}
+
+TEST_F(ValidationErrorTest, DupeDependency) {
+ BuildFile("name: \"foo.proto\"");
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "dependency: \"foo.proto\" "
+ "dependency: \"foo.proto\" ",
+
+ "bar.proto: bar.proto: OTHER: Import \"foo.proto\" was listed twice.\n");
+}
+
+TEST_F(ValidationErrorTest, UnknownDependency) {
+ BuildFileWithErrors(
+ "name: \"bar.proto\" "
+ "dependency: \"foo.proto\" ",
+
+ "bar.proto: bar.proto: OTHER: Import \"foo.proto\" has not been loaded.\n");
+}
+
+TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
+ // Used to crash: If we depend on a non-existent file and then refer to a
+ // package defined in a file that we didn't import, and that package is
+ // nested within a parent package which this file is also in, and we don't
+ // include that parent package in the name (i.e. we do a relative lookup)...
+ // Yes, really.
+ BuildFile(
+ "name: 'foo.proto' "
+ "package: 'outer.foo' ");
+ BuildFileWithErrors(
+ "name: 'bar.proto' "
+ "dependency: 'baz.proto' "
+ "package: 'outer.bar' "
+ "message_type { "
+ " name: 'Bar' "
+ " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
+ "}",
+
+ "bar.proto: bar.proto: OTHER: Import \"baz.proto\" has not been loaded.\n"
+ "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined in "
+ "\"foo.proto\", which is not imported by \"bar.proto\". To use it here, "
+ "please add the necessary import.\n");
+}
+
+TEST_F(ValidationErrorTest, DupeFile) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" }");
+ // Note: We should *not* get redundant errors about "Foo" already being
+ // defined.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ // Add another type so that the files aren't identical (in which case there
+ // would be no error).
+ "enum_type { name: \"Bar\" }",
+
+ "foo.proto: foo.proto: OTHER: A file with this name is already in the "
+ "pool.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldInExtensionRange) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name: \"qux\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " extension_range { start: 10 end: 20 }"
+ "}",
+
+ "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field "
+ "\"bar\" (10).\n"
+ "foo.proto: Foo.baz: NUMBER: Extension range 10 to 19 includes field "
+ "\"baz\" (19).\n");
+}
+
+TEST_F(ValidationErrorTest, OverlappingExtensionRanges) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 10 end: 20 }"
+ " extension_range { start: 20 end: 30 }"
+ " extension_range { start: 19 end: 21 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
+ "already-defined range 10 to 19.\n"
+ "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with "
+ "already-defined range 20 to 29.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidDefaults) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+
+ // Invalid number.
+ " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32"
+ " default_value: \"abc\" }"
+
+ // Empty default value.
+ " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32"
+ " default_value: \"\" }"
+
+ // Invalid boolean.
+ " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL"
+ " default_value: \"abc\" }"
+
+ // Messages can't have defaults.
+ " field { name: \"qux\" number: 4 label: LABEL_OPTIONAL type: TYPE_MESSAGE"
+ " default_value: \"abc\" type_name: \"Foo\" }"
+
+ // Same thing, but we don't know that this field has message type until
+ // we look up the type name.
+ " field { name: \"quux\" number: 5 label: LABEL_OPTIONAL"
+ " default_value: \"abc\" type_name: \"Foo\" }"
+
+ // Repeateds can't have defaults.
+ " field { name: \"corge\" number: 6 label: LABEL_REPEATED type: TYPE_INT32"
+ " default_value: \"1\" }"
+ "}",
+
+ "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value.\n"
+ "foo.proto: Foo.bar: DEFAULT_VALUE: Couldn't parse default value.\n"
+ "foo.proto: Foo.baz: DEFAULT_VALUE: Boolean default must be true or "
+ "false.\n"
+ "foo.proto: Foo.qux: DEFAULT_VALUE: Messages can't have default values.\n"
+ "foo.proto: Foo.corge: DEFAULT_VALUE: Repeated fields can't have default "
+ "values.\n"
+ // This ends up being reported later because the error is detected at
+ // cross-linking time.
+ "foo.proto: Foo.quux: DEFAULT_VALUE: Messages can't have default "
+ "values.\n");
+}
+
+TEST_F(ValidationErrorTest, NegativeFieldNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n");
+}
+
+TEST_F(ValidationErrorTest, HugeFieldNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 0x70000000 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than "
+ "536870911.\n");
+}
+
+TEST_F(ValidationErrorTest, ReservedFieldNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field {name:\"foo\" number: 18999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field {name:\"bar\" number: 19000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field {name:\"baz\" number: 19999 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field {name:\"qux\" number: 20000 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.bar: NUMBER: Field numbers 19000 through 19999 are "
+ "reserved for the protocol buffer library implementation.\n"
+ "foo.proto: Foo.baz: NUMBER: Field numbers 19000 through 19999 are "
+ "reserved for the protocol buffer library implementation.\n");
+}
+
+TEST_F(ValidationErrorTest, ExtensionMissingExtendee) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
+ " type_name: \"Foo\" }"
+ "}",
+
+ "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for "
+ "extension field.\n");
+}
+
+TEST_F(ValidationErrorTest, NonExtensionWithExtendee) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ " extension_range { start: 1 end: 2 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL"
+ " type_name: \"Foo\" extendee: \"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for "
+ "non-extension field.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldNumberConflict) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name: \"bar\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.bar: NUMBER: Field number 1 has already been used in "
+ "\"Foo\" by field \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, BadMessageSetExtensionType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"MessageSet\""
+ " options { message_set_wire_format: true }"
+ " extension_range { start: 4 end: 5 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: \"MessageSet\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
+ "messages.\n");
+}
+
+TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"MessageSet\""
+ " options { message_set_wire_format: true }"
+ " extension_range { start: 4 end: 5 }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE"
+ " type_name: \"Foo\" extendee: \"MessageSet\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional "
+ "messages.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldInMessageSet) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " options { message_set_wire_format: true }"
+ " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only "
+ "extensions.\n");
+}
+
+TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: -10 end: -1 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n");
+}
+
+TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 1 end: 0x70000000 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than "
+ "536870911.\n");
+}
+
+TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension_range { start: 10 end: 10 }"
+ " extension_range { start: 10 end: 5 }"
+ "}",
+
+ "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
+ "start number.\n"
+ "foo.proto: Foo: NUMBER: Extension range end number must be greater than "
+ "start number.\n");
+}
+
+TEST_F(ValidationErrorTest, EmptyEnum) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Foo\" }"
+ // Also use the empty enum in a message to make sure there are no crashes
+ // during validation (possible if the code attempts to derive a default
+ // value for the field).
+ "message_type {"
+ " name: \"Bar\""
+ " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type_name:\"Foo\" }"
+ " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL type_name:\"Foo\" "
+ " default_value: \"NO_SUCH_VALUE\" }"
+ "}",
+
+ "foo.proto: Foo: NAME: Enums must contain at least one value.\n"
+ "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named "
+ "\"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedExtendee) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: \"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, NonMessageExtendee) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }"
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: \"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, NotAnExtensionNumber) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " extendee: \"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension "
+ "number.\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedFieldType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) {
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type { name: \"Bar\" } ");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}",
+ "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", "
+ "which is not imported by \"foo.proto\". To use it here, please add the "
+ "necessary import.\n");
+}
+
+TEST_F(ValidationErrorTest, SearchMostLocalFirst) {
+ // The following should produce an error that Bar.Baz is not defined:
+ // message Bar { message Baz {} }
+ // message Foo {
+ // message Bar {
+ // // Placing "message Baz{}" here, or removing Foo.Bar altogether,
+ // // would fix the error.
+ // }
+ // optional Bar.Baz baz = 1;
+ // }
+ // An one point the lookup code incorrectly did not produce an error in this
+ // case, because when looking for Bar.Baz, it would try "Foo.Bar.Baz" first,
+ // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually
+ // refer to the inner Bar, not the outer one.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ " nested_type { name: \"Baz\" }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " nested_type { name: \"Bar\" }"
+ " field { name:\"baz\" number:1 label:LABEL_OPTIONAL"
+ " type_name:\"Bar.Baz\" }"
+ "}",
+
+ "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
+ // This test would find the most local "Bar" first, and does, but
+ // proceeds to find the outer one because the inner one's not an
+ // aggregate.
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ " nested_type { name: \"Baz\" }"
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " field { name: \"Bar\" number:1 type:TYPE_BYTES } "
+ " field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
+ " type_name:\"Bar.Baz\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) {
+ // Imagine we have the following:
+ //
+ // foo.proto:
+ // package foo.bar;
+ // bar.proto:
+ // package foo.bar;
+ // import "foo.proto";
+ // message Bar {}
+ // baz.proto:
+ // package foo;
+ // import "bar.proto"
+ // message Baz { optional bar.Bar qux = 1; }
+ //
+ // When validating baz.proto, we will look up "bar.Bar". As part of this
+ // lookup, we first lookup "bar" then try to find "Bar" within it. "bar"
+ // should resolve to "foo.bar". Note, though, that "foo.bar" was originally
+ // defined in foo.proto, which is not a direct dependency of baz.proto. The
+ // implementation of FindSymbol() normally only returns symbols in direct
+ // dependencies, not indirect ones. This test insures that this does not
+ // prevent it from finding "foo.bar".
+
+ BuildFile(
+ "name: \"foo.proto\" "
+ "package: \"foo.bar\" ");
+ BuildFile(
+ "name: \"bar.proto\" "
+ "package: \"foo.bar\" "
+ "dependency: \"foo.proto\" "
+ "message_type { name: \"Bar\" }");
+ BuildFile(
+ "name: \"baz.proto\" "
+ "package: \"foo\" "
+ "dependency: \"bar.proto\" "
+ "message_type { "
+ " name: \"Baz\" "
+ " field { name:\"qux\" number:1 label:LABEL_OPTIONAL "
+ " type_name:\"bar.Bar\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeNotAType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
+ " type_name:\".Foo.bar\" }"
+ " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
+}
+
+TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " nested_type {"
+ " name: \"Bar\""
+ " field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " }"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
+ " type_name:\"Bar.Baz\" }"
+ "}",
+ "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Bar\""
+ "}"
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Bar\" } "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM"
+ " type_name:\"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n");
+}
+
+TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE"
+ " type_name:\"Bar\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, BadEnumDefaultValue) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\""
+ " default_value:\"NO_SUCH_VALUE\" }"
+ "}",
+
+ "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named "
+ "\"NO_SUCH_VALUE\".\n");
+}
+
+TEST_F(ValidationErrorTest, PrimitiveWithTypeName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32"
+ " type_name:\"Foo\" }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n");
+}
+
+TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"Foo\""
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }"
+ "}",
+
+ "foo.proto: Foo.foo: TYPE: Field with message or enum type missing "
+ "type_name.\n");
+}
+
+TEST_F(ValidationErrorTest, InputTypeNotDefined) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "service {"
+ " name: \"TestService\""
+ " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
+ "}",
+
+ "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, InputTypeNotAMessage) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "service {"
+ " name: \"TestService\""
+ " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }"
+ "}",
+
+ "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, OutputTypeNotDefined) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "service {"
+ " name: \"TestService\""
+ " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
+ "}",
+
+ "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, OutputTypeNotAMessage) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } "
+ "service {"
+ " name: \"TestService\""
+ " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }"
+ "}",
+
+ "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message type.\n");
+}
+
+TEST_F(ValidationErrorTest, IllegalPackedField) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {\n"
+ " name: \"Foo\""
+ " field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
+ " type:TYPE_STRING "
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ " field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
+ " type_name: \"Foo\""
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
+ " type:TYPE_INT32 "
+ " options { uninterpreted_option {"
+ " name { name_part: \"packed\" is_extension: false }"
+ " identifier_value: \"true\" }}}\n"
+ "}",
+
+ "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n"
+ "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n"
+ "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
+ "specified for repeated primitive fields.\n"
+ );
+}
+
+TEST_F(ValidationErrorTest, OptionWrongType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"TestMessage\" "
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
+ " options { uninterpreted_option { name { name_part: \"ctype\" "
+ " is_extension: false }"
+ " positive_int_value: 1 }"
+ " }"
+ " }"
+ "}\n",
+
+ "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
+ "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
+}
+
+TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"TestMessage\" "
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
+ " options { uninterpreted_option { name { name_part: \"ctype\" "
+ " is_extension: false }"
+ " name { name_part: \"foo\" "
+ " is_extension: true }"
+ " positive_int_value: 1 }"
+ " }"
+ " }"
+ "}\n",
+
+ "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
+ "atomic type, not a message.\n");
+}
+
+TEST_F(ValidationErrorTest, DupOption) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"TestMessage\" "
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
+ " options { uninterpreted_option { name { name_part: \"ctype\" "
+ " is_extension: false }"
+ " identifier_value: \"CORD\" }"
+ " uninterpreted_option { name { name_part: \"ctype\" "
+ " is_extension: false }"
+ " identifier_value: \"CORD\" }"
+ " }"
+ " }"
+ "}\n",
+
+ "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
+ "already set.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidOptionName) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type { "
+ " name: \"TestMessage\" "
+ " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
+ " options { uninterpreted_option { "
+ " name { name_part: \"uninterpreted_option\" "
+ " is_extension: false }"
+ " positive_int_value: 1 "
+ " }"
+ " }"
+ " }"
+ "}\n",
+
+ "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
+ "reserved name \"uninterpreted_option\".\n");
+}
+
+TEST_F(ValidationErrorTest, RepeatedOption) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_REPEATED "
+ " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " double_value: 1.2 } }",
+
+ "foo.proto: foo.proto: OPTION_NAME: Option field \"(foo)\" is repeated. "
+ "Repeated options are not supported.\n");
+}
+
+TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
+ "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
+
+ "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
+ "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " positive_int_value: 0x80000000 } "
+ "}",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+ "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " negative_int_value: -0x80000001 } "
+ "}",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+ "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " string_value: \"5\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
+ "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " positive_int_value: 0x8000000000000000 } "
+ "}",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+ "for int64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"5\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
+ "for int64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " positive_int_value: 0x100000000 } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+ "for uint32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " double_value: -5.6 } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
+ "for uint32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " negative_int_value: -5 } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
+ "for uint64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " string_value: \"bar\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
+ "for float option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " string_value: \"bar\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
+ "for double option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"bar\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
+ "for boolean option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
+ " value { name: \"BAZ\" number: 2 } }"
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_ENUM type_name: \"FooEnum\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " string_value: \"QUUX\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
+ "enum-valued option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
+ " value { name: \"BAZ\" number: 2 } }"
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_ENUM type_name: \"FooEnum\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"QUUX\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
+ "named \"QUUX\" for option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
+ " value { name: \"BAZ\" number: 2 } }"
+ "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
+ " value { name: \"QUUX\" number: 2 } }"
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_ENUM type_name: \"FooEnum1\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"QUUX\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
+ "named \"QUUX\" for option \"foo\". This appears to be a value from a "
+ "sibling type.\n");
+}
+
+TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " identifier_value: \"QUUX\" } }",
+
+ "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string for "
+ "string option \"foo\".\n");
+}
+
+// Helper function for tests that check for aggregate value parsing
+// errors. The "value" argument is embedded inside the
+// "uninterpreted_option" portion of the result.
+static string EmbedAggregateValue(const char* value) {
+ return strings::Substitute(
+ "name: \"foo.proto\" "
+ "dependency: \"google/protobuf/descriptor.proto\" "
+ "message_type { name: \"Foo\" } "
+ "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+ " type: TYPE_MESSAGE type_name: \"Foo\" "
+ " extendee: \"google.protobuf.FileOptions\" }"
+ "options { uninterpreted_option { name { name_part: \"foo\" "
+ " is_extension: true } "
+ " $0 } }",
+ value);
+}
+
+TEST_F(ValidationErrorTest, AggregateValueNotFound) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("string_value: \"\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
+ "To set the entire message, use syntax like "
+ "\"foo = { <proto text format> }\". To set fields within it, use "
+ "syntax like \"foo.foo = value\".\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueParseError) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("aggregate_value: \"1+2\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+ "value for \"foo\": Expected identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
+ BuildDescriptorMessagesInTestPool();
+
+ BuildFileWithErrors(
+ EmbedAggregateValue("aggregate_value: \"x:100\""),
+ "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+ "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
+}
+
+TEST_F(ValidationErrorTest, NotLiteImportsLite) {
+ BuildFile(
+ "name: \"bar.proto\" "
+ "options { optimize_for: LITE_RUNTIME } ");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"bar.proto\" ",
+
+ "foo.proto: foo.proto: OTHER: Files that do not use optimize_for = "
+ "LITE_RUNTIME cannot import files which do use this option. This file "
+ "is not lite, but it imports \"bar.proto\" which is.\n");
+}
+
+TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
+ BuildFile(
+ "name: \"bar.proto\" "
+ "message_type: {"
+ " name: \"Bar\""
+ " extension_range { start: 1 end: 1000 }"
+ "}");
+
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "dependency: \"bar.proto\" "
+ "options { optimize_for: LITE_RUNTIME } "
+ "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
+ " type: TYPE_INT32 extendee: \"Bar\" }",
+
+ "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be "
+ "declared in non-lite files. Note that you cannot extend a non-lite "
+ "type to contain a lite type, but the reverse is allowed.\n");
+}
+
+TEST_F(ValidationErrorTest, NoLiteServices) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "options {"
+ " optimize_for: LITE_RUNTIME"
+ " cc_generic_services: true"
+ " java_generic_services: true"
+ "} "
+ "service { name: \"Foo\" }",
+
+ "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
+ "define services unless you set both options cc_generic_services and "
+ "java_generic_sevices to false.\n");
+
+ BuildFile(
+ "name: \"bar.proto\" "
+ "options {"
+ " optimize_for: LITE_RUNTIME"
+ " cc_generic_services: false"
+ " java_generic_services: false"
+ "} "
+ "service { name: \"Bar\" }");
+}
+
+TEST_F(ValidationErrorTest, RollbackAfterError) {
+ // Build a file which contains every kind of construct but references an
+ // undefined type. All these constructs will be added to the symbol table
+ // before the undefined type error is noticed. The DescriptorPool will then
+ // have to roll everything back.
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
+ "} "
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"BAR\" number:1 }"
+ "} "
+ "service {"
+ " name: \"TestService\""
+ " method {"
+ " name: \"Baz\""
+ " input_type: \"NoSuchType\"" // error
+ " output_type: \"TestMessage\""
+ " }"
+ "}",
+
+ "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not defined.\n");
+
+ // Make sure that if we build the same file again with the error fixed,
+ // it works. If the above rollback was incomplete, then some symbols will
+ // be left defined, and this second attempt will fail since it tries to
+ // re-define the same symbols.
+ BuildFile(
+ "name: \"foo.proto\" "
+ "message_type {"
+ " name: \"TestMessage\""
+ " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }"
+ "} "
+ "enum_type {"
+ " name: \"TestEnum\""
+ " value { name:\"BAR\" number:1 }"
+ "} "
+ "service {"
+ " name: \"TestService\""
+ " method { name:\"Baz\""
+ " input_type:\"TestMessage\""
+ " output_type:\"TestMessage\" }"
+ "}");
+}
+
+TEST_F(ValidationErrorTest, ErrorsReportedToLogError) {
+ // Test that errors are reported to GOOGLE_LOG(ERROR) if no error collector is
+ // provided.
+
+ FileDescriptorProto file_proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "name: \"foo.proto\" "
+ "message_type { name: \"Foo\" } "
+ "message_type { name: \"Foo\" } ",
+ &file_proto));
+
+ vector<string> errors;
+
+ {
+ ScopedMemoryLog log;
+ EXPECT_TRUE(pool_.BuildFile(file_proto) == NULL);
+ errors = log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(2, errors.size());
+
+ EXPECT_EQ("Invalid proto descriptor for file \"foo.proto\":", errors[0]);
+ EXPECT_EQ(" Foo: \"Foo\" is already defined.", errors[1]);
+}
+
+// ===================================================================
+// DescriptorDatabase
+
+static void AddToDatabase(SimpleDescriptorDatabase* database,
+ const char* file_text) {
+ FileDescriptorProto file_proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+ database->Add(file_proto);
+}
+
+class DatabaseBackedPoolTest : public testing::Test {
+ protected:
+ DatabaseBackedPoolTest() {}
+
+ SimpleDescriptorDatabase database_;
+
+ virtual void SetUp() {
+ AddToDatabase(&database_,
+ "name: \"foo.proto\" "
+ "message_type { name:\"Foo\" extension_range { start: 1 end: 100 } } "
+ "enum_type { name:\"TestEnum\" value { name:\"DUMMY\" number:0 } } "
+ "service { name:\"TestService\" } ");
+ AddToDatabase(&database_,
+ "name: \"bar.proto\" "
+ "dependency: \"foo.proto\" "
+ "message_type { name:\"Bar\" } "
+ "extension { name:\"foo_ext\" extendee: \".Foo\" number:5 "
+ " label:LABEL_OPTIONAL type:TYPE_INT32 } ");
+ }
+
+ // We can't inject a file containing errors into a DescriptorPool, so we
+ // need an actual mock DescriptorDatabase to test errors.
+ class ErrorDescriptorDatabase : public DescriptorDatabase {
+ public:
+ ErrorDescriptorDatabase() {}
+ ~ErrorDescriptorDatabase() {}
+
+ // implements DescriptorDatabase ---------------------------------
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output) {
+ // error.proto and error2.proto cyclically import each other.
+ if (filename == "error.proto") {
+ output->Clear();
+ output->set_name("error.proto");
+ output->add_dependency("error2.proto");
+ return true;
+ } else if (filename == "error2.proto") {
+ output->Clear();
+ output->set_name("error2.proto");
+ output->add_dependency("error.proto");
+ return true;
+ } else {
+ return false;
+ }
+ }
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output) {
+ return false;
+ }
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) {
+ return false;
+ }
+ };
+
+ // A DescriptorDatabase that counts how many times each method has been
+ // called and forwards to some other DescriptorDatabase.
+ class CallCountingDatabase : public DescriptorDatabase {
+ public:
+ CallCountingDatabase(DescriptorDatabase* wrapped_db)
+ : wrapped_db_(wrapped_db) {
+ Clear();
+ }
+ ~CallCountingDatabase() {}
+
+ DescriptorDatabase* wrapped_db_;
+
+ int call_count_;
+
+ void Clear() {
+ call_count_ = 0;
+ }
+
+ // implements DescriptorDatabase ---------------------------------
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output) {
+ ++call_count_;
+ return wrapped_db_->FindFileByName(filename, output);
+ }
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output) {
+ ++call_count_;
+ return wrapped_db_->FindFileContainingSymbol(symbol_name, output);
+ }
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) {
+ ++call_count_;
+ return wrapped_db_->FindFileContainingExtension(
+ containing_type, field_number, output);
+ }
+ };
+
+ // A DescriptorDatabase which falsely always returns foo.proto when searching
+ // for any symbol or extension number. This shouldn't cause the
+ // DescriptorPool to reload foo.proto if it is already loaded.
+ class FalsePositiveDatabase : public DescriptorDatabase {
+ public:
+ FalsePositiveDatabase(DescriptorDatabase* wrapped_db)
+ : wrapped_db_(wrapped_db) {}
+ ~FalsePositiveDatabase() {}
+
+ DescriptorDatabase* wrapped_db_;
+
+ // implements DescriptorDatabase ---------------------------------
+ bool FindFileByName(const string& filename,
+ FileDescriptorProto* output) {
+ return wrapped_db_->FindFileByName(filename, output);
+ }
+ bool FindFileContainingSymbol(const string& symbol_name,
+ FileDescriptorProto* output) {
+ return FindFileByName("foo.proto", output);
+ }
+ bool FindFileContainingExtension(const string& containing_type,
+ int field_number,
+ FileDescriptorProto* output) {
+ return FindFileByName("foo.proto", output);
+ }
+ };
+};
+
+TEST_F(DatabaseBackedPoolTest, FindFileByName) {
+ DescriptorPool pool(&database_);
+
+ const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(foo != NULL);
+ EXPECT_EQ("foo.proto", foo->name());
+ ASSERT_EQ(1, foo->message_type_count());
+ EXPECT_EQ("Foo", foo->message_type(0)->name());
+
+ EXPECT_EQ(foo, pool.FindFileByName("foo.proto"));
+
+ EXPECT_TRUE(pool.FindFileByName("no_such_file.proto") == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindDependencyBeforeDependent) {
+ DescriptorPool pool(&database_);
+
+ const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(foo != NULL);
+ EXPECT_EQ("foo.proto", foo->name());
+ ASSERT_EQ(1, foo->message_type_count());
+ EXPECT_EQ("Foo", foo->message_type(0)->name());
+
+ const FileDescriptor* bar = pool.FindFileByName("bar.proto");
+ ASSERT_TRUE(bar != NULL);
+ EXPECT_EQ("bar.proto", bar->name());
+ ASSERT_EQ(1, bar->message_type_count());
+ EXPECT_EQ("Bar", bar->message_type(0)->name());
+
+ ASSERT_EQ(1, bar->dependency_count());
+ EXPECT_EQ(foo, bar->dependency(0));
+}
+
+TEST_F(DatabaseBackedPoolTest, FindDependentBeforeDependency) {
+ DescriptorPool pool(&database_);
+
+ const FileDescriptor* bar = pool.FindFileByName("bar.proto");
+ ASSERT_TRUE(bar != NULL);
+ EXPECT_EQ("bar.proto", bar->name());
+ ASSERT_EQ(1, bar->message_type_count());
+ ASSERT_EQ("Bar", bar->message_type(0)->name());
+
+ const FileDescriptor* foo = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(foo != NULL);
+ EXPECT_EQ("foo.proto", foo->name());
+ ASSERT_EQ(1, foo->message_type_count());
+ ASSERT_EQ("Foo", foo->message_type(0)->name());
+
+ ASSERT_EQ(1, bar->dependency_count());
+ EXPECT_EQ(foo, bar->dependency(0));
+}
+
+TEST_F(DatabaseBackedPoolTest, FindFileContainingSymbol) {
+ DescriptorPool pool(&database_);
+
+ const FileDescriptor* file = pool.FindFileContainingSymbol("Foo");
+ ASSERT_TRUE(file != NULL);
+ EXPECT_EQ("foo.proto", file->name());
+ EXPECT_EQ(file, pool.FindFileByName("foo.proto"));
+
+ EXPECT_TRUE(pool.FindFileContainingSymbol("NoSuchSymbol") == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindMessageTypeByName) {
+ DescriptorPool pool(&database_);
+
+ const Descriptor* type = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(type != NULL);
+ EXPECT_EQ("Foo", type->name());
+ EXPECT_EQ(type->file(), pool.FindFileByName("foo.proto"));
+
+ EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchType") == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindExtensionByNumber) {
+ DescriptorPool pool(&database_);
+
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != NULL);
+
+ const FieldDescriptor* extension = pool.FindExtensionByNumber(foo, 5);
+ ASSERT_TRUE(extension != NULL);
+ EXPECT_EQ("foo_ext", extension->name());
+ EXPECT_EQ(extension->file(), pool.FindFileByName("bar.proto"));
+
+ EXPECT_TRUE(pool.FindExtensionByNumber(foo, 12) == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, FindAllExtensions) {
+ DescriptorPool pool(&database_);
+
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+
+ for (int i = 0; i < 2; ++i) {
+ // Repeat the lookup twice, to check that we get consistent
+ // results despite the fallback database lookup mutating the pool.
+ vector<const FieldDescriptor*> extensions;
+ pool.FindAllExtensions(foo, &extensions);
+ ASSERT_EQ(1, extensions.size());
+ EXPECT_EQ(5, extensions[0]->number());
+ }
+}
+
+TEST_F(DatabaseBackedPoolTest, ErrorWithoutErrorCollector) {
+ ErrorDescriptorDatabase error_database;
+ DescriptorPool pool(&error_database);
+
+ vector<string> errors;
+
+ {
+ ScopedMemoryLog log;
+ EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
+ errors = log.GetMessages(ERROR);
+ }
+
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST_F(DatabaseBackedPoolTest, ErrorWithErrorCollector) {
+ ErrorDescriptorDatabase error_database;
+ MockErrorCollector error_collector;
+ DescriptorPool pool(&error_database, &error_collector);
+
+ EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
+ EXPECT_EQ(
+ "error.proto: error.proto: OTHER: File recursively imports itself: "
+ "error.proto -> error2.proto -> error.proto\n"
+ "error2.proto: error2.proto: OTHER: Import \"error.proto\" was not "
+ "found or had errors.\n"
+ "error.proto: error.proto: OTHER: Import \"error2.proto\" was not "
+ "found or had errors.\n",
+ error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, UnittestProto) {
+ // Try to load all of unittest.proto from a DescriptorDatabase. This should
+ // thoroughly test all paths through DescriptorBuilder to insure that there
+ // are no deadlocking problems when pool_->mutex_ is non-NULL.
+ const FileDescriptor* original_file =
+ protobuf_unittest::TestAllTypes::descriptor()->file();
+
+ DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
+ DescriptorPool pool(&database);
+ const FileDescriptor* file_from_database =
+ pool.FindFileByName(original_file->name());
+
+ ASSERT_TRUE(file_from_database != NULL);
+
+ FileDescriptorProto original_file_proto;
+ original_file->CopyTo(&original_file_proto);
+
+ FileDescriptorProto file_from_database_proto;
+ file_from_database->CopyTo(&file_from_database_proto);
+
+ EXPECT_EQ(original_file_proto.DebugString(),
+ file_from_database_proto.DebugString());
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntRetryDbUnnecessarily) {
+ // Searching for a child of an existing descriptor should never fall back
+ // to the DescriptorDatabase even if it isn't found, because we know all
+ // children are already loaded.
+ CallCountingDatabase call_counter(&database_);
+ DescriptorPool pool(&call_counter);
+
+ const FileDescriptor* file = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(file != NULL);
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != NULL);
+ const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
+ ASSERT_TRUE(test_enum != NULL);
+ const ServiceDescriptor* test_service = pool.FindServiceByName("TestService");
+ ASSERT_TRUE(test_service != NULL);
+
+ EXPECT_NE(0, call_counter.call_count_);
+ call_counter.Clear();
+
+ EXPECT_TRUE(foo->FindFieldByName("no_such_field") == NULL);
+ EXPECT_TRUE(foo->FindExtensionByName("no_such_extension") == NULL);
+ EXPECT_TRUE(foo->FindNestedTypeByName("NoSuchMessageType") == NULL);
+ EXPECT_TRUE(foo->FindEnumTypeByName("NoSuchEnumType") == NULL);
+ EXPECT_TRUE(foo->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
+ EXPECT_TRUE(test_enum->FindValueByName("NO_SUCH_VALUE") == NULL);
+ EXPECT_TRUE(test_service->FindMethodByName("NoSuchMethod") == NULL);
+
+ EXPECT_TRUE(file->FindMessageTypeByName("NoSuchMessageType") == NULL);
+ EXPECT_TRUE(file->FindEnumTypeByName("NoSuchEnumType") == NULL);
+ EXPECT_TRUE(file->FindEnumValueByName("NO_SUCH_VALUE") == NULL);
+ EXPECT_TRUE(file->FindServiceByName("NO_SUCH_VALUE") == NULL);
+ EXPECT_TRUE(file->FindExtensionByName("no_such_extension") == NULL);
+ EXPECT_EQ(0, call_counter.call_count_);
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntReloadFilesUncesessarily) {
+ // If FindFileContainingSymbol() or FindFileContainingExtension() return a
+ // file that is already in the DescriptorPool, it should not attempt to
+ // reload the file.
+ FalsePositiveDatabase false_positive_database(&database_);
+ MockErrorCollector error_collector;
+ DescriptorPool pool(&false_positive_database, &error_collector);
+
+ // First make sure foo.proto is loaded.
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != NULL);
+
+ // Try inducing false positives.
+ EXPECT_TRUE(pool.FindMessageTypeByName("NoSuchSymbol") == NULL);
+ EXPECT_TRUE(pool.FindExtensionByNumber(foo, 22) == NULL);
+
+ // No errors should have been reported. (If foo.proto was incorrectly
+ // loaded multiple times, errors would have been reported.)
+ EXPECT_EQ("", error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
+ ErrorDescriptorDatabase error_database;
+ MockErrorCollector error_collector;
+ DescriptorPool pool(&error_database, &error_collector);
+
+ EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
+ error_collector.text_.clear();
+ EXPECT_TRUE(pool.FindFileByName("error.proto") == NULL);
+ EXPECT_EQ("", error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
+ // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
+ // to FindFieldByName()), we should fail fast, without checking the fallback
+ // database.
+ CallCountingDatabase call_counter(&database_);
+ DescriptorPool pool(&call_counter);
+
+ const FileDescriptor* file = pool.FindFileByName("foo.proto");
+ ASSERT_TRUE(file != NULL);
+ const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+ ASSERT_TRUE(foo != NULL);
+ const EnumDescriptor* test_enum = pool.FindEnumTypeByName("TestEnum");
+ ASSERT_TRUE(test_enum != NULL);
+
+ EXPECT_NE(0, call_counter.call_count_);
+ call_counter.Clear();
+
+ EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL);
+ EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL);
+ EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL);
+
+ EXPECT_EQ(0, call_counter.call_count_);
+}
+
+// ===================================================================
+
+
+} // namespace descriptor_unittest
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/dynamic_message.cc b/src/third_party/protobuf/src/google/protobuf/dynamic_message.cc
new file mode 100644
index 0000000..c711a2d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/dynamic_message.cc
@@ -0,0 +1,558 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// DynamicMessage is implemented by constructing a data structure which
+// has roughly the same memory layout as a generated message would have.
+// Then, we use GeneratedMessageReflection to implement our reflection
+// interface. All the other operations we need to implement (e.g.
+// parsing, copying, etc.) are already implemented in terms of
+// Reflection, so the rest is easy.
+//
+// The up side of this strategy is that it's very efficient. We don't
+// need to use hash_maps or generic representations of fields. The
+// down side is that this is a low-level memory management hack which
+// can be tricky to get right.
+//
+// As mentioned in the header, we only expose a DynamicMessageFactory
+// publicly, not the DynamicMessage class itself. This is because
+// GenericMessageReflection wants to have a pointer to a "default"
+// copy of the class, with all fields initialized to their default
+// values. We only want to construct one of these per message type,
+// so DynamicMessageFactory stores a cache of default messages for
+// each type it sees (each unique Descriptor pointer). The code
+// refers to the "default" copy of the class as the "prototype".
+//
+// Note on memory allocation: This module often calls "operator new()"
+// to allocate untyped memory, rather than calling something like
+// "new uint8[]". This is because "operator new()" means "Give me some
+// space which I can use as I please." while "new uint8[]" means "Give
+// me an array of 8-bit integers.". In practice, the later may return
+// a pointer that is not aligned correctly for general use. I believe
+// Item 8 of "More Effective C++" discusses this in more detail, though
+// I don't have the book on me right now so I'm not sure.
+
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/stubs/common.h>
+
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/wire_format.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+using internal::ExtensionSet;
+using internal::GeneratedMessageReflection;
+
+
+// ===================================================================
+// Some helper tables and functions...
+
+namespace {
+
+// Compute the byte size of the in-memory representation of the field.
+int FieldSpaceUsed(const FieldDescriptor* field) {
+ typedef FieldDescriptor FD; // avoid line wrapping
+ if (field->label() == FD::LABEL_REPEATED) {
+ switch (field->cpp_type()) {
+ case FD::CPPTYPE_INT32 : return sizeof(RepeatedField<int32 >);
+ case FD::CPPTYPE_INT64 : return sizeof(RepeatedField<int64 >);
+ case FD::CPPTYPE_UINT32 : return sizeof(RepeatedField<uint32 >);
+ case FD::CPPTYPE_UINT64 : return sizeof(RepeatedField<uint64 >);
+ case FD::CPPTYPE_DOUBLE : return sizeof(RepeatedField<double >);
+ case FD::CPPTYPE_FLOAT : return sizeof(RepeatedField<float >);
+ case FD::CPPTYPE_BOOL : return sizeof(RepeatedField<bool >);
+ case FD::CPPTYPE_ENUM : return sizeof(RepeatedField<int >);
+ case FD::CPPTYPE_MESSAGE: return sizeof(RepeatedPtrField<Message>);
+
+ case FD::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ return sizeof(RepeatedPtrField<string>);
+ }
+ break;
+ }
+ } else {
+ switch (field->cpp_type()) {
+ case FD::CPPTYPE_INT32 : return sizeof(int32 );
+ case FD::CPPTYPE_INT64 : return sizeof(int64 );
+ case FD::CPPTYPE_UINT32 : return sizeof(uint32 );
+ case FD::CPPTYPE_UINT64 : return sizeof(uint64 );
+ case FD::CPPTYPE_DOUBLE : return sizeof(double );
+ case FD::CPPTYPE_FLOAT : return sizeof(float );
+ case FD::CPPTYPE_BOOL : return sizeof(bool );
+ case FD::CPPTYPE_ENUM : return sizeof(int );
+ case FD::CPPTYPE_MESSAGE: return sizeof(Message*);
+
+ case FD::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ return sizeof(string*);
+ }
+ break;
+ }
+ }
+
+ GOOGLE_LOG(DFATAL) << "Can't get here.";
+ return 0;
+}
+
+inline int DivideRoundingUp(int i, int j) {
+ return (i + (j - 1)) / j;
+}
+
+static const int kSafeAlignment = sizeof(uint64);
+
+inline int AlignTo(int offset, int alignment) {
+ return DivideRoundingUp(offset, alignment) * alignment;
+}
+
+// Rounds the given byte offset up to the next offset aligned such that any
+// type may be stored at it.
+inline int AlignOffset(int offset) {
+ return AlignTo(offset, kSafeAlignment);
+}
+
+#define bitsizeof(T) (sizeof(T) * 8)
+
+} // namespace
+
+// ===================================================================
+
+class DynamicMessage : public Message {
+ public:
+ struct TypeInfo {
+ int size;
+ int has_bits_offset;
+ int unknown_fields_offset;
+ int extensions_offset;
+
+ // Not owned by the TypeInfo.
+ DynamicMessageFactory* factory; // The factory that created this object.
+ const DescriptorPool* pool; // The factory's DescriptorPool.
+ const Descriptor* type; // Type of this DynamicMessage.
+
+ // Warning: The order in which the following pointers are defined is
+ // important (the prototype must be deleted *before* the offsets).
+ scoped_array<int> offsets;
+ scoped_ptr<const GeneratedMessageReflection> reflection;
+ scoped_ptr<const DynamicMessage> prototype;
+ };
+
+ DynamicMessage(const TypeInfo* type_info);
+ ~DynamicMessage();
+
+ // Called on the prototype after construction to initialize message fields.
+ void CrossLinkPrototypes();
+
+ // implements Message ----------------------------------------------
+
+ Message* New() const;
+
+ int GetCachedSize() const;
+ void SetCachedSize(int size) const;
+
+ Metadata GetMetadata() const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
+
+ inline bool is_prototype() const {
+ return type_info_->prototype == this ||
+ // If type_info_->prototype is NULL, then we must be constructing
+ // the prototype now, which means we must be the prototype.
+ type_info_->prototype == NULL;
+ }
+
+ inline void* OffsetToPointer(int offset) {
+ return reinterpret_cast<uint8*>(this) + offset;
+ }
+ inline const void* OffsetToPointer(int offset) const {
+ return reinterpret_cast<const uint8*>(this) + offset;
+ }
+
+ const TypeInfo* type_info_;
+
+ // TODO(kenton): Make this an atomic<int> when C++ supports it.
+ mutable int cached_byte_size_;
+};
+
+DynamicMessage::DynamicMessage(const TypeInfo* type_info)
+ : type_info_(type_info),
+ cached_byte_size_(0) {
+ // We need to call constructors for various fields manually and set
+ // default values where appropriate. We use placement new to call
+ // constructors. If you haven't heard of placement new, I suggest Googling
+ // it now. We use placement new even for primitive types that don't have
+ // constructors for consistency. (In theory, placement new should be used
+ // any time you are trying to convert untyped memory to typed memory, though
+ // in practice that's not strictly necessary for types that don't have a
+ // constructor.)
+
+ const Descriptor* descriptor = type_info_->type;
+
+ new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet;
+
+ if (type_info_->extensions_offset != -1) {
+ new(OffsetToPointer(type_info_->extensions_offset)) ExtensionSet;
+ }
+
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ const FieldDescriptor* field = descriptor->field(i);
+ void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ if (!field->is_repeated()) { \
+ new(field_ptr) TYPE(field->default_value_##TYPE()); \
+ } else { \
+ new(field_ptr) RepeatedField<TYPE>(); \
+ } \
+ break;
+
+ HANDLE_TYPE(INT32 , int32 );
+ HANDLE_TYPE(INT64 , int64 );
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE(FLOAT , float );
+ HANDLE_TYPE(BOOL , bool );
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ if (!field->is_repeated()) {
+ new(field_ptr) int(field->default_value_enum()->number());
+ } else {
+ new(field_ptr) RepeatedField<int>();
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ if (!field->is_repeated()) {
+ if (is_prototype()) {
+ new(field_ptr) const string*(&field->default_value_string());
+ } else {
+ string* default_value =
+ *reinterpret_cast<string* const*>(
+ type_info_->prototype->OffsetToPointer(
+ type_info_->offsets[i]));
+ new(field_ptr) string*(default_value);
+ }
+ } else {
+ new(field_ptr) RepeatedPtrField<string>();
+ }
+ break;
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ if (!field->is_repeated()) {
+ new(field_ptr) Message*(NULL);
+ } else {
+ new(field_ptr) RepeatedPtrField<Message>();
+ }
+ break;
+ }
+ }
+ }
+}
+
+DynamicMessage::~DynamicMessage() {
+ const Descriptor* descriptor = type_info_->type;
+
+ reinterpret_cast<UnknownFieldSet*>(
+ OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet();
+
+ if (type_info_->extensions_offset != -1) {
+ reinterpret_cast<ExtensionSet*>(
+ OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet();
+ }
+
+ // We need to manually run the destructors for repeated fields and strings,
+ // just as we ran their constructors in the the DynamicMessage constructor.
+ // Additionally, if any singular embedded messages have been allocated, we
+ // need to delete them, UNLESS we are the prototype message of this type,
+ // in which case any embedded messages are other prototypes and shouldn't
+ // be touched.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ const FieldDescriptor* field = descriptor->field(i);
+ void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
+
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE : \
+ reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr) \
+ ->~RepeatedField<LOWERCASE>(); \
+ break
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, int);
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ reinterpret_cast<RepeatedPtrField<string>*>(field_ptr)
+ ->~RepeatedPtrField<string>();
+ break;
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
+ ->~RepeatedPtrField<Message>();
+ break;
+ }
+
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING: {
+ string* ptr = *reinterpret_cast<string**>(field_ptr);
+ if (ptr != &field->default_value_string()) {
+ delete ptr;
+ }
+ break;
+ }
+ }
+ } else if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) &&
+ !is_prototype()) {
+ Message* message = *reinterpret_cast<Message**>(field_ptr);
+ if (message != NULL) {
+ delete message;
+ }
+ }
+ }
+}
+
+void DynamicMessage::CrossLinkPrototypes() {
+ // This should only be called on the prototype message.
+ GOOGLE_CHECK(is_prototype());
+
+ DynamicMessageFactory* factory = type_info_->factory;
+ const Descriptor* descriptor = type_info_->type;
+
+ // Cross-link default messages.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ const FieldDescriptor* field = descriptor->field(i);
+ void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_repeated()) {
+ // For fields with message types, we need to cross-link with the
+ // prototype for the field's type.
+ // For singular fields, the field is just a pointer which should
+ // point to the prototype.
+ *reinterpret_cast<const Message**>(field_ptr) =
+ factory->GetPrototypeNoLock(field->message_type());
+ }
+ }
+}
+
+Message* DynamicMessage::New() const {
+ void* new_base = reinterpret_cast<uint8*>(operator new(type_info_->size));
+ memset(new_base, 0, type_info_->size);
+ return new(new_base) DynamicMessage(type_info_);
+}
+
+int DynamicMessage::GetCachedSize() const {
+ return cached_byte_size_;
+}
+
+void DynamicMessage::SetCachedSize(int size) const {
+ // This is theoretically not thread-compatible, but in practice it works
+ // because if multiple threads write this simultaneously, they will be
+ // writing the exact same value.
+ cached_byte_size_ = size;
+}
+
+Metadata DynamicMessage::GetMetadata() const {
+ Metadata metadata;
+ metadata.descriptor = type_info_->type;
+ metadata.reflection = type_info_->reflection.get();
+ return metadata;
+}
+
+// ===================================================================
+
+struct DynamicMessageFactory::PrototypeMap {
+ typedef hash_map<const Descriptor*, const DynamicMessage::TypeInfo*> Map;
+ Map map_;
+};
+
+DynamicMessageFactory::DynamicMessageFactory()
+ : pool_(NULL), delegate_to_generated_factory_(false),
+ prototypes_(new PrototypeMap) {
+}
+
+DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
+ : pool_(pool), delegate_to_generated_factory_(false),
+ prototypes_(new PrototypeMap) {
+}
+
+DynamicMessageFactory::~DynamicMessageFactory() {
+ for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
+ iter != prototypes_->map_.end(); ++iter) {
+ delete iter->second;
+ }
+}
+
+const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
+ MutexLock lock(&prototypes_mutex_);
+ return GetPrototypeNoLock(type);
+}
+
+const Message* DynamicMessageFactory::GetPrototypeNoLock(
+ const Descriptor* type) {
+ if (delegate_to_generated_factory_ &&
+ type->file()->pool() == DescriptorPool::generated_pool()) {
+ return MessageFactory::generated_factory()->GetPrototype(type);
+ }
+
+ const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
+ if (*target != NULL) {
+ // Already exists.
+ return (*target)->prototype.get();
+ }
+
+ DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
+ *target = type_info;
+
+ type_info->type = type;
+ type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
+ type_info->factory = this;
+
+ // We need to construct all the structures passed to
+ // GeneratedMessageReflection's constructor. This includes:
+ // - A block of memory that contains space for all the message's fields.
+ // - An array of integers indicating the byte offset of each field within
+ // this block.
+ // - A big bitfield containing a bit for each field indicating whether
+ // or not that field is set.
+
+ // Compute size and offsets.
+ int* offsets = new int[type->field_count()];
+ type_info->offsets.reset(offsets);
+
+ // Decide all field offsets by packing in order.
+ // We place the DynamicMessage object itself at the beginning of the allocated
+ // space.
+ int size = sizeof(DynamicMessage);
+ size = AlignOffset(size);
+
+ // Next the has_bits, which is an array of uint32s.
+ type_info->has_bits_offset = size;
+ int has_bits_array_size =
+ DivideRoundingUp(type->field_count(), bitsizeof(uint32));
+ size += has_bits_array_size * sizeof(uint32);
+ size = AlignOffset(size);
+
+ // The ExtensionSet, if any.
+ if (type->extension_range_count() > 0) {
+ type_info->extensions_offset = size;
+ size += sizeof(ExtensionSet);
+ size = AlignOffset(size);
+ } else {
+ // No extensions.
+ type_info->extensions_offset = -1;
+ }
+
+ // All the fields.
+ for (int i = 0; i < type->field_count(); i++) {
+ // Make sure field is aligned to avoid bus errors.
+ int field_size = FieldSpaceUsed(type->field(i));
+ size = AlignTo(size, min(kSafeAlignment, field_size));
+ offsets[i] = size;
+ size += field_size;
+ }
+
+ // Add the UnknownFieldSet to the end.
+ size = AlignOffset(size);
+ type_info->unknown_fields_offset = size;
+ size += sizeof(UnknownFieldSet);
+
+ // Align the final size to make sure no clever allocators think that
+ // alignment is not necessary.
+ size = AlignOffset(size);
+ type_info->size = size;
+
+ // Allocate the prototype.
+ void* base = operator new(size);
+ memset(base, 0, size);
+ DynamicMessage* prototype = new(base) DynamicMessage(type_info);
+ type_info->prototype.reset(prototype);
+
+ // Construct the reflection object.
+ type_info->reflection.reset(
+ new GeneratedMessageReflection(
+ type_info->type,
+ type_info->prototype.get(),
+ type_info->offsets.get(),
+ type_info->has_bits_offset,
+ type_info->unknown_fields_offset,
+ type_info->extensions_offset,
+ type_info->pool,
+ this,
+ type_info->size));
+
+ // Cross link prototypes.
+ prototype->CrossLinkPrototypes();
+
+ return prototype;
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/dynamic_message.h b/src/third_party/protobuf/src/google/protobuf/dynamic_message.h
new file mode 100644
index 0000000..81dd2c6
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/dynamic_message.h
@@ -0,0 +1,136 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines an implementation of Message which can emulate types which are not
+// known at compile-time.
+
+#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
+#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
+
+#include <google/protobuf/message.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// Defined in other files.
+class Descriptor; // descriptor.h
+class DescriptorPool; // descriptor.h
+
+// Constructs implementations of Message which can emulate types which are not
+// known at compile-time.
+//
+// Sometimes you want to be able to manipulate protocol types that you don't
+// know about at compile time. It would be nice to be able to construct
+// a Message object which implements the message type given by any arbitrary
+// Descriptor. DynamicMessage provides this.
+//
+// As it turns out, a DynamicMessage needs to construct extra
+// information about its type in order to operate. Most of this information
+// can be shared between all DynamicMessages of the same type. But, caching
+// this information in some sort of global map would be a bad idea, since
+// the cached information for a particular descriptor could outlive the
+// descriptor itself. To avoid this problem, DynamicMessageFactory
+// encapsulates this "cache". All DynamicMessages of the same type created
+// from the same factory will share the same support data. Any Descriptors
+// used with a particular factory must outlive the factory.
+class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
+ public:
+ // Construct a DynamicMessageFactory that will search for extensions in
+ // the DescriptorPool in which the exendee is defined.
+ DynamicMessageFactory();
+
+ // Construct a DynamicMessageFactory that will search for extensions in
+ // the given DescriptorPool.
+ //
+ // DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the
+ // parser to look for extensions in an alternate pool. However, note that
+ // this is almost never what you want to do. Almost all users should use
+ // the zero-arg constructor.
+ DynamicMessageFactory(const DescriptorPool* pool);
+
+ ~DynamicMessageFactory();
+
+ // Call this to tell the DynamicMessageFactory that if it is given a
+ // Descriptor d for which:
+ // d->file()->pool() == DescriptorPool::generated_pool(),
+ // then it should delegate to MessageFactory::generated_factory() instead
+ // of constructing a dynamic implementation of the message. In theory there
+ // is no down side to doing this, so it may become the default in the future.
+ void SetDelegateToGeneratedFactory(bool enable) {
+ delegate_to_generated_factory_ = enable;
+ }
+
+ // implements MessageFactory ---------------------------------------
+
+ // Given a Descriptor, constructs the default (prototype) Message of that
+ // type. You can then call that message's New() method to construct a
+ // mutable message of that type.
+ //
+ // Calling this method twice with the same Descriptor returns the same
+ // object. The returned object remains property of the factory and will
+ // be destroyed when the factory is destroyed. Also, any objects created
+ // by calling the prototype's New() method share some data with the
+ // prototype, so these must be destoyed before the DynamicMessageFactory
+ // is destroyed.
+ //
+ // The given descriptor must outlive the returned message, and hence must
+ // outlive the DynamicMessageFactory.
+ //
+ // The method is thread-safe.
+ const Message* GetPrototype(const Descriptor* type);
+
+ private:
+ const DescriptorPool* pool_;
+ bool delegate_to_generated_factory_;
+
+ // This struct just contains a hash_map. We can't #include <google/protobuf/stubs/hash.h> from
+ // this header due to hacks needed for hash_map portability in the open source
+ // release. Namely, stubs/hash.h, which defines hash_map portably, is not a
+ // public header (for good reason), but dynamic_message.h is, and public
+ // headers may only #include other public headers.
+ struct PrototypeMap;
+ scoped_ptr<PrototypeMap> prototypes_;
+ mutable Mutex prototypes_mutex_;
+
+ friend class DynamicMessage;
+ const Message* GetPrototypeNoLock(const Descriptor* type);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
+};
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc b/src/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc
new file mode 100644
index 0000000..41b89ab
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc
@@ -0,0 +1,162 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Since the reflection interface for DynamicMessage is implemented by
+// GenericMessageReflection, the only thing we really have to test is
+// that DynamicMessage correctly sets up the information that
+// GenericMessageReflection needs to use. So, we focus on that in this
+// test. Other tests, such as generic_message_reflection_unittest and
+// reflection_ops_unittest, cover the rest of the functionality used by
+// DynamicMessage.
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/unittest.pb.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+class DynamicMessageTest : public testing::Test {
+ protected:
+ DescriptorPool pool_;
+ DynamicMessageFactory factory_;
+ const Descriptor* descriptor_;
+ const Message* prototype_;
+ const Descriptor* extensions_descriptor_;
+ const Message* extensions_prototype_;
+ const Descriptor* packed_descriptor_;
+ const Message* packed_prototype_;
+
+ DynamicMessageTest(): factory_(&pool_) {}
+
+ virtual void SetUp() {
+ // We want to make sure that DynamicMessage works (particularly with
+ // extensions) even if we use descriptors that are *not* from compiled-in
+ // types, so we make copies of the descriptors for unittest.proto and
+ // unittest_import.proto.
+ FileDescriptorProto unittest_file;
+ FileDescriptorProto unittest_import_file;
+
+ unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
+ unittest_import::ImportMessage::descriptor()->file()->CopyTo(
+ &unittest_import_file);
+
+ ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != NULL);
+ ASSERT_TRUE(pool_.BuildFile(unittest_file) != NULL);
+
+ descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes");
+ ASSERT_TRUE(descriptor_ != NULL);
+ prototype_ = factory_.GetPrototype(descriptor_);
+
+ extensions_descriptor_ =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions");
+ ASSERT_TRUE(extensions_descriptor_ != NULL);
+ extensions_prototype_ = factory_.GetPrototype(extensions_descriptor_);
+
+ packed_descriptor_ =
+ pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes");
+ ASSERT_TRUE(packed_descriptor_ != NULL);
+ packed_prototype_ = factory_.GetPrototype(packed_descriptor_);
+ }
+};
+
+TEST_F(DynamicMessageTest, Descriptor) {
+ // Check that the descriptor on the DynamicMessage matches the descriptor
+ // passed to GetPrototype().
+ EXPECT_EQ(prototype_->GetDescriptor(), descriptor_);
+}
+
+TEST_F(DynamicMessageTest, OnePrototype) {
+ // Check that requesting the same prototype twice produces the same object.
+ EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_));
+}
+
+TEST_F(DynamicMessageTest, Defaults) {
+ // Check that all default values are set correctly in the initial message.
+ TestUtil::ReflectionTester reflection_tester(descriptor_);
+ reflection_tester.ExpectClearViaReflection(*prototype_);
+}
+
+TEST_F(DynamicMessageTest, IndependentOffsets) {
+ // Check that all fields have independent offsets by setting each
+ // one to a unique value then checking that they all still have those
+ // unique values (i.e. they don't stomp each other).
+ scoped_ptr<Message> message(prototype_->New());
+ TestUtil::ReflectionTester reflection_tester(descriptor_);
+
+ reflection_tester.SetAllFieldsViaReflection(message.get());
+ reflection_tester.ExpectAllFieldsSetViaReflection(*message);
+}
+
+TEST_F(DynamicMessageTest, Extensions) {
+ // Check that extensions work.
+ scoped_ptr<Message> message(extensions_prototype_->New());
+ TestUtil::ReflectionTester reflection_tester(extensions_descriptor_);
+
+ reflection_tester.SetAllFieldsViaReflection(message.get());
+ reflection_tester.ExpectAllFieldsSetViaReflection(*message);
+}
+
+TEST_F(DynamicMessageTest, PackedFields) {
+ // Check that packed fields work properly.
+ scoped_ptr<Message> message(packed_prototype_->New());
+ TestUtil::ReflectionTester reflection_tester(packed_descriptor_);
+
+ reflection_tester.SetPackedFieldsViaReflection(message.get());
+ reflection_tester.ExpectPackedFieldsSetViaReflection(*message);
+}
+
+TEST_F(DynamicMessageTest, SpaceUsed) {
+ // Test that SpaceUsed() works properly
+
+ // Since we share the implementation with generated messages, we don't need
+ // to test very much here. Just make sure it appears to be working.
+
+ scoped_ptr<Message> message(prototype_->New());
+ TestUtil::ReflectionTester reflection_tester(descriptor_);
+
+ int initial_space_used = message->SpaceUsed();
+
+ reflection_tester.SetAllFieldsViaReflection(message.get());
+ EXPECT_LT(initial_space_used, message->SpaceUsed());
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/extension_set.cc b/src/third_party/protobuf/src/google/protobuf/extension_set.cc
new file mode 100644
index 0000000..dbb0915
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/extension_set.cc
@@ -0,0 +1,1466 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/map-util.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace {
+
+inline WireFormatLite::FieldType real_type(FieldType type) {
+ GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
+ return static_cast<WireFormatLite::FieldType>(type);
+}
+
+inline WireFormatLite::CppType cpp_type(FieldType type) {
+ return WireFormatLite::FieldTypeToCppType(real_type(type));
+}
+
+// Registry stuff.
+typedef hash_map<pair<const MessageLite*, int>,
+ ExtensionInfo> ExtensionRegistry;
+ExtensionRegistry* registry_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
+
+void DeleteRegistry() {
+ delete registry_;
+ registry_ = NULL;
+}
+
+void InitRegistry() {
+ registry_ = new ExtensionRegistry;
+ internal::OnShutdown(&DeleteRegistry);
+}
+
+// This function is only called at startup, so there is no need for thread-
+// safety.
+void Register(const MessageLite* containing_type,
+ int number, ExtensionInfo info) {
+ ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry);
+
+ if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
+ info)) {
+ GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
+ << containing_type->GetTypeName()
+ << "\", field number " << number << ".";
+ }
+}
+
+const ExtensionInfo* FindRegisteredExtension(
+ const MessageLite* containing_type, int number) {
+ return (registry_ == NULL) ? NULL :
+ FindOrNull(*registry_, make_pair(containing_type, number));
+}
+
+} // namespace
+
+ExtensionFinder::~ExtensionFinder() {}
+
+bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
+ const ExtensionInfo* extension =
+ FindRegisteredExtension(containing_type_, number);
+ if (extension == NULL) {
+ return false;
+ } else {
+ *output = *extension;
+ return true;
+ }
+}
+
+void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
+ int number, FieldType type,
+ bool is_repeated, bool is_packed) {
+ GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
+ GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
+ GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
+ ExtensionInfo info(type, is_repeated, is_packed);
+ Register(containing_type, number, info);
+}
+
+static bool CallNoArgValidityFunc(const void* arg, int number) {
+ // Note: Must use C-style cast here rather than reinterpret_cast because
+ // the C++ standard at one point did not allow casts between function and
+ // data pointers and some compilers enforce this for C++-style casts. No
+ // compiler enforces it for C-style casts since lots of C-style code has
+ // relied on these kinds of casts for a long time, despite being
+ // technically undefined. See:
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
+ // Also note: Some compilers do not allow function pointers to be "const".
+ // Which makes sense, I suppose, because it's meaningless.
+ return ((EnumValidityFunc*)arg)(number);
+}
+
+void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
+ int number, FieldType type,
+ bool is_repeated, bool is_packed,
+ EnumValidityFunc* is_valid) {
+ GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
+ ExtensionInfo info(type, is_repeated, is_packed);
+ info.enum_validity_check.func = CallNoArgValidityFunc;
+ // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
+ info.enum_validity_check.arg = (void*)is_valid;
+ Register(containing_type, number, info);
+}
+
+void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
+ int number, FieldType type,
+ bool is_repeated, bool is_packed,
+ const MessageLite* prototype) {
+ GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
+ type == WireFormatLite::TYPE_GROUP);
+ ExtensionInfo info(type, is_repeated, is_packed);
+ info.message_prototype = prototype;
+ Register(containing_type, number, info);
+}
+
+
+// ===================================================================
+// Constructors and basic methods.
+
+ExtensionSet::ExtensionSet() {}
+
+ExtensionSet::~ExtensionSet() {
+ for (map<int, Extension>::iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ iter->second.Free();
+ }
+}
+
+// Defined in extension_set_heavy.cc.
+// void ExtensionSet::AppendToList(const Descriptor* containing_type,
+// const DescriptorPool* pool,
+// vector<const FieldDescriptor*>* output) const
+
+bool ExtensionSet::Has(int number) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) return false;
+ GOOGLE_DCHECK(!iter->second.is_repeated);
+ return !iter->second.is_cleared;
+}
+
+int ExtensionSet::ExtensionSize(int number) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) return false;
+ return iter->second.GetSize();
+}
+
+FieldType ExtensionSet::ExtensionType(int number) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) {
+ GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
+ return 0;
+ }
+ if (iter->second.is_cleared) {
+ GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
+ }
+ return iter->second.type;
+}
+
+void ExtensionSet::ClearExtension(int number) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) return;
+ iter->second.Clear();
+}
+
+// ===================================================================
+// Field accessors
+
+namespace {
+
+enum Cardinality {
+ REPEATED,
+ OPTIONAL
+};
+
+} // namespace
+
+#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
+ GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \
+ GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
+
+// -------------------------------------------------------------------
+// Primitives
+
+#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
+ \
+LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
+ LOWERCASE default_value) const { \
+ map<int, Extension>::const_iterator iter = extensions_.find(number); \
+ if (iter == extensions_.end() || iter->second.is_cleared) { \
+ return default_value; \
+ } else { \
+ GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
+ return iter->second.LOWERCASE##_value; \
+ } \
+} \
+ \
+void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
+ LOWERCASE value, \
+ const FieldDescriptor* descriptor) { \
+ Extension* extension; \
+ if (MaybeNewExtension(number, descriptor, &extension)) { \
+ extension->type = type; \
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
+ extension->is_repeated = false; \
+ } else { \
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
+ } \
+ extension->is_cleared = false; \
+ extension->LOWERCASE##_value = value; \
+} \
+ \
+LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
+ map<int, Extension>::const_iterator iter = extensions_.find(number); \
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
+ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
+ return iter->second.repeated_##LOWERCASE##_value->Get(index); \
+} \
+ \
+void ExtensionSet::SetRepeated##CAMELCASE( \
+ int number, int index, LOWERCASE value) { \
+ map<int, Extension>::iterator iter = extensions_.find(number); \
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
+ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
+ iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
+} \
+ \
+void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
+ bool packed, LOWERCASE value, \
+ const FieldDescriptor* descriptor) { \
+ Extension* extension; \
+ if (MaybeNewExtension(number, descriptor, &extension)) { \
+ extension->type = type; \
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
+ extension->is_repeated = true; \
+ extension->is_packed = packed; \
+ extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \
+ } else { \
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
+ GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
+ } \
+ extension->repeated_##LOWERCASE##_value->Add(value); \
+}
+
+PRIMITIVE_ACCESSORS( INT32, int32, Int32)
+PRIMITIVE_ACCESSORS( INT64, int64, Int64)
+PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
+PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
+PRIMITIVE_ACCESSORS( FLOAT, float, Float)
+PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
+PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
+
+#undef PRIMITIVE_ACCESSORS
+
+// -------------------------------------------------------------------
+// Enums
+
+int ExtensionSet::GetEnum(int number, int default_value) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end() || iter->second.is_cleared) {
+ // Not present. Return the default value.
+ return default_value;
+ } else {
+ GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
+ return iter->second.enum_value;
+ }
+}
+
+void ExtensionSet::SetEnum(int number, FieldType type, int value,
+ const FieldDescriptor* descriptor) {
+ Extension* extension;
+ if (MaybeNewExtension(number, descriptor, &extension)) {
+ extension->type = type;
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
+ extension->is_repeated = false;
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
+ }
+ extension->is_cleared = false;
+ extension->enum_value = value;
+}
+
+int ExtensionSet::GetRepeatedEnum(int number, int index) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
+ return iter->second.repeated_enum_value->Get(index);
+}
+
+void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
+ iter->second.repeated_enum_value->Set(index, value);
+}
+
+void ExtensionSet::AddEnum(int number, FieldType type,
+ bool packed, int value,
+ const FieldDescriptor* descriptor) {
+ Extension* extension;
+ if (MaybeNewExtension(number, descriptor, &extension)) {
+ extension->type = type;
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
+ extension->is_repeated = true;
+ extension->is_packed = packed;
+ extension->repeated_enum_value = new RepeatedField<int>();
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
+ GOOGLE_DCHECK_EQ(extension->is_packed, packed);
+ }
+ extension->repeated_enum_value->Add(value);
+}
+
+// -------------------------------------------------------------------
+// Strings
+
+const string& ExtensionSet::GetString(int number,
+ const string& default_value) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end() || iter->second.is_cleared) {
+ // Not present. Return the default value.
+ return default_value;
+ } else {
+ GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
+ return *iter->second.string_value;
+ }
+}
+
+string* ExtensionSet::MutableString(int number, FieldType type,
+ const FieldDescriptor* descriptor) {
+ Extension* extension;
+ if (MaybeNewExtension(number, descriptor, &extension)) {
+ extension->type = type;
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
+ extension->is_repeated = false;
+ extension->string_value = new string;
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
+ }
+ extension->is_cleared = false;
+ return extension->string_value;
+}
+
+const string& ExtensionSet::GetRepeatedString(int number, int index) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
+ return iter->second.repeated_string_value->Get(index);
+}
+
+string* ExtensionSet::MutableRepeatedString(int number, int index) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
+ return iter->second.repeated_string_value->Mutable(index);
+}
+
+string* ExtensionSet::AddString(int number, FieldType type,
+ const FieldDescriptor* descriptor) {
+ Extension* extension;
+ if (MaybeNewExtension(number, descriptor, &extension)) {
+ extension->type = type;
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
+ extension->is_repeated = true;
+ extension->is_packed = false;
+ extension->repeated_string_value = new RepeatedPtrField<string>();
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
+ }
+ return extension->repeated_string_value->Add();
+}
+
+// -------------------------------------------------------------------
+// Messages
+
+const MessageLite& ExtensionSet::GetMessage(
+ int number, const MessageLite& default_value) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end()) {
+ // Not present. Return the default value.
+ return default_value;
+ } else {
+ GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
+ return *iter->second.message_value;
+ }
+}
+
+// Defined in extension_set_heavy.cc.
+// const MessageLite& ExtensionSet::GetMessage(int number,
+// const Descriptor* message_type,
+// MessageFactory* factory) const
+
+MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
+ const MessageLite& prototype,
+ const FieldDescriptor* descriptor) {
+ Extension* extension;
+ if (MaybeNewExtension(number, descriptor, &extension)) {
+ extension->type = type;
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
+ extension->is_repeated = false;
+ extension->message_value = prototype.New();
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ }
+ extension->is_cleared = false;
+ return extension->message_value;
+}
+
+// Defined in extension_set_heavy.cc.
+// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
+// const Descriptor* message_type,
+// MessageFactory* factory)
+
+const MessageLite& ExtensionSet::GetRepeatedMessage(
+ int number, int index) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
+ return iter->second.repeated_message_value->Get(index);
+}
+
+MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+ GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
+ return iter->second.repeated_message_value->Mutable(index);
+}
+
+MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
+ const MessageLite& prototype,
+ const FieldDescriptor* descriptor) {
+ Extension* extension;
+ if (MaybeNewExtension(number, descriptor, &extension)) {
+ extension->type = type;
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
+ extension->is_repeated = true;
+ extension->repeated_message_value =
+ new RepeatedPtrField<MessageLite>();
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
+ }
+
+ // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
+ // allocate an abstract object, so we have to be tricky.
+ MessageLite* result = extension->repeated_message_value
+ ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
+ if (result == NULL) {
+ result = prototype.New();
+ extension->repeated_message_value->AddAllocated(result);
+ }
+ return result;
+}
+
+// Defined in extension_set_heavy.cc.
+// MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
+// const Descriptor* message_type,
+// MessageFactory* factory)
+
+#undef GOOGLE_DCHECK_TYPE
+
+void ExtensionSet::RemoveLast(int number) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+
+ Extension* extension = &iter->second;
+ GOOGLE_DCHECK(extension->is_repeated);
+
+ switch(cpp_type(extension->type)) {
+ case WireFormatLite::CPPTYPE_INT32:
+ extension->repeated_int32_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_INT64:
+ extension->repeated_int64_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_UINT32:
+ extension->repeated_uint32_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_UINT64:
+ extension->repeated_uint64_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_FLOAT:
+ extension->repeated_float_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_DOUBLE:
+ extension->repeated_double_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_BOOL:
+ extension->repeated_bool_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_ENUM:
+ extension->repeated_enum_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_STRING:
+ extension->repeated_string_value->RemoveLast();
+ break;
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ extension->repeated_message_value->RemoveLast();
+ break;
+ }
+}
+
+void ExtensionSet::SwapElements(int number, int index1, int index2) {
+ map<int, Extension>::iterator iter = extensions_.find(number);
+ GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+
+ Extension* extension = &iter->second;
+ GOOGLE_DCHECK(extension->is_repeated);
+
+ switch(cpp_type(extension->type)) {
+ case WireFormatLite::CPPTYPE_INT32:
+ extension->repeated_int32_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_INT64:
+ extension->repeated_int64_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_UINT32:
+ extension->repeated_uint32_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_UINT64:
+ extension->repeated_uint64_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_FLOAT:
+ extension->repeated_float_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_DOUBLE:
+ extension->repeated_double_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_BOOL:
+ extension->repeated_bool_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_ENUM:
+ extension->repeated_enum_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_STRING:
+ extension->repeated_string_value->SwapElements(index1, index2);
+ break;
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ extension->repeated_message_value->SwapElements(index1, index2);
+ break;
+ }
+}
+
+// ===================================================================
+
+void ExtensionSet::Clear() {
+ for (map<int, Extension>::iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ iter->second.Clear();
+ }
+}
+
+void ExtensionSet::MergeFrom(const ExtensionSet& other) {
+ for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
+ iter != other.extensions_.end(); ++iter) {
+ const Extension& other_extension = iter->second;
+
+ if (other_extension.is_repeated) {
+ Extension* extension;
+ bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
+ &extension);
+ if (is_new) {
+ // Extension did not already exist in set.
+ extension->type = other_extension.type;
+ extension->is_repeated = true;
+ } else {
+ GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
+ GOOGLE_DCHECK(extension->is_repeated);
+ }
+
+ switch (cpp_type(other_extension.type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ if (is_new) { \
+ extension->repeated_##LOWERCASE##_value = \
+ new REPEATED_TYPE; \
+ } \
+ extension->repeated_##LOWERCASE##_value->MergeFrom( \
+ *other_extension.repeated_##LOWERCASE##_value); \
+ break;
+
+ HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
+ HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
+ HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
+ HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
+ HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
+ HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
+ HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
+ HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
+ HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ if (is_new) {
+ extension->repeated_message_value =
+ new RepeatedPtrField<MessageLite>();
+ }
+ // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
+ // it would attempt to allocate new objects.
+ RepeatedPtrField<MessageLite>* other_repeated_message =
+ other_extension.repeated_message_value;
+ for (int i = 0; i < other_repeated_message->size(); i++) {
+ const MessageLite& other_message = other_repeated_message->Get(i);
+ MessageLite* target = extension->repeated_message_value
+ ->AddFromCleared<GenericTypeHandler<MessageLite> >();
+ if (target == NULL) {
+ target = other_message.New();
+ extension->repeated_message_value->AddAllocated(target);
+ }
+ target->CheckTypeAndMergeFrom(other_message);
+ }
+ break;
+ }
+ } else {
+ if (!other_extension.is_cleared) {
+ switch (cpp_type(other_extension.type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ Set##CAMELCASE(iter->first, other_extension.type, \
+ other_extension.LOWERCASE##_value, \
+ other_extension.descriptor); \
+ break;
+
+ HANDLE_TYPE( INT32, int32, Int32);
+ HANDLE_TYPE( INT64, int64, Int64);
+ HANDLE_TYPE(UINT32, uint32, UInt32);
+ HANDLE_TYPE(UINT64, uint64, UInt64);
+ HANDLE_TYPE( FLOAT, float, Float);
+ HANDLE_TYPE(DOUBLE, double, Double);
+ HANDLE_TYPE( BOOL, bool, Bool);
+ HANDLE_TYPE( ENUM, enum, Enum);
+#undef HANDLE_TYPE
+ case WireFormatLite::CPPTYPE_STRING:
+ SetString(iter->first, other_extension.type,
+ *other_extension.string_value,
+ other_extension.descriptor);
+ break;
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ MutableMessage(iter->first, other_extension.type,
+ *other_extension.message_value,
+ other_extension.descriptor)
+ ->CheckTypeAndMergeFrom(*other_extension.message_value);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void ExtensionSet::Swap(ExtensionSet* x) {
+ extensions_.swap(x->extensions_);
+}
+
+bool ExtensionSet::IsInitialized() const {
+ // Extensions are never required. However, we need to check that all
+ // embedded messages are initialized.
+ for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ const Extension& extension = iter->second;
+ if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
+ if (extension.is_repeated) {
+ for (int i = 0; i < extension.repeated_message_value->size(); i++) {
+ if (!extension.repeated_message_value->Get(i).IsInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (!extension.is_cleared) {
+ if (!extension.message_value->IsInitialized()) return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper) {
+ int number = WireFormatLite::GetTagFieldNumber(tag);
+ WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+
+ ExtensionInfo extension;
+ bool is_unknown;
+ if (!extension_finder->Find(number, &extension)) {
+ is_unknown = true;
+ } else if (extension.is_packed) {
+ is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ } else {
+ WireFormatLite::WireType expected_wire_type =
+ WireFormatLite::WireTypeForFieldType(real_type(extension.type));
+ is_unknown = (wire_type != expected_wire_type);
+ }
+
+ if (is_unknown) {
+ field_skipper->SkipField(input, tag);
+ } else if (extension.is_packed) {
+ uint32 size;
+ if (!input->ReadVarint32(&size)) return false;
+ io::CodedInputStream::Limit limit = input->PushLimit(size);
+
+ switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ while (input->BytesUntilLimit() > 0) { \
+ CPP_LOWERCASE value; \
+ if (!WireFormatLite::ReadPrimitive< \
+ CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
+ input, &value)) return false; \
+ Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
+ true, value, extension.descriptor); \
+ } \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32);
+ HANDLE_TYPE( INT64, Int64, int64);
+ HANDLE_TYPE( UINT32, UInt32, uint32);
+ HANDLE_TYPE( UINT64, UInt64, uint64);
+ HANDLE_TYPE( SINT32, Int32, int32);
+ HANDLE_TYPE( SINT64, Int64, int64);
+ HANDLE_TYPE( FIXED32, UInt32, uint32);
+ HANDLE_TYPE( FIXED64, UInt64, uint64);
+ HANDLE_TYPE(SFIXED32, Int32, int32);
+ HANDLE_TYPE(SFIXED64, Int64, int64);
+ HANDLE_TYPE( FLOAT, Float, float);
+ HANDLE_TYPE( DOUBLE, Double, double);
+ HANDLE_TYPE( BOOL, Bool, bool);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::TYPE_ENUM:
+ while (input->BytesUntilLimit() > 0) {
+ int value;
+ if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+ input, &value)) return false;
+ if (extension.enum_validity_check.func(
+ extension.enum_validity_check.arg, value)) {
+ AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
+ extension.descriptor);
+ }
+ }
+ break;
+
+ case WireFormatLite::TYPE_STRING:
+ case WireFormatLite::TYPE_BYTES:
+ case WireFormatLite::TYPE_GROUP:
+ case WireFormatLite::TYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+ break;
+ }
+
+ input->PopLimit(limit);
+ } else {
+ switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: { \
+ CPP_LOWERCASE value; \
+ if (!WireFormatLite::ReadPrimitive< \
+ CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
+ input, &value)) return false; \
+ if (extension.is_repeated) { \
+ Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
+ false, value, extension.descriptor); \
+ } else { \
+ Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
+ extension.descriptor); \
+ } \
+ } break
+
+ HANDLE_TYPE( INT32, Int32, int32);
+ HANDLE_TYPE( INT64, Int64, int64);
+ HANDLE_TYPE( UINT32, UInt32, uint32);
+ HANDLE_TYPE( UINT64, UInt64, uint64);
+ HANDLE_TYPE( SINT32, Int32, int32);
+ HANDLE_TYPE( SINT64, Int64, int64);
+ HANDLE_TYPE( FIXED32, UInt32, uint32);
+ HANDLE_TYPE( FIXED64, UInt64, uint64);
+ HANDLE_TYPE(SFIXED32, Int32, int32);
+ HANDLE_TYPE(SFIXED64, Int64, int64);
+ HANDLE_TYPE( FLOAT, Float, float);
+ HANDLE_TYPE( DOUBLE, Double, double);
+ HANDLE_TYPE( BOOL, Bool, bool);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::TYPE_ENUM: {
+ int value;
+ if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+ input, &value)) return false;
+
+ if (!extension.enum_validity_check.func(
+ extension.enum_validity_check.arg, value)) {
+ // Invalid value. Treat as unknown.
+ field_skipper->SkipUnknownEnum(number, value);
+ } else if (extension.is_repeated) {
+ AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
+ extension.descriptor);
+ } else {
+ SetEnum(number, WireFormatLite::TYPE_ENUM, value,
+ extension.descriptor);
+ }
+ break;
+ }
+
+ case WireFormatLite::TYPE_STRING: {
+ string* value = extension.is_repeated ?
+ AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
+ MutableString(number, WireFormatLite::TYPE_STRING,
+ extension.descriptor);
+ if (!WireFormatLite::ReadString(input, value)) return false;
+ break;
+ }
+
+ case WireFormatLite::TYPE_BYTES: {
+ string* value = extension.is_repeated ?
+ AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
+ MutableString(number, WireFormatLite::TYPE_STRING,
+ extension.descriptor);
+ if (!WireFormatLite::ReadBytes(input, value)) return false;
+ break;
+ }
+
+ case WireFormatLite::TYPE_GROUP: {
+ MessageLite* value = extension.is_repeated ?
+ AddMessage(number, WireFormatLite::TYPE_GROUP,
+ *extension.message_prototype, extension.descriptor) :
+ MutableMessage(number, WireFormatLite::TYPE_GROUP,
+ *extension.message_prototype, extension.descriptor);
+ if (!WireFormatLite::ReadGroup(number, input, value)) return false;
+ break;
+ }
+
+ case WireFormatLite::TYPE_MESSAGE: {
+ MessageLite* value = extension.is_repeated ?
+ AddMessage(number, WireFormatLite::TYPE_MESSAGE,
+ *extension.message_prototype, extension.descriptor) :
+ MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
+ *extension.message_prototype, extension.descriptor);
+ if (!WireFormatLite::ReadMessage(input, value)) return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+ const MessageLite* containing_type,
+ UnknownFieldSet* unknown_fields) {
+ FieldSkipper skipper(unknown_fields);
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseField(tag, input, &finder, &skipper);
+}
+
+// Defined in extension_set_heavy.cc.
+// bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
+// const Message* containing_type,
+// UnknownFieldSet* unknown_fields)
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper) {
+ while (true) {
+ uint32 tag = input->ReadTag();
+ switch (tag) {
+ case 0:
+ return true;
+ case WireFormatLite::kMessageSetItemStartTag:
+ if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
+ return false;
+ }
+ break;
+ default:
+ if (!ParseField(tag, input, extension_finder, field_skipper)) {
+ return false;
+ }
+ break;
+ }
+ }
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+ const MessageLite* containing_type,
+ UnknownFieldSet* unknown_fields) {
+ FieldSkipper skipper(unknown_fields);
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseMessageSet(input, &finder, &skipper);
+}
+
+// Defined in extension_set_heavy.cc.
+// bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input,
+// const Message* containing_type,
+// UnknownFieldSet* unknown_fields);
+
+bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper) {
+ // TODO(kenton): It would be nice to share code between this and
+ // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
+ // differences would be hard to factor out.
+
+ // This method parses a group which should contain two fields:
+ // required int32 type_id = 2;
+ // required data message = 3;
+
+ // Once we see a type_id, we'll construct a fake tag for this extension
+ // which is the tag it would have had under the proto2 extensions wire
+ // format.
+ uint32 fake_tag = 0;
+
+ // If we see message data before the type_id, we'll append it to this so
+ // we can parse it later. This will probably never happen in practice,
+ // as no MessageSet encoder I know of writes the message before the type ID.
+ // But, it's technically valid so we should allow it.
+ // TODO(kenton): Use a Cord instead? Do I care?
+ string message_data;
+
+ while (true) {
+ uint32 tag = input->ReadTag();
+ if (tag == 0) return false;
+
+ switch (tag) {
+ case WireFormatLite::kMessageSetTypeIdTag: {
+ uint32 type_id;
+ if (!input->ReadVarint32(&type_id)) return false;
+ fake_tag = WireFormatLite::MakeTag(type_id,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+
+ if (!message_data.empty()) {
+ // We saw some message data before the type_id. Have to parse it
+ // now.
+ io::CodedInputStream sub_input(
+ reinterpret_cast<const uint8*>(message_data.data()),
+ message_data.size());
+ if (!ParseField(fake_tag, &sub_input,
+ extension_finder, field_skipper)) {
+ return false;
+ }
+ message_data.clear();
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetMessageTag: {
+ if (fake_tag == 0) {
+ // We haven't seen a type_id yet. Append this data to message_data.
+ string temp;
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (!input->ReadString(&temp, length)) return false;
+ message_data.append(temp);
+ } else {
+ // Already saw type_id, so we can parse this directly.
+ if (!ParseField(fake_tag, input,
+ extension_finder, field_skipper)) {
+ return false;
+ }
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetItemEndTag: {
+ return true;
+ }
+
+ default: {
+ if (!field_skipper->SkipField(input, tag)) return false;
+ }
+ }
+ }
+}
+
+void ExtensionSet::SerializeWithCachedSizes(
+ int start_field_number, int end_field_number,
+ io::CodedOutputStream* output) const {
+ map<int, Extension>::const_iterator iter;
+ for (iter = extensions_.lower_bound(start_field_number);
+ iter != extensions_.end() && iter->first < end_field_number;
+ ++iter) {
+ iter->second.SerializeFieldWithCachedSizes(iter->first, output);
+ }
+}
+
+void ExtensionSet::SerializeMessageSetWithCachedSizes(
+ io::CodedOutputStream* output) const {
+ map<int, Extension>::const_iterator iter;
+ for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
+ iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
+ }
+}
+
+int ExtensionSet::ByteSize() const {
+ int total_size = 0;
+
+ for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ total_size += iter->second.ByteSize(iter->first);
+ }
+
+ return total_size;
+}
+
+int ExtensionSet::MessageSetByteSize() const {
+ int total_size = 0;
+
+ for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ total_size += iter->second.MessageSetItemByteSize(iter->first);
+ }
+
+ return total_size;
+}
+
+// Defined in extension_set_heavy.cc.
+// int ExtensionSet::SpaceUsedExcludingSelf() const
+
+bool ExtensionSet::MaybeNewExtension(int number,
+ const FieldDescriptor* descriptor,
+ Extension** result) {
+ pair<map<int, Extension>::iterator, bool> insert_result =
+ extensions_.insert(make_pair(number, Extension()));
+ *result = &insert_result.first->second;
+ (*result)->descriptor = descriptor;
+ return insert_result.second;
+}
+
+// ===================================================================
+// Methods of ExtensionSet::Extension
+
+void ExtensionSet::Extension::Clear() {
+ if (is_repeated) {
+ switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ repeated_##LOWERCASE##_value->Clear(); \
+ break
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE( UINT32, uint32);
+ HANDLE_TYPE( UINT64, uint64);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( DOUBLE, double);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, enum);
+ HANDLE_TYPE( STRING, string);
+ HANDLE_TYPE(MESSAGE, message);
+#undef HANDLE_TYPE
+ }
+ } else {
+ if (!is_cleared) {
+ switch (cpp_type(type)) {
+ case WireFormatLite::CPPTYPE_STRING:
+ string_value->clear();
+ break;
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ message_value->Clear();
+ break;
+ default:
+ // No need to do anything. Get*() will return the default value
+ // as long as is_cleared is true and Set*() will overwrite the
+ // previous value.
+ break;
+ }
+
+ is_cleared = true;
+ }
+ }
+}
+
+void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
+ int number,
+ io::CodedOutputStream* output) const {
+ if (is_repeated) {
+ if (is_packed) {
+ if (cached_size == 0) return;
+
+ WireFormatLite::WriteTag(number,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(cached_size);
+
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
+ WireFormatLite::Write##CAMELCASE##NoTag( \
+ repeated_##LOWERCASE##_value->Get(i), output); \
+ } \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32);
+ HANDLE_TYPE( INT64, Int64, int64);
+ HANDLE_TYPE( UINT32, UInt32, uint32);
+ HANDLE_TYPE( UINT64, UInt64, uint64);
+ HANDLE_TYPE( SINT32, SInt32, int32);
+ HANDLE_TYPE( SINT64, SInt64, int64);
+ HANDLE_TYPE( FIXED32, Fixed32, uint32);
+ HANDLE_TYPE( FIXED64, Fixed64, uint64);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64);
+ HANDLE_TYPE( FLOAT, Float, float);
+ HANDLE_TYPE( DOUBLE, Double, double);
+ HANDLE_TYPE( BOOL, Bool, bool);
+ HANDLE_TYPE( ENUM, Enum, enum);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::TYPE_STRING:
+ case WireFormatLite::TYPE_BYTES:
+ case WireFormatLite::TYPE_GROUP:
+ case WireFormatLite::TYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+ break;
+ }
+ } else {
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
+ WireFormatLite::Write##CAMELCASE(number, \
+ repeated_##LOWERCASE##_value->Get(i), output); \
+ } \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32);
+ HANDLE_TYPE( INT64, Int64, int64);
+ HANDLE_TYPE( UINT32, UInt32, uint32);
+ HANDLE_TYPE( UINT64, UInt64, uint64);
+ HANDLE_TYPE( SINT32, SInt32, int32);
+ HANDLE_TYPE( SINT64, SInt64, int64);
+ HANDLE_TYPE( FIXED32, Fixed32, uint32);
+ HANDLE_TYPE( FIXED64, Fixed64, uint64);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64);
+ HANDLE_TYPE( FLOAT, Float, float);
+ HANDLE_TYPE( DOUBLE, Double, double);
+ HANDLE_TYPE( BOOL, Bool, bool);
+ HANDLE_TYPE( STRING, String, string);
+ HANDLE_TYPE( BYTES, Bytes, string);
+ HANDLE_TYPE( ENUM, Enum, enum);
+ HANDLE_TYPE( GROUP, Group, message);
+ HANDLE_TYPE( MESSAGE, Message, message);
+#undef HANDLE_TYPE
+ }
+ }
+ } else if (!is_cleared) {
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32_value);
+ HANDLE_TYPE( INT64, Int64, int64_value);
+ HANDLE_TYPE( UINT32, UInt32, uint32_value);
+ HANDLE_TYPE( UINT64, UInt64, uint64_value);
+ HANDLE_TYPE( SINT32, SInt32, int32_value);
+ HANDLE_TYPE( SINT64, SInt64, int64_value);
+ HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
+ HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
+ HANDLE_TYPE( FLOAT, Float, float_value);
+ HANDLE_TYPE( DOUBLE, Double, double_value);
+ HANDLE_TYPE( BOOL, Bool, bool_value);
+ HANDLE_TYPE( STRING, String, *string_value);
+ HANDLE_TYPE( BYTES, Bytes, *string_value);
+ HANDLE_TYPE( ENUM, Enum, enum_value);
+ HANDLE_TYPE( GROUP, Group, *message_value);
+ HANDLE_TYPE( MESSAGE, Message, *message_value);
+#undef HANDLE_TYPE
+ }
+ }
+}
+
+void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
+ int number,
+ io::CodedOutputStream* output) const {
+ if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+ // Not a valid MessageSet extension, but serialize it the normal way.
+ SerializeFieldWithCachedSizes(number, output);
+ return;
+ }
+
+ if (is_cleared) return;
+
+ // Start group.
+ output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
+
+ // Write type ID.
+ WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
+ number,
+ output);
+ // Write message.
+ WireFormatLite::WriteMessageMaybeToArray(
+ WireFormatLite::kMessageSetMessageNumber,
+ *message_value,
+ output);
+
+ // End group.
+ output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
+}
+
+int ExtensionSet::Extension::ByteSize(int number) const {
+ int result = 0;
+
+ if (is_repeated) {
+ if (is_packed) {
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
+ result += WireFormatLite::CAMELCASE##Size( \
+ repeated_##LOWERCASE##_value->Get(i)); \
+ } \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32);
+ HANDLE_TYPE( INT64, Int64, int64);
+ HANDLE_TYPE( UINT32, UInt32, uint32);
+ HANDLE_TYPE( UINT64, UInt64, uint64);
+ HANDLE_TYPE( SINT32, SInt32, int32);
+ HANDLE_TYPE( SINT64, SInt64, int64);
+ HANDLE_TYPE( ENUM, Enum, enum);
+#undef HANDLE_TYPE
+
+ // Stuff with fixed size.
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ result += WireFormatLite::k##CAMELCASE##Size * \
+ repeated_##LOWERCASE##_value->size(); \
+ break
+ HANDLE_TYPE( FIXED32, Fixed32, uint32);
+ HANDLE_TYPE( FIXED64, Fixed64, uint64);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64);
+ HANDLE_TYPE( FLOAT, Float, float);
+ HANDLE_TYPE( DOUBLE, Double, double);
+ HANDLE_TYPE( BOOL, Bool, bool);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::TYPE_STRING:
+ case WireFormatLite::TYPE_BYTES:
+ case WireFormatLite::TYPE_GROUP:
+ case WireFormatLite::TYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+ break;
+ }
+
+ cached_size = result;
+ if (result > 0) {
+ result += io::CodedOutputStream::VarintSize32(result);
+ result += io::CodedOutputStream::VarintSize32(
+ WireFormatLite::MakeTag(number,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
+ }
+ } else {
+ int tag_size = WireFormatLite::TagSize(number, real_type(type));
+
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ result += tag_size * repeated_##LOWERCASE##_value->size(); \
+ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
+ result += WireFormatLite::CAMELCASE##Size( \
+ repeated_##LOWERCASE##_value->Get(i)); \
+ } \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32);
+ HANDLE_TYPE( INT64, Int64, int64);
+ HANDLE_TYPE( UINT32, UInt32, uint32);
+ HANDLE_TYPE( UINT64, UInt64, uint64);
+ HANDLE_TYPE( SINT32, SInt32, int32);
+ HANDLE_TYPE( SINT64, SInt64, int64);
+ HANDLE_TYPE( STRING, String, string);
+ HANDLE_TYPE( BYTES, Bytes, string);
+ HANDLE_TYPE( ENUM, Enum, enum);
+ HANDLE_TYPE( GROUP, Group, message);
+ HANDLE_TYPE( MESSAGE, Message, message);
+#undef HANDLE_TYPE
+
+ // Stuff with fixed size.
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
+ repeated_##LOWERCASE##_value->size(); \
+ break
+ HANDLE_TYPE( FIXED32, Fixed32, uint32);
+ HANDLE_TYPE( FIXED64, Fixed64, uint64);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64);
+ HANDLE_TYPE( FLOAT, Float, float);
+ HANDLE_TYPE( DOUBLE, Double, double);
+ HANDLE_TYPE( BOOL, Bool, bool);
+#undef HANDLE_TYPE
+ }
+ }
+ } else if (!is_cleared) {
+ result += WireFormatLite::TagSize(number, real_type(type));
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32_value);
+ HANDLE_TYPE( INT64, Int64, int64_value);
+ HANDLE_TYPE( UINT32, UInt32, uint32_value);
+ HANDLE_TYPE( UINT64, UInt64, uint64_value);
+ HANDLE_TYPE( SINT32, SInt32, int32_value);
+ HANDLE_TYPE( SINT64, SInt64, int64_value);
+ HANDLE_TYPE( STRING, String, *string_value);
+ HANDLE_TYPE( BYTES, Bytes, *string_value);
+ HANDLE_TYPE( ENUM, Enum, enum_value);
+ HANDLE_TYPE( GROUP, Group, *message_value);
+ HANDLE_TYPE( MESSAGE, Message, *message_value);
+#undef HANDLE_TYPE
+
+ // Stuff with fixed size.
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
+ case WireFormatLite::TYPE_##UPPERCASE: \
+ result += WireFormatLite::k##CAMELCASE##Size; \
+ break
+ HANDLE_TYPE( FIXED32, Fixed32);
+ HANDLE_TYPE( FIXED64, Fixed64);
+ HANDLE_TYPE(SFIXED32, SFixed32);
+ HANDLE_TYPE(SFIXED64, SFixed64);
+ HANDLE_TYPE( FLOAT, Float);
+ HANDLE_TYPE( DOUBLE, Double);
+ HANDLE_TYPE( BOOL, Bool);
+#undef HANDLE_TYPE
+ }
+ }
+
+ return result;
+}
+
+int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
+ if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+ // Not a valid MessageSet extension, but compute the byte size for it the
+ // normal way.
+ return ByteSize(number);
+ }
+
+ if (is_cleared) return 0;
+
+ int our_size = WireFormatLite::kMessageSetItemTagsSize;
+
+ // type_id
+ our_size += io::CodedOutputStream::VarintSize32(number);
+
+ // message
+ int message_size = message_value->ByteSize();
+
+ our_size += io::CodedOutputStream::VarintSize32(message_size);
+ our_size += message_size;
+
+ return our_size;
+}
+
+int ExtensionSet::Extension::GetSize() const {
+ GOOGLE_DCHECK(is_repeated);
+ switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ return repeated_##LOWERCASE##_value->size()
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE( UINT32, uint32);
+ HANDLE_TYPE( UINT64, uint64);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( DOUBLE, double);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, enum);
+ HANDLE_TYPE( STRING, string);
+ HANDLE_TYPE(MESSAGE, message);
+#undef HANDLE_TYPE
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return 0;
+}
+
+void ExtensionSet::Extension::Free() {
+ if (is_repeated) {
+ switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case WireFormatLite::CPPTYPE_##UPPERCASE: \
+ delete repeated_##LOWERCASE##_value; \
+ break
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE( UINT32, uint32);
+ HANDLE_TYPE( UINT64, uint64);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( DOUBLE, double);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, enum);
+ HANDLE_TYPE( STRING, string);
+ HANDLE_TYPE(MESSAGE, message);
+#undef HANDLE_TYPE
+ }
+ } else {
+ switch (cpp_type(type)) {
+ case WireFormatLite::CPPTYPE_STRING:
+ delete string_value;
+ break;
+ case WireFormatLite::CPPTYPE_MESSAGE:
+ delete message_value;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+// Defined in extension_set_heavy.cc.
+// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/extension_set.h b/src/third_party/protobuf/src/google/protobuf/extension_set.h
new file mode 100644
index 0000000..68ce423
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/extension_set.h
@@ -0,0 +1,906 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_H__
+#define GOOGLE_PROTOBUF_EXTENSION_SET_H__
+
+#include <vector>
+#include <map>
+#include <utility>
+#include <string>
+
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+
+namespace protobuf {
+ class Descriptor; // descriptor.h
+ class FieldDescriptor; // descriptor.h
+ class DescriptorPool; // descriptor.h
+ class MessageLite; // message_lite.h
+ class Message; // message.h
+ class MessageFactory; // message.h
+ class UnknownFieldSet; // unknown_field_set.h
+ namespace io {
+ class CodedInputStream; // coded_stream.h
+ class CodedOutputStream; // coded_stream.h
+ }
+ namespace internal {
+ class FieldSkipper; // wire_format_lite.h
+ class RepeatedPtrFieldBase; // repeated_field.h
+ }
+ template <typename Element> class RepeatedField; // repeated_field.h
+ template <typename Element> class RepeatedPtrField; // repeated_field.h
+}
+
+namespace protobuf {
+namespace internal {
+
+// Used to store values of type WireFormatLite::FieldType without having to
+// #include wire_format_lite.h. Also, ensures that we use only one byte to
+// store these values, which is important to keep the layout of
+// ExtensionSet::Extension small.
+typedef uint8 FieldType;
+
+// A function which, given an integer value, returns true if the number
+// matches one of the defined values for the corresponding enum type. This
+// is used with RegisterEnumExtension, below.
+typedef bool EnumValidityFunc(int number);
+
+// Version of the above which takes an argument. This is needed to deal with
+// extensions that are not compiled in.
+typedef bool EnumValidityFuncWithArg(const void* arg, int number);
+
+// Information about a registered extension.
+struct ExtensionInfo {
+ inline ExtensionInfo() {}
+ inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed)
+ : type(type), is_repeated(is_repeated), is_packed(is_packed),
+ descriptor(NULL) {}
+
+ FieldType type;
+ bool is_repeated;
+ bool is_packed;
+
+ struct EnumValidityCheck {
+ EnumValidityFuncWithArg* func;
+ const void* arg;
+ };
+
+ union {
+ EnumValidityCheck enum_validity_check;
+ const MessageLite* message_prototype;
+ };
+
+ // The descriptor for this extension, if one exists and is known. May be
+ // NULL. Must not be NULL if the descriptor for the extension does not
+ // live in the same pool as the descriptor for the containing type.
+ const FieldDescriptor* descriptor;
+};
+
+// Abstract interface for an object which looks up extension definitions. Used
+// when parsing.
+class LIBPROTOBUF_EXPORT ExtensionFinder {
+ public:
+ virtual ~ExtensionFinder();
+
+ // Find the extension with the given containing type and number.
+ virtual bool Find(int number, ExtensionInfo* output) = 0;
+};
+
+// Implementation of ExtensionFinder which finds extensions defined in .proto
+// files which have been compiled into the binary.
+class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
+ public:
+ GeneratedExtensionFinder(const MessageLite* containing_type)
+ : containing_type_(containing_type) {}
+ virtual ~GeneratedExtensionFinder() {}
+
+ // Returns true and fills in *output if found, otherwise returns false.
+ virtual bool Find(int number, ExtensionInfo* output);
+
+ private:
+ const MessageLite* containing_type_;
+};
+
+// Note: extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
+// finding extensions from a DescriptorPool.
+
+// This is an internal helper class intended for use within the protocol buffer
+// library and generated classes. Clients should not use it directly. Instead,
+// use the generated accessors such as GetExtension() of the class being
+// extended.
+//
+// This class manages extensions for a protocol message object. The
+// message's HasExtension(), GetExtension(), MutableExtension(), and
+// ClearExtension() methods are just thin wrappers around the embedded
+// ExtensionSet. When parsing, if a tag number is encountered which is
+// inside one of the message type's extension ranges, the tag is passed
+// off to the ExtensionSet for parsing. Etc.
+class LIBPROTOBUF_EXPORT ExtensionSet {
+ public:
+ ExtensionSet();
+ ~ExtensionSet();
+
+ // These are called at startup by protocol-compiler-generated code to
+ // register known extensions. The registrations are used by ParseField()
+ // to look up extensions for parsed field numbers. Note that dynamic parsing
+ // does not use ParseField(); only protocol-compiler-generated parsing
+ // methods do.
+ static void RegisterExtension(const MessageLite* containing_type,
+ int number, FieldType type,
+ bool is_repeated, bool is_packed);
+ static void RegisterEnumExtension(const MessageLite* containing_type,
+ int number, FieldType type,
+ bool is_repeated, bool is_packed,
+ EnumValidityFunc* is_valid);
+ static void RegisterMessageExtension(const MessageLite* containing_type,
+ int number, FieldType type,
+ bool is_repeated, bool is_packed,
+ const MessageLite* prototype);
+
+ // =================================================================
+
+ // Add all fields which are currently present to the given vector. This
+ // is useful to implement Reflection::ListFields().
+ void AppendToList(const Descriptor* containing_type,
+ const DescriptorPool* pool,
+ vector<const FieldDescriptor*>* output) const;
+
+ // =================================================================
+ // Accessors
+ //
+ // Generated message classes include type-safe templated wrappers around
+ // these methods. Generally you should use those rather than call these
+ // directly, unless you are doing low-level memory management.
+ //
+ // When calling any of these accessors, the extension number requested
+ // MUST exist in the DescriptorPool provided to the constructor. Otheriwse,
+ // the method will fail an assert. Normally, though, you would not call
+ // these directly; you would either call the generated accessors of your
+ // message class (e.g. GetExtension()) or you would call the accessors
+ // of the reflection interface. In both cases, it is impossible to
+ // trigger this assert failure: the generated accessors only accept
+ // linked-in extension types as parameters, while the Reflection interface
+ // requires you to provide the FieldDescriptor describing the extension.
+ //
+ // When calling any of these accessors, a protocol-compiler-generated
+ // implementation of the extension corresponding to the number MUST
+ // be linked in, and the FieldDescriptor used to refer to it MUST be
+ // the one generated by that linked-in code. Otherwise, the method will
+ // die on an assert failure. The message objects returned by the message
+ // accessors are guaranteed to be of the correct linked-in type.
+ //
+ // These methods pretty much match Reflection except that:
+ // - They're not virtual.
+ // - They identify fields by number rather than FieldDescriptors.
+ // - They identify enum values using integers rather than descriptors.
+ // - Strings provide Mutable() in addition to Set() accessors.
+
+ bool Has(int number) const;
+ int ExtensionSize(int number) const; // Size of a repeated extension.
+ FieldType ExtensionType(int number) const;
+ void ClearExtension(int number);
+
+ // singular fields -------------------------------------------------
+
+ int32 GetInt32 (int number, int32 default_value) const;
+ int64 GetInt64 (int number, int64 default_value) const;
+ uint32 GetUInt32(int number, uint32 default_value) const;
+ uint64 GetUInt64(int number, uint64 default_value) const;
+ float GetFloat (int number, float default_value) const;
+ double GetDouble(int number, double default_value) const;
+ bool GetBool (int number, bool default_value) const;
+ int GetEnum (int number, int default_value) const;
+ const string & GetString (int number, const string& default_value) const;
+ const MessageLite& GetMessage(int number,
+ const MessageLite& default_value) const;
+ const MessageLite& GetMessage(int number, const Descriptor* message_type,
+ MessageFactory* factory) const;
+
+ // |descriptor| may be NULL so long as it is known that the descriptor for
+ // the extension lives in the same pool as the descriptor for the containing
+ // type.
+#define desc const FieldDescriptor* descriptor // avoid line wrapping
+ void SetInt32 (int number, FieldType type, int32 value, desc);
+ void SetInt64 (int number, FieldType type, int64 value, desc);
+ void SetUInt32(int number, FieldType type, uint32 value, desc);
+ void SetUInt64(int number, FieldType type, uint64 value, desc);
+ void SetFloat (int number, FieldType type, float value, desc);
+ void SetDouble(int number, FieldType type, double value, desc);
+ void SetBool (int number, FieldType type, bool value, desc);
+ void SetEnum (int number, FieldType type, int value, desc);
+ void SetString(int number, FieldType type, const string& value, desc);
+ string * MutableString (int number, FieldType type, desc);
+ MessageLite* MutableMessage(int number, FieldType type,
+ const MessageLite& prototype, desc);
+ MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
+ MessageFactory* factory);
+#undef desc
+
+ // repeated fields -------------------------------------------------
+
+ int32 GetRepeatedInt32 (int number, int index) const;
+ int64 GetRepeatedInt64 (int number, int index) const;
+ uint32 GetRepeatedUInt32(int number, int index) const;
+ uint64 GetRepeatedUInt64(int number, int index) const;
+ float GetRepeatedFloat (int number, int index) const;
+ double GetRepeatedDouble(int number, int index) const;
+ bool GetRepeatedBool (int number, int index) const;
+ int GetRepeatedEnum (int number, int index) const;
+ const string & GetRepeatedString (int number, int index) const;
+ const MessageLite& GetRepeatedMessage(int number, int index) const;
+
+ void SetRepeatedInt32 (int number, int index, int32 value);
+ void SetRepeatedInt64 (int number, int index, int64 value);
+ void SetRepeatedUInt32(int number, int index, uint32 value);
+ void SetRepeatedUInt64(int number, int index, uint64 value);
+ void SetRepeatedFloat (int number, int index, float value);
+ void SetRepeatedDouble(int number, int index, double value);
+ void SetRepeatedBool (int number, int index, bool value);
+ void SetRepeatedEnum (int number, int index, int value);
+ void SetRepeatedString(int number, int index, const string& value);
+ string * MutableRepeatedString (int number, int index);
+ MessageLite* MutableRepeatedMessage(int number, int index);
+
+#define desc const FieldDescriptor* descriptor // avoid line wrapping
+ void AddInt32 (int number, FieldType type, bool packed, int32 value, desc);
+ void AddInt64 (int number, FieldType type, bool packed, int64 value, desc);
+ void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
+ void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
+ void AddFloat (int number, FieldType type, bool packed, float value, desc);
+ void AddDouble(int number, FieldType type, bool packed, double value, desc);
+ void AddBool (int number, FieldType type, bool packed, bool value, desc);
+ void AddEnum (int number, FieldType type, bool packed, int value, desc);
+ void AddString(int number, FieldType type, const string& value, desc);
+ string * AddString (int number, FieldType type, desc);
+ MessageLite* AddMessage(int number, FieldType type,
+ const MessageLite& prototype, desc);
+ MessageLite* AddMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory);
+#undef desc
+
+ void RemoveLast(int number);
+ void SwapElements(int number, int index1, int index2);
+
+ // -----------------------------------------------------------------
+ // TODO(kenton): Hardcore memory management accessors
+
+ // =================================================================
+ // convenience methods for implementing methods of Message
+ //
+ // These could all be implemented in terms of the other methods of this
+ // class, but providing them here helps keep the generated code size down.
+
+ void Clear();
+ void MergeFrom(const ExtensionSet& other);
+ void Swap(ExtensionSet* other);
+ bool IsInitialized() const;
+
+ // Parses a single extension from the input. The input should start out
+ // positioned immediately after the tag. |containing_type| is the default
+ // instance for the containing message; it is used only to look up the
+ // extension by number. See RegisterExtension(), above. Unlike the other
+ // methods of ExtensionSet, this only works for generated message types --
+ // it looks up extensions registered using RegisterExtension().
+ bool ParseField(uint32 tag, io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper);
+
+ // Specific versions for lite or full messages (constructs the appropriate
+ // FieldSkipper automatically).
+ bool ParseField(uint32 tag, io::CodedInputStream* input,
+ const MessageLite* containing_type,
+ UnknownFieldSet* unknown_fields);
+ bool ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
+ const Message* containing_type,
+ UnknownFieldSet* unknown_fields);
+
+ // Parse an entire message in MessageSet format. Such messages have no
+ // fields, only extensions.
+ bool ParseMessageSet(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper);
+
+ // Specific versions for lite or full messages (constructs the appropriate
+ // FieldSkipper automatically).
+ bool ParseMessageSet(io::CodedInputStream* input,
+ const MessageLite* containing_type,
+ UnknownFieldSet* unknown_fields);
+ bool ParseMessageSetHeavy(io::CodedInputStream* input,
+ const Message* containing_type,
+ UnknownFieldSet* unknown_fields);
+
+ // Write all extension fields with field numbers in the range
+ // [start_field_number, end_field_number)
+ // to the output stream, using the cached sizes computed when ByteSize() was
+ // last called. Note that the range bounds are inclusive-exclusive.
+ void SerializeWithCachedSizes(int start_field_number,
+ int end_field_number,
+ io::CodedOutputStream* output) const;
+
+ // Same as SerializeWithCachedSizes, but without any bounds checking.
+ // The caller must ensure that target has sufficient capacity for the
+ // serialized extensions.
+ //
+ // Returns a pointer past the last written byte.
+ uint8* SerializeWithCachedSizesToArray(int start_field_number,
+ int end_field_number,
+ uint8* target) const;
+
+ // Like above but serializes in MessageSet format.
+ void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const;
+ uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const;
+
+ // Returns the total serialized size of all the extensions.
+ int ByteSize() const;
+
+ // Like ByteSize() but uses MessageSet format.
+ int MessageSetByteSize() const;
+
+ // Returns (an estimate of) the total number of bytes used for storing the
+ // extensions in memory, excluding sizeof(*this). If the ExtensionSet is
+ // for a lite message (and thus possibly contains lite messages), the results
+ // are undefined (might work, might crash, might corrupt data, might not even
+ // be linked in). It's up to the protocol compiler to avoid calling this on
+ // such ExtensionSets (easy enough since lite messages don't implement
+ // SpaceUsed()).
+ int SpaceUsedExcludingSelf() const;
+
+ private:
+
+ struct Extension {
+ union {
+ int32 int32_value;
+ int64 int64_value;
+ uint32 uint32_value;
+ uint64 uint64_value;
+ float float_value;
+ double double_value;
+ bool bool_value;
+ int enum_value;
+ string* string_value;
+ MessageLite* message_value;
+
+ RepeatedField <int32 >* repeated_int32_value;
+ RepeatedField <int64 >* repeated_int64_value;
+ RepeatedField <uint32 >* repeated_uint32_value;
+ RepeatedField <uint64 >* repeated_uint64_value;
+ RepeatedField <float >* repeated_float_value;
+ RepeatedField <double >* repeated_double_value;
+ RepeatedField <bool >* repeated_bool_value;
+ RepeatedField <int >* repeated_enum_value;
+ RepeatedPtrField<string >* repeated_string_value;
+ RepeatedPtrField<MessageLite>* repeated_message_value;
+ };
+
+ FieldType type;
+ bool is_repeated;
+
+ // For singular types, indicates if the extension is "cleared". This
+ // happens when an extension is set and then later cleared by the caller.
+ // We want to keep the Extension object around for reuse, so instead of
+ // removing it from the map, we just set is_cleared = true. This has no
+ // meaning for repeated types; for those, the size of the RepeatedField
+ // simply becomes zero when cleared.
+ bool is_cleared;
+
+ // For repeated types, this indicates if the [packed=true] option is set.
+ bool is_packed;
+
+ // The descriptor for this extension, if one exists and is known. May be
+ // NULL. Must not be NULL if the descriptor for the extension does not
+ // live in the same pool as the descriptor for the containing type.
+ const FieldDescriptor* descriptor;
+
+ // For packed fields, the size of the packed data is recorded here when
+ // ByteSize() is called then used during serialization.
+ // TODO(kenton): Use atomic<int> when C++ supports it.
+ mutable int cached_size;
+
+ // Some helper methods for operations on a single Extension.
+ void SerializeFieldWithCachedSizes(
+ int number,
+ io::CodedOutputStream* output) const;
+ uint8* SerializeFieldWithCachedSizesToArray(
+ int number,
+ uint8* target) const;
+ void SerializeMessageSetItemWithCachedSizes(
+ int number,
+ io::CodedOutputStream* output) const;
+ uint8* SerializeMessageSetItemWithCachedSizesToArray(
+ int number,
+ uint8* target) const;
+ int ByteSize(int number) const;
+ int MessageSetItemByteSize(int number) const;
+ void Clear();
+ int GetSize() const;
+ void Free();
+ int SpaceUsedExcludingSelf() const;
+ };
+
+
+ // Gets the extension with the given number, creating it if it does not
+ // already exist. Returns true if the extension did not already exist.
+ bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
+ Extension** result);
+
+ // Parse a single MessageSet item -- called just after the item group start
+ // tag has been read.
+ bool ParseMessageSetItem(io::CodedInputStream* input,
+ ExtensionFinder* extension_finder,
+ FieldSkipper* field_skipper);
+
+
+ // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This
+ // friendship should automatically extend to ExtensionSet::Extension, but
+ // unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
+ // correctly. So, we must provide helpers for calling methods of that
+ // class.
+
+ // Defined in extension_set_heavy.cc.
+ static inline int RepeatedMessage_SpaceUsedExcludingSelf(
+ RepeatedPtrFieldBase* field);
+
+ // The Extension struct is small enough to be passed by value, so we use it
+ // directly as the value type in the map rather than use pointers. We use
+ // a map rather than hash_map here because we expect most ExtensionSets will
+ // only contain a small number of extensions whereas hash_map is optimized
+ // for 100 elements or more. Also, we want AppendToList() to order fields
+ // by field number.
+ map<int, Extension> extensions_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
+};
+
+// These are just for convenience...
+inline void ExtensionSet::SetString(int number, FieldType type,
+ const string& value,
+ const FieldDescriptor* descriptor) {
+ MutableString(number, type, descriptor)->assign(value);
+}
+inline void ExtensionSet::SetRepeatedString(int number, int index,
+ const string& value) {
+ MutableRepeatedString(number, index)->assign(value);
+}
+inline void ExtensionSet::AddString(int number, FieldType type,
+ const string& value,
+ const FieldDescriptor* descriptor) {
+ AddString(number, type, descriptor)->assign(value);
+}
+
+// ===================================================================
+// Glue for generated extension accessors
+
+// -------------------------------------------------------------------
+// Template magic
+
+// First we have a set of classes representing "type traits" for different
+// field types. A type traits class knows how to implement basic accessors
+// for extensions of a particular type given an ExtensionSet. The signature
+// for a type traits class looks like this:
+//
+// class TypeTraits {
+// public:
+// typedef ? ConstType;
+// typedef ? MutableType;
+//
+// static inline ConstType Get(int number, const ExtensionSet& set);
+// static inline void Set(int number, ConstType value, ExtensionSet* set);
+// static inline MutableType Mutable(int number, ExtensionSet* set);
+//
+// // Variants for repeated fields.
+// static inline ConstType Get(int number, const ExtensionSet& set,
+// int index);
+// static inline void Set(int number, int index,
+// ConstType value, ExtensionSet* set);
+// static inline MutableType Mutable(int number, int index,
+// ExtensionSet* set);
+// static inline void Add(int number, ConstType value, ExtensionSet* set);
+// static inline MutableType Add(int number, ExtensionSet* set);
+// };
+//
+// Not all of these methods make sense for all field types. For example, the
+// "Mutable" methods only make sense for strings and messages, and the
+// repeated methods only make sense for repeated types. So, each type
+// traits class implements only the set of methods from this signature that it
+// actually supports. This will cause a compiler error if the user tries to
+// access an extension using a method that doesn't make sense for its type.
+// For example, if "foo" is an extension of type "optional int32", then if you
+// try to write code like:
+// my_message.MutableExtension(foo)
+// you will get a compile error because PrimitiveTypeTraits<int32> does not
+// have a "Mutable()" method.
+
+// -------------------------------------------------------------------
+// PrimitiveTypeTraits
+
+// Since the ExtensionSet has different methods for each primitive type,
+// we must explicitly define the methods of the type traits class for each
+// known type.
+template <typename Type>
+class PrimitiveTypeTraits {
+ public:
+ typedef Type ConstType;
+
+ static inline ConstType Get(int number, const ExtensionSet& set,
+ ConstType default_value);
+ static inline void Set(int number, FieldType field_type,
+ ConstType value, ExtensionSet* set);
+};
+
+template <typename Type>
+class RepeatedPrimitiveTypeTraits {
+ public:
+ typedef Type ConstType;
+
+ static inline Type Get(int number, const ExtensionSet& set, int index);
+ static inline void Set(int number, int index, Type value, ExtensionSet* set);
+ static inline void Add(int number, FieldType field_type,
+ bool is_packed, Type value, ExtensionSet* set);
+};
+
+#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \
+template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get( \
+ int number, const ExtensionSet& set, TYPE default_value) { \
+ return set.Get##METHOD(number, default_value); \
+} \
+template<> inline void PrimitiveTypeTraits<TYPE>::Set( \
+ int number, FieldType field_type, TYPE value, ExtensionSet* set) { \
+ set->Set##METHOD(number, field_type, value, NULL); \
+} \
+ \
+template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get( \
+ int number, const ExtensionSet& set, int index) { \
+ return set.GetRepeated##METHOD(number, index); \
+} \
+template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \
+ int number, int index, TYPE value, ExtensionSet* set) { \
+ set->SetRepeated##METHOD(number, index, value); \
+} \
+template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \
+ int number, FieldType field_type, bool is_packed, \
+ TYPE value, ExtensionSet* set) { \
+ set->Add##METHOD(number, field_type, is_packed, value, NULL); \
+}
+
+PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE( int64, Int64)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint32, UInt32)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(uint64, UInt64)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE( float, Float)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE(double, Double)
+PROTOBUF_DEFINE_PRIMITIVE_TYPE( bool, Bool)
+
+#undef PROTOBUF_DEFINE_PRIMITIVE_TYPE
+
+// -------------------------------------------------------------------
+// StringTypeTraits
+
+// Strings support both Set() and Mutable().
+class LIBPROTOBUF_EXPORT StringTypeTraits {
+ public:
+ typedef const string& ConstType;
+ typedef string* MutableType;
+
+ static inline const string& Get(int number, const ExtensionSet& set,
+ ConstType default_value) {
+ return set.GetString(number, default_value);
+ }
+ static inline void Set(int number, FieldType field_type,
+ const string& value, ExtensionSet* set) {
+ set->SetString(number, field_type, value, NULL);
+ }
+ static inline string* Mutable(int number, FieldType field_type,
+ ExtensionSet* set) {
+ return set->MutableString(number, field_type, NULL);
+ }
+};
+
+class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
+ public:
+ typedef const string& ConstType;
+ typedef string* MutableType;
+
+ static inline const string& Get(int number, const ExtensionSet& set,
+ int index) {
+ return set.GetRepeatedString(number, index);
+ }
+ static inline void Set(int number, int index,
+ const string& value, ExtensionSet* set) {
+ set->SetRepeatedString(number, index, value);
+ }
+ static inline string* Mutable(int number, int index, ExtensionSet* set) {
+ return set->MutableRepeatedString(number, index);
+ }
+ static inline void Add(int number, FieldType field_type,
+ bool /*is_packed*/, const string& value,
+ ExtensionSet* set) {
+ set->AddString(number, field_type, value, NULL);
+ }
+ static inline string* Add(int number, FieldType field_type,
+ ExtensionSet* set) {
+ return set->AddString(number, field_type, NULL);
+ }
+};
+
+// -------------------------------------------------------------------
+// EnumTypeTraits
+
+// ExtensionSet represents enums using integers internally, so we have to
+// static_cast around.
+template <typename Type, bool IsValid(int)>
+class EnumTypeTraits {
+ public:
+ typedef Type ConstType;
+
+ static inline ConstType Get(int number, const ExtensionSet& set,
+ ConstType default_value) {
+ return static_cast<Type>(set.GetEnum(number, default_value));
+ }
+ static inline void Set(int number, FieldType field_type,
+ ConstType value, ExtensionSet* set) {
+ GOOGLE_DCHECK(IsValid(value));
+ set->SetEnum(number, field_type, value, NULL);
+ }
+};
+
+template <typename Type, bool IsValid(int)>
+class RepeatedEnumTypeTraits {
+ public:
+ typedef Type ConstType;
+
+ static inline ConstType Get(int number, const ExtensionSet& set, int index) {
+ return static_cast<Type>(set.GetRepeatedEnum(number, index));
+ }
+ static inline void Set(int number, int index,
+ ConstType value, ExtensionSet* set) {
+ GOOGLE_DCHECK(IsValid(value));
+ set->SetRepeatedEnum(number, index, value);
+ }
+ static inline void Add(int number, FieldType field_type,
+ bool is_packed, ConstType value, ExtensionSet* set) {
+ GOOGLE_DCHECK(IsValid(value));
+ set->AddEnum(number, field_type, is_packed, value, NULL);
+ }
+};
+
+// -------------------------------------------------------------------
+// MessageTypeTraits
+
+// ExtensionSet guarantees that when manipulating extensions with message
+// types, the implementation used will be the compiled-in class representing
+// that type. So, we can static_cast down to the exact type we expect.
+template <typename Type>
+class MessageTypeTraits {
+ public:
+ typedef const Type& ConstType;
+ typedef Type* MutableType;
+
+ static inline ConstType Get(int number, const ExtensionSet& set,
+ ConstType default_value) {
+ return static_cast<const Type&>(
+ set.GetMessage(number, default_value));
+ }
+ static inline MutableType Mutable(int number, FieldType field_type,
+ ExtensionSet* set) {
+ return static_cast<Type*>(
+ set->MutableMessage(number, field_type, Type::default_instance(), NULL));
+ }
+};
+
+template <typename Type>
+class RepeatedMessageTypeTraits {
+ public:
+ typedef const Type& ConstType;
+ typedef Type* MutableType;
+
+ static inline ConstType Get(int number, const ExtensionSet& set, int index) {
+ return static_cast<const Type&>(set.GetRepeatedMessage(number, index));
+ }
+ static inline MutableType Mutable(int number, int index, ExtensionSet* set) {
+ return static_cast<Type*>(set->MutableRepeatedMessage(number, index));
+ }
+ static inline MutableType Add(int number, FieldType field_type,
+ ExtensionSet* set) {
+ return static_cast<Type*>(
+ set->AddMessage(number, field_type, Type::default_instance(), NULL));
+ }
+};
+
+// -------------------------------------------------------------------
+// ExtensionIdentifier
+
+// This is the type of actual extension objects. E.g. if you have:
+// extends Foo with optional int32 bar = 1234;
+// then "bar" will be defined in C++ as:
+// ExtensionIdentifier<Foo, PrimitiveTypeTraits<int32>, 1, false> bar(1234);
+//
+// Note that we could, in theory, supply the field number as a template
+// parameter, and thus make an instance of ExtensionIdentifier have no
+// actual contents. However, if we did that, then using at extension
+// identifier would not necessarily cause the compiler to output any sort
+// of reference to any simple defined in the extension's .pb.o file. Some
+// linkers will actually drop object files that are not explicitly referenced,
+// but that would be bad because it would cause this extension to not be
+// registered at static initialization, and therefore using it would crash.
+
+template <typename ExtendeeType, typename TypeTraitsType,
+ FieldType field_type, bool is_packed>
+class ExtensionIdentifier {
+ public:
+ typedef TypeTraitsType TypeTraits;
+ typedef ExtendeeType Extendee;
+
+ ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value)
+ : number_(number), default_value_(default_value) {}
+ inline int number() const { return number_; }
+ typename TypeTraits::ConstType default_value() const {
+ return default_value_;
+ }
+
+ private:
+ const int number_;
+ typename TypeTraits::ConstType default_value_;
+};
+
+// -------------------------------------------------------------------
+// Generated accessors
+
+// This macro should be expanded in the context of a generated type which
+// has extensions.
+//
+// We use "_proto_TypeTraits" as a type name below because "TypeTraits"
+// causes problems if the class has a nested message or enum type with that
+// name and "_TypeTraits" is technically reserved for the C++ library since
+// it starts with an underscore followed by a capital letter.
+#define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME) \
+ /* Has, Size, Clear */ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline bool HasExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
+ return _extensions_.Has(id.number()); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline void ClearExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
+ _extensions_.ClearExtension(id.number()); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline int ExtensionSize( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
+ return _extensions_.ExtensionSize(id.number()); \
+ } \
+ \
+ /* Singular accessors */ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline typename _proto_TypeTraits::ConstType GetExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) const { \
+ return _proto_TypeTraits::Get(id.number(), _extensions_, \
+ id.default_value()); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline typename _proto_TypeTraits::MutableType MutableExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
+ return _proto_TypeTraits::Mutable(id.number(), field_type, &_extensions_);\
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline void SetExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
+ typename _proto_TypeTraits::ConstType value) { \
+ _proto_TypeTraits::Set(id.number(), field_type, value, &_extensions_); \
+ } \
+ \
+ /* Repeated accessors */ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline typename _proto_TypeTraits::ConstType GetExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
+ int index) const { \
+ return _proto_TypeTraits::Get(id.number(), _extensions_, index); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline typename _proto_TypeTraits::MutableType MutableExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
+ int index) { \
+ return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline void SetExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
+ int index, typename _proto_TypeTraits::ConstType value) { \
+ _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline typename _proto_TypeTraits::MutableType AddExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id) { \
+ return _proto_TypeTraits::Add(id.number(), field_type, &_extensions_); \
+ } \
+ \
+ template <typename _proto_TypeTraits, \
+ ::google::protobuf::internal::FieldType field_type, \
+ bool is_packed> \
+ inline void AddExtension( \
+ const ::google::protobuf::internal::ExtensionIdentifier< \
+ CLASSNAME, _proto_TypeTraits, field_type, is_packed>& id, \
+ typename _proto_TypeTraits::ConstType value) { \
+ _proto_TypeTraits::Add(id.number(), field_type, is_packed, \
+ value, &_extensions_); \
+ }
+
+} // namespace internal
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_EXTENSION_SET_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/extension_set_heavy.cc b/src/third_party/protobuf/src/google/protobuf/extension_set_heavy.cc
new file mode 100644
index 0000000..e00fd4d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/extension_set_heavy.cc
@@ -0,0 +1,457 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Contains methods defined in extension_set.h which cannot be part of the
+// lite library because they use descriptors or reflection.
+
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Implementation of ExtensionFinder which finds extensions in a given
+// DescriptorPool, using the given MessageFactory to construct sub-objects.
+// This class is implemented in extension_set_heavy.cc.
+class DescriptorPoolExtensionFinder : public ExtensionFinder {
+ public:
+ DescriptorPoolExtensionFinder(const DescriptorPool* pool,
+ MessageFactory* factory,
+ const Descriptor* containing_type)
+ : pool_(pool), factory_(factory), containing_type_(containing_type) {}
+ virtual ~DescriptorPoolExtensionFinder() {}
+
+ virtual bool Find(int number, ExtensionInfo* output);
+
+ private:
+ const DescriptorPool* pool_;
+ MessageFactory* factory_;
+ const Descriptor* containing_type_;
+};
+
+void ExtensionSet::AppendToList(const Descriptor* containing_type,
+ const DescriptorPool* pool,
+ vector<const FieldDescriptor*>* output) const {
+ for (map<int, Extension>::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ bool has = false;
+ if (iter->second.is_repeated) {
+ has = iter->second.GetSize() > 0;
+ } else {
+ has = !iter->second.is_cleared;
+ }
+
+ if (has) {
+ // TODO(kenton): Looking up each field by number is somewhat unfortunate.
+ // Is there a better way? The problem is that descriptors are lazily-
+ // initialized, so they might not even be constructed until
+ // AppendToList() is called.
+
+ if (iter->second.descriptor == NULL) {
+ output->push_back(pool->FindExtensionByNumber(
+ containing_type, iter->first));
+ } else {
+ output->push_back(iter->second.descriptor);
+ }
+ }
+ }
+}
+
+inline FieldDescriptor::Type real_type(FieldType type) {
+ GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
+ return static_cast<FieldDescriptor::Type>(type);
+}
+
+inline FieldDescriptor::CppType cpp_type(FieldType type) {
+ return FieldDescriptor::TypeToCppType(
+ static_cast<FieldDescriptor::Type>(type));
+}
+
+#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
+ GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED \
+ : FieldDescriptor::LABEL_OPTIONAL, \
+ FieldDescriptor::LABEL_##LABEL); \
+ GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
+
+const MessageLite& ExtensionSet::GetMessage(int number,
+ const Descriptor* message_type,
+ MessageFactory* factory) const {
+ map<int, Extension>::const_iterator iter = extensions_.find(number);
+ if (iter == extensions_.end() || iter->second.is_cleared) {
+ // Not present. Return the default value.
+ return *factory->GetPrototype(message_type);
+ } else {
+ GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
+ return *iter->second.message_value;
+ }
+}
+
+MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory) {
+ Extension* extension;
+ if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
+ extension->type = descriptor->type();
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
+ extension->is_repeated = false;
+ extension->is_packed = false;
+ const MessageLite* prototype =
+ factory->GetPrototype(descriptor->message_type());
+ GOOGLE_CHECK(prototype != NULL);
+ extension->message_value = prototype->New();
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+ }
+ extension->is_cleared = false;
+ return extension->message_value;
+}
+
+MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory) {
+ Extension* extension;
+ if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
+ extension->type = descriptor->type();
+ GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
+ extension->is_repeated = true;
+ extension->repeated_message_value =
+ new RepeatedPtrField<MessageLite>();
+ } else {
+ GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
+ }
+
+ // RepeatedPtrField<Message> does not know how to Add() since it cannot
+ // allocate an abstract object, so we have to be tricky.
+ MessageLite* result = extension->repeated_message_value
+ ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
+ if (result == NULL) {
+ const MessageLite* prototype;
+ if (extension->repeated_message_value->size() == 0) {
+ prototype = factory->GetPrototype(descriptor->message_type());
+ GOOGLE_CHECK(prototype != NULL);
+ } else {
+ prototype = &extension->repeated_message_value->Get(0);
+ }
+ result = prototype->New();
+ extension->repeated_message_value->AddAllocated(result);
+ }
+ return result;
+}
+
+static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
+ return reinterpret_cast<const EnumDescriptor*>(arg)
+ ->FindValueByNumber(number) != NULL;
+}
+
+bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
+ const FieldDescriptor* extension =
+ pool_->FindExtensionByNumber(containing_type_, number);
+ if (extension == NULL) {
+ return false;
+ } else {
+ output->type = extension->type();
+ output->is_repeated = extension->is_repeated();
+ output->is_packed = extension->options().packed();
+ output->descriptor = extension;
+ if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ output->message_prototype =
+ factory_->GetPrototype(extension->message_type());
+ GOOGLE_CHECK(output->message_prototype != NULL)
+ << "Extension factory's GetPrototype() returned NULL for extension: "
+ << extension->full_name();
+ } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ output->enum_validity_check.func = ValidateEnumUsingDescriptor;
+ output->enum_validity_check.arg = extension->enum_type();
+ }
+
+ return true;
+ }
+}
+
+bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
+ const Message* containing_type,
+ UnknownFieldSet* unknown_fields) {
+ FieldSkipper skipper(unknown_fields);
+ if (input->GetExtensionPool() == NULL) {
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseField(tag, input, &finder, &skipper);
+ } else {
+ DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
+ input->GetExtensionFactory(),
+ containing_type->GetDescriptor());
+ return ParseField(tag, input, &finder, &skipper);
+ }
+}
+
+bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input,
+ const Message* containing_type,
+ UnknownFieldSet* unknown_fields) {
+ FieldSkipper skipper(unknown_fields);
+ if (input->GetExtensionPool() == NULL) {
+ GeneratedExtensionFinder finder(containing_type);
+ return ParseMessageSet(input, &finder, &skipper);
+ } else {
+ DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
+ input->GetExtensionFactory(),
+ containing_type->GetDescriptor());
+ return ParseMessageSet(input, &finder, &skipper);
+ }
+}
+
+int ExtensionSet::SpaceUsedExcludingSelf() const {
+ int total_size =
+ extensions_.size() * sizeof(map<int, Extension>::value_type);
+ for (map<int, Extension>::const_iterator iter = extensions_.begin(),
+ end = extensions_.end();
+ iter != end;
+ ++iter) {
+ total_size += iter->second.SpaceUsedExcludingSelf();
+ }
+ return total_size;
+}
+
+inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
+ RepeatedPtrFieldBase* field) {
+ return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
+}
+
+int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
+ int total_size = 0;
+ if (is_repeated) {
+ switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE: \
+ total_size += sizeof(*repeated_##LOWERCASE##_value) + \
+ repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
+ break
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE( UINT32, uint32);
+ HANDLE_TYPE( UINT64, uint64);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( DOUBLE, double);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, enum);
+ HANDLE_TYPE( STRING, string);
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
+ // but MessageLite has no SpaceUsed(), so we must directly call
+ // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
+ // handler.
+ total_size += sizeof(*repeated_message_value) +
+ RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
+ break;
+ }
+ } else {
+ switch (cpp_type(type)) {
+ case FieldDescriptor::CPPTYPE_STRING:
+ total_size += sizeof(*string_value) +
+ StringSpaceUsedExcludingSelf(*string_value);
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ total_size += down_cast<Message*>(message_value)->SpaceUsed();
+ break;
+ default:
+ // No extra storage costs for primitive types.
+ break;
+ }
+ }
+ return total_size;
+}
+
+// The Serialize*ToArray methods are only needed in the heavy library, as
+// the lite library only generates SerializeWithCachedSizes.
+uint8* ExtensionSet::SerializeWithCachedSizesToArray(
+ int start_field_number, int end_field_number,
+ uint8* target) const {
+ map<int, Extension>::const_iterator iter;
+ for (iter = extensions_.lower_bound(start_field_number);
+ iter != extensions_.end() && iter->first < end_field_number;
+ ++iter) {
+ target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first,
+ target);
+ }
+ return target;
+}
+
+uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
+ uint8* target) const {
+ map<int, Extension>::const_iterator iter;
+ for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
+ target = iter->second.SerializeMessageSetItemWithCachedSizesToArray(
+ iter->first, target);
+ }
+ return target;
+}
+
+uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
+ int number, uint8* target) const {
+ if (is_repeated) {
+ if (is_packed) {
+ if (cached_size == 0) return target;
+
+ target = WireFormatLite::WriteTagToArray(number,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
+ target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
+
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case FieldDescriptor::TYPE_##UPPERCASE: \
+ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
+ target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \
+ repeated_##LOWERCASE##_value->Get(i), target); \
+ } \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32);
+ HANDLE_TYPE( INT64, Int64, int64);
+ HANDLE_TYPE( UINT32, UInt32, uint32);
+ HANDLE_TYPE( UINT64, UInt64, uint64);
+ HANDLE_TYPE( SINT32, SInt32, int32);
+ HANDLE_TYPE( SINT64, SInt64, int64);
+ HANDLE_TYPE( FIXED32, Fixed32, uint32);
+ HANDLE_TYPE( FIXED64, Fixed64, uint64);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64);
+ HANDLE_TYPE( FLOAT, Float, float);
+ HANDLE_TYPE( DOUBLE, Double, double);
+ HANDLE_TYPE( BOOL, Bool, bool);
+ HANDLE_TYPE( ENUM, Enum, enum);
+#undef HANDLE_TYPE
+
+ case WireFormatLite::TYPE_STRING:
+ case WireFormatLite::TYPE_BYTES:
+ case WireFormatLite::TYPE_GROUP:
+ case WireFormatLite::TYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+ break;
+ }
+ } else {
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
+ case FieldDescriptor::TYPE_##UPPERCASE: \
+ for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
+ target = WireFormatLite::Write##CAMELCASE##ToArray(number, \
+ repeated_##LOWERCASE##_value->Get(i), target); \
+ } \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32);
+ HANDLE_TYPE( INT64, Int64, int64);
+ HANDLE_TYPE( UINT32, UInt32, uint32);
+ HANDLE_TYPE( UINT64, UInt64, uint64);
+ HANDLE_TYPE( SINT32, SInt32, int32);
+ HANDLE_TYPE( SINT64, SInt64, int64);
+ HANDLE_TYPE( FIXED32, Fixed32, uint32);
+ HANDLE_TYPE( FIXED64, Fixed64, uint64);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64);
+ HANDLE_TYPE( FLOAT, Float, float);
+ HANDLE_TYPE( DOUBLE, Double, double);
+ HANDLE_TYPE( BOOL, Bool, bool);
+ HANDLE_TYPE( STRING, String, string);
+ HANDLE_TYPE( BYTES, Bytes, string);
+ HANDLE_TYPE( ENUM, Enum, enum);
+ HANDLE_TYPE( GROUP, Group, message);
+ HANDLE_TYPE( MESSAGE, Message, message);
+#undef HANDLE_TYPE
+ }
+ }
+ } else if (!is_cleared) {
+ switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
+ case FieldDescriptor::TYPE_##UPPERCASE: \
+ target = WireFormatLite::Write##CAMELCASE##ToArray( \
+ number, VALUE, target); \
+ break
+
+ HANDLE_TYPE( INT32, Int32, int32_value);
+ HANDLE_TYPE( INT64, Int64, int64_value);
+ HANDLE_TYPE( UINT32, UInt32, uint32_value);
+ HANDLE_TYPE( UINT64, UInt64, uint64_value);
+ HANDLE_TYPE( SINT32, SInt32, int32_value);
+ HANDLE_TYPE( SINT64, SInt64, int64_value);
+ HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
+ HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
+ HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
+ HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
+ HANDLE_TYPE( FLOAT, Float, float_value);
+ HANDLE_TYPE( DOUBLE, Double, double_value);
+ HANDLE_TYPE( BOOL, Bool, bool_value);
+ HANDLE_TYPE( STRING, String, *string_value);
+ HANDLE_TYPE( BYTES, Bytes, *string_value);
+ HANDLE_TYPE( ENUM, Enum, enum_value);
+ HANDLE_TYPE( GROUP, Group, *message_value);
+ HANDLE_TYPE( MESSAGE, Message, *message_value);
+#undef HANDLE_TYPE
+ }
+ }
+ return target;
+}
+
+uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
+ int number,
+ uint8* target) const {
+ if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+ // Not a valid MessageSet extension, but serialize it the normal way.
+ GOOGLE_LOG(WARNING) << "Invalid message set extension.";
+ return SerializeFieldWithCachedSizesToArray(number, target);
+ }
+
+ if (is_cleared) return target;
+
+ // Start group.
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetItemStartTag, target);
+ // Write type ID.
+ target = WireFormatLite::WriteUInt32ToArray(
+ WireFormatLite::kMessageSetTypeIdNumber, number, target);
+ // Write message.
+ target = WireFormatLite::WriteMessageToArray(
+ WireFormatLite::kMessageSetMessageNumber, *message_value, target);
+ // End group.
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetItemEndTag, target);
+ return target;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/extension_set_unittest.cc b/src/third_party/protobuf/src/google/protobuf/extension_set_unittest.cc
new file mode 100644
index 0000000..000f846
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/extension_set_unittest.cc
@@ -0,0 +1,642 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+// This test closely mirrors google/protobuf/compiler/cpp/unittest.cc
+// except that it uses extensions rather than regular fields.
+
+TEST(ExtensionSetTest, Defaults) {
+ // Check that all default values are set correctly in the initial message.
+ unittest::TestAllExtensions message;
+
+ TestUtil::ExpectExtensionsClear(message);
+
+ // Messages should return pointers to default instances until first use.
+ // (This is not checked by ExpectClear() since it is not actually true after
+ // the fields have been set and then cleared.)
+ EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(),
+ &message.GetExtension(unittest::optionalgroup_extension));
+ EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.GetExtension(unittest::optional_nested_message_extension));
+ EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
+ &message.GetExtension(
+ unittest::optional_foreign_message_extension));
+ EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+ &message.GetExtension(unittest::optional_import_message_extension));
+}
+
+TEST(ExtensionSetTest, Accessors) {
+ // Set every field to a unique value then go back and check all those
+ // values.
+ unittest::TestAllExtensions message;
+
+ TestUtil::SetAllExtensions(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+
+ TestUtil::ModifyRepeatedExtensions(&message);
+ TestUtil::ExpectRepeatedExtensionsModified(message);
+}
+
+TEST(ExtensionSetTest, Clear) {
+ // Set every field to a unique value, clear the message, then check that
+ // it is cleared.
+ unittest::TestAllExtensions message;
+
+ TestUtil::SetAllExtensions(&message);
+ message.Clear();
+ TestUtil::ExpectExtensionsClear(message);
+
+ // Unlike with the defaults test, we do NOT expect that requesting embedded
+ // messages will return a pointer to the default instance. Instead, they
+ // should return the objects that were created when mutable_blah() was
+ // called.
+ EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
+ &message.GetExtension(unittest::optionalgroup_extension));
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.GetExtension(unittest::optional_nested_message_extension));
+ EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+ &message.GetExtension(
+ unittest::optional_foreign_message_extension));
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &message.GetExtension(unittest::optional_import_message_extension));
+
+ // Make sure setting stuff again after clearing works. (This takes slightly
+ // different code paths since the objects are reused.)
+ TestUtil::SetAllExtensions(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ExtensionSetTest, ClearOneField) {
+ // Set every field to a unique value, then clear one value and insure that
+ // only that one value is cleared.
+ unittest::TestAllExtensions message;
+
+ TestUtil::SetAllExtensions(&message);
+ int64 original_value =
+ message.GetExtension(unittest::optional_int64_extension);
+
+ // Clear the field and make sure it shows up as cleared.
+ message.ClearExtension(unittest::optional_int64_extension);
+ EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension));
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension));
+
+ // Other adjacent fields should not be cleared.
+ EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension));
+
+ // Make sure if we set it again, then all fields are set.
+ message.SetExtension(unittest::optional_int64_extension, original_value);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ExtensionSetTest, CopyFrom) {
+ unittest::TestAllExtensions message1, message2;
+ string data;
+
+ TestUtil::SetAllExtensions(&message1);
+ message2.CopyFrom(message1);
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, CopyFromUpcasted) {
+ unittest::TestAllExtensions message1, message2;
+ string data;
+ const Message& upcasted_message = message1;
+
+ TestUtil::SetAllExtensions(&message1);
+ message2.CopyFrom(upcasted_message);
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, SwapWithEmpty) {
+ unittest::TestAllExtensions message1, message2;
+ TestUtil::SetAllExtensions(&message1);
+
+ TestUtil::ExpectAllExtensionsSet(message1);
+ TestUtil::ExpectExtensionsClear(message2);
+ message1.Swap(&message2);
+ TestUtil::ExpectAllExtensionsSet(message2);
+ TestUtil::ExpectExtensionsClear(message1);
+}
+
+TEST(ExtensionSetTest, SwapWithSelf) {
+ unittest::TestAllExtensions message;
+ TestUtil::SetAllExtensions(&message);
+
+ TestUtil::ExpectAllExtensionsSet(message);
+ message.Swap(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ExtensionSetTest, SerializationToArray) {
+ // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
+ // compatibility of extensions.
+ //
+ // This checks serialization to a flat array by explicitly reserving space in
+ // the string and calling the generated message's
+ // SerializeWithCachedSizesToArray.
+ unittest::TestAllExtensions source;
+ unittest::TestAllTypes destination;
+ TestUtil::SetAllExtensions(&source);
+ int size = source.ByteSize();
+ string data;
+ data.resize(size);
+ uint8* target = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = source.SerializeWithCachedSizesToArray(target);
+ EXPECT_EQ(size, end - target);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, SerializationToStream) {
+ // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
+ // compatibility of extensions.
+ //
+ // This checks serialization to an output stream by creating an array output
+ // stream that can only buffer 1 byte at a time - this prevents the message
+ // from ever jumping to the fast path, ensuring that serialization happens via
+ // the CodedOutputStream.
+ unittest::TestAllExtensions source;
+ unittest::TestAllTypes destination;
+ TestUtil::SetAllExtensions(&source);
+ int size = source.ByteSize();
+ string data;
+ data.resize(size);
+ {
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ source.SerializeWithCachedSizes(&output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedSerializationToArray) {
+ // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
+ // wire compatibility of extensions.
+ //
+ // This checks serialization to a flat array by explicitly reserving space in
+ // the string and calling the generated message's
+ // SerializeWithCachedSizesToArray.
+ unittest::TestPackedExtensions source;
+ unittest::TestPackedTypes destination;
+ TestUtil::SetPackedExtensions(&source);
+ int size = source.ByteSize();
+ string data;
+ data.resize(size);
+ uint8* target = reinterpret_cast<uint8*>(string_as_array(&data));
+ uint8* end = source.SerializeWithCachedSizesToArray(target);
+ EXPECT_EQ(size, end - target);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedSerializationToStream) {
+ // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
+ // wire compatibility of extensions.
+ //
+ // This checks serialization to an output stream by creating an array output
+ // stream that can only buffer 1 byte at a time - this prevents the message
+ // from ever jumping to the fast path, ensuring that serialization happens via
+ // the CodedOutputStream.
+ unittest::TestPackedExtensions source;
+ unittest::TestPackedTypes destination;
+ TestUtil::SetPackedExtensions(&source);
+ int size = source.ByteSize();
+ string data;
+ data.resize(size);
+ {
+ io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ source.SerializeWithCachedSizes(&output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, Parsing) {
+ // Serialize as TestAllTypes and parse as TestAllExtensions.
+ unittest::TestAllTypes source;
+ unittest::TestAllExtensions destination;
+ string data;
+
+ TestUtil::SetAllFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectAllExtensionsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedParsing) {
+ // Serialize as TestPackedTypes and parse as TestPackedExtensions.
+ unittest::TestPackedTypes source;
+ unittest::TestPackedExtensions destination;
+ string data;
+
+ TestUtil::SetPackedFields(&source);
+ source.SerializeToString(&data);
+ EXPECT_TRUE(destination.ParseFromString(data));
+ TestUtil::ExpectPackedExtensionsSet(destination);
+}
+
+TEST(ExtensionSetTest, IsInitialized) {
+ // Test that IsInitialized() returns false if required fields in nested
+ // extensions are missing.
+ unittest::TestAllExtensions message;
+
+ EXPECT_TRUE(message.IsInitialized());
+
+ message.MutableExtension(unittest::TestRequired::single);
+ EXPECT_FALSE(message.IsInitialized());
+
+ message.MutableExtension(unittest::TestRequired::single)->set_a(1);
+ EXPECT_FALSE(message.IsInitialized());
+ message.MutableExtension(unittest::TestRequired::single)->set_b(2);
+ EXPECT_FALSE(message.IsInitialized());
+ message.MutableExtension(unittest::TestRequired::single)->set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+
+ message.AddExtension(unittest::TestRequired::multi);
+ EXPECT_FALSE(message.IsInitialized());
+
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
+ EXPECT_FALSE(message.IsInitialized());
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
+ EXPECT_FALSE(message.IsInitialized());
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
+ EXPECT_TRUE(message.IsInitialized());
+}
+
+TEST(ExtensionSetTest, MutableString) {
+ // Test the mutable string accessors.
+ unittest::TestAllExtensions message;
+
+ message.MutableExtension(unittest::optional_string_extension)->assign("foo");
+ EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension));
+ EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension));
+
+ message.AddExtension(unittest::repeated_string_extension)->assign("bar");
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension));
+ EXPECT_EQ("bar",
+ message.GetExtension(unittest::repeated_string_extension, 0));
+}
+
+TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
+ // Scalar primitive extensions should increase the extension set size by a
+ // minimum of the size of the primitive type.
+#define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \
+ do { \
+ unittest::TestAllExtensions message; \
+ const int base_size = message.SpaceUsed(); \
+ message.SetExtension(unittest::optional_##type##_extension, value); \
+ int min_expected_size = base_size + \
+ sizeof(message.GetExtension(unittest::optional_##type##_extension)); \
+ EXPECT_LE(min_expected_size, message.SpaceUsed()); \
+ } while (0)
+
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(int32 , 101);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(int64 , 102);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(uint32 , 103);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(uint64 , 104);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(sint32 , 105);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(sint64 , 106);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32 , 107);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64 , 108);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(float , 111);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(double , 112);
+ TEST_SCALAR_EXTENSIONS_SPACE_USED(bool , true);
+#undef TEST_SCALAR_EXTENSIONS_SPACE_USED
+ {
+ unittest::TestAllExtensions message;
+ const int base_size = message.SpaceUsed();
+ message.SetExtension(unittest::optional_nested_enum_extension,
+ unittest::TestAllTypes::FOO);
+ int min_expected_size = base_size +
+ sizeof(message.GetExtension(unittest::optional_nested_enum_extension));
+ EXPECT_LE(min_expected_size, message.SpaceUsed());
+ }
+ {
+ // Strings may cause extra allocations depending on their length; ensure
+ // that gets included as well.
+ unittest::TestAllExtensions message;
+ const int base_size = message.SpaceUsed();
+ const string s("this is a fairly large string that will cause some "
+ "allocation in order to store it in the extension");
+ message.SetExtension(unittest::optional_string_extension, s);
+ int min_expected_size = base_size + s.length();
+ EXPECT_LE(min_expected_size, message.SpaceUsed());
+ }
+ {
+ // Messages also have additional allocation that need to be counted.
+ unittest::TestAllExtensions message;
+ const int base_size = message.SpaceUsed();
+ unittest::ForeignMessage foreign;
+ foreign.set_c(42);
+ message.MutableExtension(unittest::optional_foreign_message_extension)->
+ CopyFrom(foreign);
+ int min_expected_size = base_size + foreign.SpaceUsed();
+ EXPECT_LE(min_expected_size, message.SpaceUsed());
+ }
+
+ // Repeated primitive extensions will increase space used by at least a
+ // RepeatedField<T>, and will cause additional allocations when the array
+ // gets too big for the initial space.
+ // This macro:
+ // - Adds a value to the repeated extension, then clears it, establishing
+ // the base size.
+ // - Adds a small number of values, testing that it doesn't increase the
+ // SpaceUsed()
+ // - Adds a large number of values (requiring allocation in the repeated
+ // field), and ensures that that allocation is included in SpaceUsed()
+#define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \
+ do { \
+ unittest::TestAllExtensions message; \
+ const int base_size = message.SpaceUsed(); \
+ int min_expected_size = sizeof(RepeatedField<cpptype>) + base_size; \
+ message.AddExtension(unittest::repeated_##type##_extension, value); \
+ message.ClearExtension(unittest::repeated_##type##_extension); \
+ const int empty_repeated_field_size = message.SpaceUsed(); \
+ EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \
+ message.AddExtension(unittest::repeated_##type##_extension, value); \
+ message.AddExtension(unittest::repeated_##type##_extension, value); \
+ EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type; \
+ message.ClearExtension(unittest::repeated_##type##_extension); \
+ for (int i = 0; i < 16; ++i) { \
+ message.AddExtension(unittest::repeated_##type##_extension, value); \
+ } \
+ int expected_size = sizeof(cpptype) * 16 + empty_repeated_field_size; \
+ EXPECT_EQ(expected_size, message.SpaceUsed()) << #type; \
+ } while (0)
+
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(int32 , int32 , 101);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(int64 , int64 , 102);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(uint32 , uint32, 103);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(uint64 , uint64, 104);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(sint32 , int32 , 105);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(sint64 , int64 , 106);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed32 , uint32, 107);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed64 , uint64, 108);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed32, int32 , 109);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed64, int64 , 110);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(float , float , 111);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(double , double, 112);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(bool , bool , true);
+ TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int,
+ unittest::TestAllTypes::FOO);
+#undef TEST_REPEATED_EXTENSIONS_SPACE_USED
+ // Repeated strings
+ {
+ unittest::TestAllExtensions message;
+ const int base_size = message.SpaceUsed();
+ int min_expected_size = sizeof(RepeatedPtrField<string>) + base_size;
+ const string value(256, 'x');
+ // Once items are allocated, they may stick around even when cleared so
+ // without the hardcore memory management accessors there isn't a notion of
+ // the empty repeated field memory usage as there is with primitive types.
+ for (int i = 0; i < 16; ++i) {
+ message.AddExtension(unittest::repeated_string_extension, value);
+ }
+ min_expected_size += (sizeof(value) + value.size()) * 16;
+ EXPECT_LE(min_expected_size, message.SpaceUsed());
+ }
+ // Repeated messages
+ {
+ unittest::TestAllExtensions message;
+ const int base_size = message.SpaceUsed();
+ int min_expected_size = sizeof(RepeatedPtrField<unittest::ForeignMessage>) +
+ base_size;
+ unittest::ForeignMessage prototype;
+ prototype.set_c(2);
+ for (int i = 0; i < 16; ++i) {
+ message.AddExtension(unittest::repeated_foreign_message_extension)->
+ CopyFrom(prototype);
+ }
+ min_expected_size += 16 * prototype.SpaceUsed();
+ EXPECT_LE(min_expected_size, message.SpaceUsed());
+ }
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(ExtensionSetTest, InvalidEnumDeath) {
+ unittest::TestAllExtensions message;
+ EXPECT_DEBUG_DEATH(
+ message.SetExtension(unittest::optional_foreign_enum_extension,
+ static_cast<unittest::ForeignEnum>(53)),
+ "IsValid");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+TEST(ExtensionSetTest, DynamicExtensions) {
+ // Test adding a dynamic extension to a compiled-in message object.
+
+ FileDescriptorProto dynamic_proto;
+ dynamic_proto.set_name("dynamic_extensions_test.proto");
+ dynamic_proto.add_dependency(
+ unittest::TestAllExtensions::descriptor()->file()->name());
+ dynamic_proto.set_package("dynamic_extensions");
+
+ // Copy the fields and nested types from TestDynamicExtensions into our new
+ // proto, converting the fields into extensions.
+ const Descriptor* template_descriptor =
+ unittest::TestDynamicExtensions::descriptor();
+ DescriptorProto template_descriptor_proto;
+ template_descriptor->CopyTo(&template_descriptor_proto);
+ dynamic_proto.mutable_message_type()->MergeFrom(
+ template_descriptor_proto.nested_type());
+ dynamic_proto.mutable_enum_type()->MergeFrom(
+ template_descriptor_proto.enum_type());
+ dynamic_proto.mutable_extension()->MergeFrom(
+ template_descriptor_proto.field());
+
+ // For each extension that we added...
+ for (int i = 0; i < dynamic_proto.extension_size(); i++) {
+ // Set its extendee to TestAllExtensions.
+ FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i);
+ extension->set_extendee(
+ unittest::TestAllExtensions::descriptor()->full_name());
+
+ // If the field refers to one of the types nested in TestDynamicExtensions,
+ // make it refer to the type in our dynamic proto instead.
+ string prefix = "." + template_descriptor->full_name() + ".";
+ if (extension->has_type_name()) {
+ string* type_name = extension->mutable_type_name();
+ if (HasPrefixString(*type_name, prefix)) {
+ type_name->replace(0, prefix.size(), ".dynamic_extensions.");
+ }
+ }
+ }
+
+ // Now build the file, using the generated pool as an underlay.
+ DescriptorPool dynamic_pool(DescriptorPool::generated_pool());
+ const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto);
+ ASSERT_TRUE(file != NULL);
+ DynamicMessageFactory dynamic_factory(&dynamic_pool);
+ dynamic_factory.SetDelegateToGeneratedFactory(true);
+
+ // Construct a message that we can parse with the extensions we defined.
+ // Since the extensions were based off of the fields of TestDynamicExtensions,
+ // we can use that message to create this test message.
+ string data;
+ {
+ unittest::TestDynamicExtensions message;
+ message.set_scalar_extension(123);
+ message.set_enum_extension(unittest::FOREIGN_BAR);
+ message.set_dynamic_enum_extension(
+ unittest::TestDynamicExtensions::DYNAMIC_BAZ);
+ message.mutable_message_extension()->set_c(456);
+ message.mutable_dynamic_message_extension()->set_dynamic_field(789);
+ message.add_repeated_extension("foo");
+ message.add_repeated_extension("bar");
+ message.add_packed_extension(12);
+ message.add_packed_extension(-34);
+ message.add_packed_extension(56);
+ message.add_packed_extension(-78);
+
+ // Also add some unknown fields.
+
+ // An unknown enum value (for a known field).
+ message.mutable_unknown_fields()->AddVarint(
+ unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber,
+ 12345);
+ // A regular unknown field.
+ message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown");
+
+ message.SerializeToString(&data);
+ }
+
+ // Now we can parse this using our dynamic extension definitions...
+ unittest::TestAllExtensions message;
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
+ ASSERT_TRUE(message.ParseFromCodedStream(&input));
+ ASSERT_TRUE(input.ConsumedEntireMessage());
+ }
+
+ // Can we print it?
+ EXPECT_EQ(
+ "[dynamic_extensions.scalar_extension]: 123\n"
+ "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n"
+ "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n"
+ "[dynamic_extensions.message_extension] {\n"
+ " c: 456\n"
+ "}\n"
+ "[dynamic_extensions.dynamic_message_extension] {\n"
+ " dynamic_field: 789\n"
+ "}\n"
+ "[dynamic_extensions.repeated_extension]: \"foo\"\n"
+ "[dynamic_extensions.repeated_extension]: \"bar\"\n"
+ "[dynamic_extensions.packed_extension]: 12\n"
+ "[dynamic_extensions.packed_extension]: -34\n"
+ "[dynamic_extensions.packed_extension]: 56\n"
+ "[dynamic_extensions.packed_extension]: -78\n"
+ "2002: 12345\n"
+ "54321: \"unknown\"\n",
+ message.DebugString());
+
+ // Can we serialize it?
+ // (Don't use EXPECT_EQ because we don't want to dump raw binary data to the
+ // terminal on failure.)
+ EXPECT_TRUE(message.SerializeAsString() == data);
+
+ // What if we parse using the reflection-based parser?
+ {
+ unittest::TestAllExtensions message2;
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message2));
+ ASSERT_TRUE(input.ConsumedEntireMessage());
+ EXPECT_EQ(message.DebugString(), message2.DebugString());
+ }
+
+ // Are the embedded generated types actually using the generated objects?
+ {
+ const FieldDescriptor* message_extension =
+ file->FindExtensionByName("message_extension");
+ ASSERT_TRUE(message_extension != NULL);
+ const Message& sub_message =
+ message.GetReflection()->GetMessage(message, message_extension);
+ const unittest::ForeignMessage* typed_sub_message =
+ dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
+ ASSERT_TRUE(typed_sub_message != NULL);
+ EXPECT_EQ(456, typed_sub_message->c());
+ }
+
+ // What does GetMessage() return for the embedded dynamic type if it isn't
+ // present?
+ {
+ const FieldDescriptor* dynamic_message_extension =
+ file->FindExtensionByName("dynamic_message_extension");
+ ASSERT_TRUE(dynamic_message_extension != NULL);
+ const Message& parent = unittest::TestAllExtensions::default_instance();
+ const Message& sub_message =
+ parent.GetReflection()->GetMessage(parent, dynamic_message_extension,
+ &dynamic_factory);
+ const Message* prototype =
+ dynamic_factory.GetPrototype(dynamic_message_extension->message_type());
+ EXPECT_EQ(prototype, &sub_message);
+ }
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc b/src/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
new file mode 100644
index 0000000..226e951
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
@@ -0,0 +1,1216 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+bool ParseNamedEnum(const EnumDescriptor* descriptor,
+ const string& name,
+ int* value) {
+ const EnumValueDescriptor* d = descriptor->FindValueByName(name);
+ if (d == NULL) return false;
+ *value = d->number();
+ return true;
+}
+
+const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
+ const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
+ return (d == NULL ? kEmptyString : d->name());
+}
+
+// ===================================================================
+// Helpers for reporting usage errors (e.g. trying to use GetInt32() on
+// a string field).
+
+namespace {
+
+void ReportReflectionUsageError(
+ const Descriptor* descriptor, const FieldDescriptor* field,
+ const char* method, const char* description) {
+ GOOGLE_LOG(FATAL)
+ << "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::" << method << "\n"
+ " Message type: " << descriptor->full_name() << "\n"
+ " Field : " << field->full_name() << "\n"
+ " Problem : " << description;
+}
+
+const char* cpptype_names_[FieldDescriptor::MAX_CPPTYPE + 1] = {
+ "INVALID_CPPTYPE",
+ "CPPTYPE_INT32",
+ "CPPTYPE_INT64",
+ "CPPTYPE_UINT32",
+ "CPPTYPE_UINT64",
+ "CPPTYPE_DOUBLE",
+ "CPPTYPE_FLOAT",
+ "CPPTYPE_BOOL",
+ "CPPTYPE_ENUM",
+ "CPPTYPE_STRING",
+ "CPPTYPE_MESSAGE"
+};
+
+static void ReportReflectionUsageTypeError(
+ const Descriptor* descriptor, const FieldDescriptor* field,
+ const char* method,
+ FieldDescriptor::CppType expected_type) {
+ GOOGLE_LOG(FATAL)
+ << "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::" << method << "\n"
+ " Message type: " << descriptor->full_name() << "\n"
+ " Field : " << field->full_name() << "\n"
+ " Problem : Field is not the right type for this message:\n"
+ " Expected : " << cpptype_names_[expected_type] << "\n"
+ " Field type: " << cpptype_names_[field->cpp_type()];
+}
+
+static void ReportReflectionUsageEnumTypeError(
+ const Descriptor* descriptor, const FieldDescriptor* field,
+ const char* method, const EnumValueDescriptor* value) {
+ GOOGLE_LOG(FATAL)
+ << "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::" << method << "\n"
+ " Message type: " << descriptor->full_name() << "\n"
+ " Field : " << field->full_name() << "\n"
+ " Problem : Enum value did not match field type:\n"
+ " Expected : " << field->enum_type()->full_name() << "\n"
+ " Actual : " << value->full_name();
+}
+
+#define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \
+ if (!(CONDITION)) \
+ ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION)
+#define USAGE_CHECK_EQ(A, B, METHOD, ERROR_DESCRIPTION) \
+ USAGE_CHECK((A) == (B), METHOD, ERROR_DESCRIPTION)
+#define USAGE_CHECK_NE(A, B, METHOD, ERROR_DESCRIPTION) \
+ USAGE_CHECK((A) != (B), METHOD, ERROR_DESCRIPTION)
+
+#define USAGE_CHECK_TYPE(METHOD, CPPTYPE) \
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_##CPPTYPE) \
+ ReportReflectionUsageTypeError(descriptor_, field, #METHOD, \
+ FieldDescriptor::CPPTYPE_##CPPTYPE)
+
+#define USAGE_CHECK_ENUM_VALUE(METHOD) \
+ if (value->type() != field->enum_type()) \
+ ReportReflectionUsageEnumTypeError(descriptor_, field, #METHOD, value)
+
+#define USAGE_CHECK_MESSAGE_TYPE(METHOD) \
+ USAGE_CHECK_EQ(field->containing_type(), descriptor_, \
+ METHOD, "Field does not match message type.");
+#define USAGE_CHECK_SINGULAR(METHOD) \
+ USAGE_CHECK_NE(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
+ "Field is repeated; the method requires a singular field.")
+#define USAGE_CHECK_REPEATED(METHOD) \
+ USAGE_CHECK_EQ(field->label(), FieldDescriptor::LABEL_REPEATED, METHOD, \
+ "Field is singular; the method requires a repeated field.")
+
+#define USAGE_CHECK_ALL(METHOD, LABEL, CPPTYPE) \
+ USAGE_CHECK_MESSAGE_TYPE(METHOD); \
+ USAGE_CHECK_##LABEL(METHOD); \
+ USAGE_CHECK_TYPE(METHOD, CPPTYPE)
+
+} // namespace
+
+// ===================================================================
+
+GeneratedMessageReflection::GeneratedMessageReflection(
+ const Descriptor* descriptor,
+ const Message* default_instance,
+ const int offsets[],
+ int has_bits_offset,
+ int unknown_fields_offset,
+ int extensions_offset,
+ const DescriptorPool* descriptor_pool,
+ MessageFactory* factory,
+ int object_size)
+ : descriptor_ (descriptor),
+ default_instance_ (default_instance),
+ offsets_ (offsets),
+ has_bits_offset_ (has_bits_offset),
+ unknown_fields_offset_(unknown_fields_offset),
+ extensions_offset_(extensions_offset),
+ object_size_ (object_size),
+ descriptor_pool_ ((descriptor_pool == NULL) ?
+ DescriptorPool::generated_pool() :
+ descriptor_pool),
+ message_factory_ (factory) {
+}
+
+GeneratedMessageReflection::~GeneratedMessageReflection() {}
+
+const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
+ const Message& message) const {
+ const void* ptr = reinterpret_cast<const uint8*>(&message) +
+ unknown_fields_offset_;
+ return *reinterpret_cast<const UnknownFieldSet*>(ptr);
+}
+UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
+ Message* message) const {
+ void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_;
+ return reinterpret_cast<UnknownFieldSet*>(ptr);
+}
+
+int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
+ // object_size_ already includes the in-memory representation of each field
+ // in the message, so we only need to account for additional memory used by
+ // the fields.
+ int total_size = object_size_;
+
+ total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
+
+ if (extensions_offset_ != -1) {
+ total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE : \
+ total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field) \
+ .SpaceUsedExcludingSelf(); \
+ break
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, int);
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ total_size += GetRaw<RepeatedPtrField<string> >(message, field)
+ .SpaceUsedExcludingSelf();
+ break;
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ // We don't know which subclass of RepeatedPtrFieldBase the type is,
+ // so we use RepeatedPtrFieldBase directly.
+ total_size +=
+ GetRaw<RepeatedPtrFieldBase>(message, field)
+ .SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
+ break;
+ }
+ } else {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32 :
+ case FieldDescriptor::CPPTYPE_INT64 :
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_FLOAT :
+ case FieldDescriptor::CPPTYPE_BOOL :
+ case FieldDescriptor::CPPTYPE_ENUM :
+ // Field is inline, so we've already counted it.
+ break;
+
+ case FieldDescriptor::CPPTYPE_STRING: {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING: {
+ const string* ptr = GetField<const string*>(message, field);
+
+ // Initially, the string points to the default value stored in
+ // the prototype. Only count the string if it has been changed
+ // from the default value.
+ const string* default_ptr = DefaultRaw<const string*>(field);
+
+ if (ptr != default_ptr) {
+ // string fields are represented by just a pointer, so also
+ // include sizeof(string) as well.
+ total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr);
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ if (&message == default_instance_) {
+ // For singular fields, the prototype just stores a pointer to the
+ // external type's prototype, so there is no extra memory usage.
+ } else {
+ const Message* sub_message = GetRaw<const Message*>(message, field);
+ if (sub_message != NULL) {
+ total_size += sub_message->SpaceUsed();
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return total_size;
+}
+
+void GeneratedMessageReflection::Swap(
+ Message* message1,
+ Message* message2) const {
+ if (message1 == message2) return;
+
+ // TODO(kenton): Other Reflection methods should probably check this too.
+ GOOGLE_CHECK_EQ(message1->GetReflection(), this)
+ << "First argument to Swap() (of type \""
+ << message1->GetDescriptor()->full_name()
+ << "\") is not compatible with this reflection object (which is for type \""
+ << descriptor_->full_name()
+ << "\"). Note that the exact same class is required; not just the same "
+ "descriptor.";
+ GOOGLE_CHECK_EQ(message2->GetReflection(), this)
+ << "Second argument to Swap() (of type \""
+ << message1->GetDescriptor()->full_name()
+ << "\") is not compatible with this reflection object (which is for type \""
+ << descriptor_->full_name()
+ << "\"). Note that the exact same class is required; not just the same "
+ "descriptor.";
+
+ uint32* has_bits1 = MutableHasBits(message1);
+ uint32* has_bits2 = MutableHasBits(message2);
+ int has_bits_size = (descriptor_->field_count() + 31) / 32;
+
+ for (int i = 0; i < has_bits_size; i++) {
+ std::swap(has_bits1[i], has_bits2[i]);
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define SWAP_ARRAYS(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap( \
+ MutableRaw<RepeatedField<TYPE> >(message2, field)); \
+ break;
+
+ SWAP_ARRAYS(INT32 , int32 );
+ SWAP_ARRAYS(INT64 , int64 );
+ SWAP_ARRAYS(UINT32, uint32);
+ SWAP_ARRAYS(UINT64, uint64);
+ SWAP_ARRAYS(FLOAT , float );
+ SWAP_ARRAYS(DOUBLE, double);
+ SWAP_ARRAYS(BOOL , bool );
+ SWAP_ARRAYS(ENUM , int );
+#undef SWAP_ARRAYS
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ MutableRaw<RepeatedPtrFieldBase>(message1, field)->Swap(
+ MutableRaw<RepeatedPtrFieldBase>(message2, field));
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+ }
+ } else {
+ switch (field->cpp_type()) {
+#define SWAP_VALUES(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ std::swap(*MutableRaw<TYPE>(message1, field), \
+ *MutableRaw<TYPE>(message2, field)); \
+ break;
+
+ SWAP_VALUES(INT32 , int32 );
+ SWAP_VALUES(INT64 , int64 );
+ SWAP_VALUES(UINT32, uint32);
+ SWAP_VALUES(UINT64, uint64);
+ SWAP_VALUES(FLOAT , float );
+ SWAP_VALUES(DOUBLE, double);
+ SWAP_VALUES(BOOL , bool );
+ SWAP_VALUES(ENUM , int );
+ SWAP_VALUES(MESSAGE, Message*);
+#undef SWAP_VALUES
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ std::swap(*MutableRaw<string*>(message1, field),
+ *MutableRaw<string*>(message2, field));
+ break;
+ }
+ break;
+
+ default:
+ GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+ }
+ }
+ }
+
+ if (extensions_offset_ != -1) {
+ MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
+ }
+
+ MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
+}
+
+// -------------------------------------------------------------------
+
+bool GeneratedMessageReflection::HasField(const Message& message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK_MESSAGE_TYPE(HasField);
+ USAGE_CHECK_SINGULAR(HasField);
+
+ if (field->is_extension()) {
+ return GetExtensionSet(message).Has(field->number());
+ } else {
+ return HasBit(message, field);
+ }
+}
+
+int GeneratedMessageReflection::FieldSize(const Message& message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK_MESSAGE_TYPE(FieldSize);
+ USAGE_CHECK_REPEATED(FieldSize);
+
+ if (field->is_extension()) {
+ return GetExtensionSet(message).ExtensionSize(field->number());
+ } else {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE : \
+ return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, int);
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return GetRaw<RepeatedPtrFieldBase>(message, field).size();
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return 0;
+ }
+}
+
+void GeneratedMessageReflection::ClearField(
+ Message* message, const FieldDescriptor* field) const {
+ USAGE_CHECK_MESSAGE_TYPE(ClearField);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->ClearExtension(field->number());
+ } else if (!field->is_repeated()) {
+ if (HasBit(*message, field)) {
+ ClearBit(message, field);
+
+ // We need to set the field back to its default value.
+ switch (field->cpp_type()) {
+#define CLEAR_TYPE(CPPTYPE, TYPE) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ *MutableRaw<TYPE>(message, field) = \
+ field->default_value_##TYPE(); \
+ break;
+
+ CLEAR_TYPE(INT32 , int32 );
+ CLEAR_TYPE(INT64 , int64 );
+ CLEAR_TYPE(UINT32, uint32);
+ CLEAR_TYPE(UINT64, uint64);
+ CLEAR_TYPE(FLOAT , float );
+ CLEAR_TYPE(DOUBLE, double);
+ CLEAR_TYPE(BOOL , bool );
+#undef CLEAR_TYPE
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ *MutableRaw<int>(message, field) =
+ field->default_value_enum()->number();
+ break;
+
+ case FieldDescriptor::CPPTYPE_STRING: {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ const string* default_ptr = DefaultRaw<const string*>(field);
+ string** value = MutableRaw<string*>(message, field);
+ if (*value != default_ptr) {
+ if (field->has_default_value()) {
+ (*value)->assign(field->default_value_string());
+ } else {
+ (*value)->clear();
+ }
+ }
+ break;
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ (*MutableRaw<Message*>(message, field))->Clear();
+ break;
+ }
+ }
+ } else {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE : \
+ MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear(); \
+ break
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, int);
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_STRING: {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ MutableRaw<RepeatedPtrField<string> >(message, field)->Clear();
+ break;
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ // We don't know which subclass of RepeatedPtrFieldBase the type is,
+ // so we use RepeatedPtrFieldBase directly.
+ MutableRaw<RepeatedPtrFieldBase>(message, field)
+ ->Clear<GenericTypeHandler<Message> >();
+ break;
+ }
+ }
+ }
+}
+
+void GeneratedMessageReflection::RemoveLast(
+ Message* message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
+ USAGE_CHECK_REPEATED(RemoveLast);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->RemoveLast(field->number());
+ } else {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE : \
+ MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast(); \
+ break
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, int);
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast();
+ break;
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ MutableRaw<RepeatedPtrFieldBase>(message, field)
+ ->RemoveLast<GenericTypeHandler<Message> >();
+ break;
+ }
+ }
+}
+
+void GeneratedMessageReflection::SwapElements(
+ Message* message,
+ const FieldDescriptor* field,
+ int index1,
+ int index2) const {
+ USAGE_CHECK_MESSAGE_TYPE(Swap);
+ USAGE_CHECK_REPEATED(Swap);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
+ } else {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
+ case FieldDescriptor::CPPTYPE_##UPPERCASE : \
+ MutableRaw<RepeatedField<LOWERCASE> >(message, field) \
+ ->SwapElements(index1, index2); \
+ break
+
+ HANDLE_TYPE( INT32, int32);
+ HANDLE_TYPE( INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE( FLOAT, float);
+ HANDLE_TYPE( BOOL, bool);
+ HANDLE_TYPE( ENUM, int);
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ MutableRaw<RepeatedPtrFieldBase>(message, field)
+ ->SwapElements(index1, index2);
+ break;
+ }
+ }
+}
+
+namespace {
+// Comparison functor for sorting FieldDescriptors by field number.
+struct FieldNumberSorter {
+ bool operator()(const FieldDescriptor* left,
+ const FieldDescriptor* right) const {
+ return left->number() < right->number();
+ }
+};
+} // namespace
+
+void GeneratedMessageReflection::ListFields(
+ const Message& message,
+ vector<const FieldDescriptor*>* output) const {
+ output->clear();
+
+ // Optimization: The default instance never has any fields set.
+ if (&message == default_instance_) return;
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->is_repeated()) {
+ if (FieldSize(message, field) > 0) {
+ output->push_back(field);
+ }
+ } else {
+ if (HasBit(message, field)) {
+ output->push_back(field);
+ }
+ }
+ }
+
+ if (extensions_offset_ != -1) {
+ GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
+ output);
+ }
+
+ // ListFields() must sort output by field number.
+ sort(output->begin(), output->end(), FieldNumberSorter());
+}
+
+// -------------------------------------------------------------------
+
+#undef DEFINE_PRIMITIVE_ACCESSORS
+#define DEFINE_PRIMITIVE_ACCESSORS(TYPENAME, TYPE, PASSTYPE, CPPTYPE) \
+ PASSTYPE GeneratedMessageReflection::Get##TYPENAME( \
+ const Message& message, const FieldDescriptor* field) const { \
+ USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE); \
+ if (field->is_extension()) { \
+ return GetExtensionSet(message).Get##TYPENAME( \
+ field->number(), field->default_value_##PASSTYPE()); \
+ } else { \
+ return GetField<TYPE>(message, field); \
+ } \
+ } \
+ \
+ void GeneratedMessageReflection::Set##TYPENAME( \
+ Message* message, const FieldDescriptor* field, \
+ PASSTYPE value) const { \
+ USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE); \
+ if (field->is_extension()) { \
+ return MutableExtensionSet(message)->Set##TYPENAME( \
+ field->number(), field->type(), value, field); \
+ } else { \
+ SetField<TYPE>(message, field, value); \
+ } \
+ } \
+ \
+ PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME( \
+ const Message& message, \
+ const FieldDescriptor* field, int index) const { \
+ USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE); \
+ if (field->is_extension()) { \
+ return GetExtensionSet(message).GetRepeated##TYPENAME( \
+ field->number(), index); \
+ } else { \
+ return GetRepeatedField<TYPE>(message, field, index); \
+ } \
+ } \
+ \
+ void GeneratedMessageReflection::SetRepeated##TYPENAME( \
+ Message* message, const FieldDescriptor* field, \
+ int index, PASSTYPE value) const { \
+ USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE); \
+ if (field->is_extension()) { \
+ MutableExtensionSet(message)->SetRepeated##TYPENAME( \
+ field->number(), index, value); \
+ } else { \
+ SetRepeatedField<TYPE>(message, field, index, value); \
+ } \
+ } \
+ \
+ void GeneratedMessageReflection::Add##TYPENAME( \
+ Message* message, const FieldDescriptor* field, \
+ PASSTYPE value) const { \
+ USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE); \
+ if (field->is_extension()) { \
+ MutableExtensionSet(message)->Add##TYPENAME( \
+ field->number(), field->type(), field->options().packed(), value, \
+ field); \
+ } else { \
+ AddField<TYPE>(message, field, value); \
+ } \
+ }
+
+DEFINE_PRIMITIVE_ACCESSORS(Int32 , int32 , int32 , INT32 )
+DEFINE_PRIMITIVE_ACCESSORS(Int64 , int64 , int64 , INT64 )
+DEFINE_PRIMITIVE_ACCESSORS(UInt32, uint32, uint32, UINT32)
+DEFINE_PRIMITIVE_ACCESSORS(UInt64, uint64, uint64, UINT64)
+DEFINE_PRIMITIVE_ACCESSORS(Float , float , float , FLOAT )
+DEFINE_PRIMITIVE_ACCESSORS(Double, double, double, DOUBLE)
+DEFINE_PRIMITIVE_ACCESSORS(Bool , bool , bool , BOOL )
+#undef DEFINE_PRIMITIVE_ACCESSORS
+
+// -------------------------------------------------------------------
+
+string GeneratedMessageReflection::GetString(
+ const Message& message, const FieldDescriptor* field) const {
+ USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
+ if (field->is_extension()) {
+ return GetExtensionSet(message).GetString(field->number(),
+ field->default_value_string());
+ } else {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ return *GetField<const string*>(message, field);
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return kEmptyString; // Make compiler happy.
+ }
+}
+
+const string& GeneratedMessageReflection::GetStringReference(
+ const Message& message,
+ const FieldDescriptor* field, string* scratch) const {
+ USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
+ if (field->is_extension()) {
+ return GetExtensionSet(message).GetString(field->number(),
+ field->default_value_string());
+ } else {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ return *GetField<const string*>(message, field);
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return kEmptyString; // Make compiler happy.
+ }
+}
+
+
+void GeneratedMessageReflection::SetString(
+ Message* message, const FieldDescriptor* field,
+ const string& value) const {
+ USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
+ if (field->is_extension()) {
+ return MutableExtensionSet(message)->SetString(field->number(),
+ field->type(), value, field);
+ } else {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING: {
+ string** ptr = MutableField<string*>(message, field);
+ if (*ptr == DefaultRaw<const string*>(field)) {
+ *ptr = new string(value);
+ } else {
+ (*ptr)->assign(value);
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+string GeneratedMessageReflection::GetRepeatedString(
+ const Message& message, const FieldDescriptor* field, int index) const {
+ USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
+ if (field->is_extension()) {
+ return GetExtensionSet(message).GetRepeatedString(field->number(), index);
+ } else {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ return GetRepeatedPtrField<string>(message, field, index);
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return kEmptyString; // Make compiler happy.
+ }
+}
+
+const string& GeneratedMessageReflection::GetRepeatedStringReference(
+ const Message& message, const FieldDescriptor* field,
+ int index, string* scratch) const {
+ USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
+ if (field->is_extension()) {
+ return GetExtensionSet(message).GetRepeatedString(field->number(), index);
+ } else {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ return GetRepeatedPtrField<string>(message, field, index);
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return kEmptyString; // Make compiler happy.
+ }
+}
+
+
+void GeneratedMessageReflection::SetRepeatedString(
+ Message* message, const FieldDescriptor* field,
+ int index, const string& value) const {
+ USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->SetRepeatedString(
+ field->number(), index, value);
+ } else {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ *MutableRepeatedField<string>(message, field, index) = value;
+ break;
+ }
+ }
+}
+
+
+void GeneratedMessageReflection::AddString(
+ Message* message, const FieldDescriptor* field,
+ const string& value) const {
+ USAGE_CHECK_ALL(AddString, REPEATED, STRING);
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->AddString(field->number(),
+ field->type(), value, field);
+ } else {
+ switch (field->options().ctype()) {
+ default: // TODO(kenton): Support other string reps.
+ case FieldOptions::STRING:
+ *AddField<string>(message, field) = value;
+ break;
+ }
+ }
+}
+
+
+// -------------------------------------------------------------------
+
+const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
+ const Message& message, const FieldDescriptor* field) const {
+ USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM);
+
+ int value;
+ if (field->is_extension()) {
+ value = GetExtensionSet(message).GetEnum(
+ field->number(), field->default_value_enum()->number());
+ } else {
+ value = GetField<int>(message, field);
+ }
+ const EnumValueDescriptor* result =
+ field->enum_type()->FindValueByNumber(value);
+ GOOGLE_CHECK(result != NULL);
+ return result;
+}
+
+void GeneratedMessageReflection::SetEnum(
+ Message* message, const FieldDescriptor* field,
+ const EnumValueDescriptor* value) const {
+ USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM);
+ USAGE_CHECK_ENUM_VALUE(SetEnum);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->SetEnum(field->number(), field->type(),
+ value->number(), field);
+ } else {
+ SetField<int>(message, field, value->number());
+ }
+}
+
+const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
+ const Message& message, const FieldDescriptor* field, int index) const {
+ USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM);
+
+ int value;
+ if (field->is_extension()) {
+ value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
+ } else {
+ value = GetRepeatedField<int>(message, field, index);
+ }
+ const EnumValueDescriptor* result =
+ field->enum_type()->FindValueByNumber(value);
+ GOOGLE_CHECK(result != NULL);
+ return result;
+}
+
+void GeneratedMessageReflection::SetRepeatedEnum(
+ Message* message,
+ const FieldDescriptor* field, int index,
+ const EnumValueDescriptor* value) const {
+ USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
+ USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->SetRepeatedEnum(
+ field->number(), index, value->number());
+ } else {
+ SetRepeatedField<int>(message, field, index, value->number());
+ }
+}
+
+void GeneratedMessageReflection::AddEnum(
+ Message* message, const FieldDescriptor* field,
+ const EnumValueDescriptor* value) const {
+ USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
+ USAGE_CHECK_ENUM_VALUE(AddEnum);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
+ field->options().packed(),
+ value->number(), field);
+ } else {
+ AddField<int>(message, field, value->number());
+ }
+}
+
+// -------------------------------------------------------------------
+
+const Message& GeneratedMessageReflection::GetMessage(
+ const Message& message, const FieldDescriptor* field,
+ MessageFactory* factory) const {
+ USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
+
+ if (field->is_extension()) {
+ return static_cast<const Message&>(
+ GetExtensionSet(message).GetMessage(
+ field->number(), field->message_type(),
+ factory == NULL ? message_factory_ : factory));
+ } else {
+ const Message* result = GetRaw<const Message*>(message, field);
+ if (result == NULL) {
+ result = DefaultRaw<const Message*>(field);
+ }
+ return *result;
+ }
+}
+
+Message* GeneratedMessageReflection::MutableMessage(
+ Message* message, const FieldDescriptor* field,
+ MessageFactory* factory) const {
+ USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE);
+
+ if (field->is_extension()) {
+ return static_cast<Message*>(
+ MutableExtensionSet(message)->MutableMessage(field,
+ factory == NULL ? message_factory_ : factory));
+ } else {
+ Message** result = MutableField<Message*>(message, field);
+ if (*result == NULL) {
+ const Message* default_message = DefaultRaw<const Message*>(field);
+ *result = default_message->New();
+ }
+ return *result;
+ }
+}
+
+const Message& GeneratedMessageReflection::GetRepeatedMessage(
+ const Message& message, const FieldDescriptor* field, int index) const {
+ USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
+
+ if (field->is_extension()) {
+ return static_cast<const Message&>(
+ GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
+ } else {
+ return GetRaw<RepeatedPtrFieldBase>(message, field)
+ .Get<GenericTypeHandler<Message> >(index);
+ }
+}
+
+Message* GeneratedMessageReflection::MutableRepeatedMessage(
+ Message* message, const FieldDescriptor* field, int index) const {
+ USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
+
+ if (field->is_extension()) {
+ return static_cast<Message*>(
+ MutableExtensionSet(message)->MutableRepeatedMessage(
+ field->number(), index));
+ } else {
+ return MutableRaw<RepeatedPtrFieldBase>(message, field)
+ ->Mutable<GenericTypeHandler<Message> >(index);
+ }
+}
+
+Message* GeneratedMessageReflection::AddMessage(
+ Message* message, const FieldDescriptor* field,
+ MessageFactory* factory) const {
+ USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
+
+ if (factory == NULL) factory = message_factory_;
+
+ if (field->is_extension()) {
+ return static_cast<Message*>(
+ MutableExtensionSet(message)->AddMessage(field, factory));
+ } else {
+ // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
+ // know how to allocate one.
+ RepeatedPtrFieldBase* repeated =
+ MutableRaw<RepeatedPtrFieldBase>(message, field);
+ Message* result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
+ if (result == NULL) {
+ // We must allocate a new object.
+ const Message* prototype;
+ if (repeated->size() == 0) {
+ prototype = factory->GetPrototype(field->message_type());
+ } else {
+ prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
+ }
+ result = prototype->New();
+ repeated->AddAllocated<GenericTypeHandler<Message> >(result);
+ }
+ return result;
+ }
+}
+
+// -------------------------------------------------------------------
+
+const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
+ const string& name) const {
+ if (extensions_offset_ == -1) return NULL;
+
+ const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
+ if (result != NULL && result->containing_type() == descriptor_) {
+ return result;
+ }
+
+ if (descriptor_->options().message_set_wire_format()) {
+ // MessageSet extensions may be identified by type name.
+ const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
+ if (type != NULL) {
+ // Look for a matching extension in the foreign type's scope.
+ for (int i = 0; i < type->extension_count(); i++) {
+ const FieldDescriptor* extension = type->extension(i);
+ if (extension->containing_type() == descriptor_ &&
+ extension->type() == FieldDescriptor::TYPE_MESSAGE &&
+ extension->is_optional() &&
+ extension->message_type() == type) {
+ // Found it.
+ return extension;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
+ int number) const {
+ if (extensions_offset_ == -1) return NULL;
+ return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
+}
+
+// ===================================================================
+// Some private helpers.
+
+// These simple template accessors obtain pointers (or references) to
+// the given field.
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetRaw(
+ const Message& message, const FieldDescriptor* field) const {
+ const void* ptr = reinterpret_cast<const uint8*>(&message) +
+ offsets_[field->index()];
+ return *reinterpret_cast<const Type*>(ptr);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::MutableRaw(
+ Message* message, const FieldDescriptor* field) const {
+ void* ptr = reinterpret_cast<uint8*>(message) + offsets_[field->index()];
+ return reinterpret_cast<Type*>(ptr);
+}
+
+template <typename Type>
+inline const Type& GeneratedMessageReflection::DefaultRaw(
+ const FieldDescriptor* field) const {
+ const void* ptr = reinterpret_cast<const uint8*>(default_instance_) +
+ offsets_[field->index()];
+ return *reinterpret_cast<const Type*>(ptr);
+}
+
+inline const uint32* GeneratedMessageReflection::GetHasBits(
+ const Message& message) const {
+ const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_;
+ return reinterpret_cast<const uint32*>(ptr);
+}
+inline uint32* GeneratedMessageReflection::MutableHasBits(
+ Message* message) const {
+ void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
+ return reinterpret_cast<uint32*>(ptr);
+}
+
+inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
+ const Message& message) const {
+ GOOGLE_DCHECK_NE(extensions_offset_, -1);
+ const void* ptr = reinterpret_cast<const uint8*>(&message) +
+ extensions_offset_;
+ return *reinterpret_cast<const ExtensionSet*>(ptr);
+}
+inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
+ Message* message) const {
+ GOOGLE_DCHECK_NE(extensions_offset_, -1);
+ void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
+ return reinterpret_cast<ExtensionSet*>(ptr);
+}
+
+// Simple accessors for manipulating has_bits_.
+inline bool GeneratedMessageReflection::HasBit(
+ const Message& message, const FieldDescriptor* field) const {
+ return GetHasBits(message)[field->index() / 32] &
+ (1 << (field->index() % 32));
+}
+
+inline void GeneratedMessageReflection::SetBit(
+ Message* message, const FieldDescriptor* field) const {
+ MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
+}
+
+inline void GeneratedMessageReflection::ClearBit(
+ Message* message, const FieldDescriptor* field) const {
+ MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
+}
+
+// Template implementations of basic accessors. Inline because each
+// template instance is only called from one location. These are
+// used for all types except messages.
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetField(
+ const Message& message, const FieldDescriptor* field) const {
+ return GetRaw<Type>(message, field);
+}
+
+template <typename Type>
+inline void GeneratedMessageReflection::SetField(
+ Message* message, const FieldDescriptor* field, const Type& value) const {
+ *MutableRaw<Type>(message, field) = value;
+ SetBit(message, field);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::MutableField(
+ Message* message, const FieldDescriptor* field) const {
+ SetBit(message, field);
+ return MutableRaw<Type>(message, field);
+}
+
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetRepeatedField(
+ const Message& message, const FieldDescriptor* field, int index) const {
+ return GetRaw<RepeatedField<Type> >(message, field).Get(index);
+}
+
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetRepeatedPtrField(
+ const Message& message, const FieldDescriptor* field, int index) const {
+ return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
+}
+
+template <typename Type>
+inline void GeneratedMessageReflection::SetRepeatedField(
+ Message* message, const FieldDescriptor* field,
+ int index, Type value) const {
+ MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::MutableRepeatedField(
+ Message* message, const FieldDescriptor* field, int index) const {
+ RepeatedPtrField<Type>* repeated =
+ MutableRaw<RepeatedPtrField<Type> >(message, field);
+ return repeated->Mutable(index);
+}
+
+template <typename Type>
+inline void GeneratedMessageReflection::AddField(
+ Message* message, const FieldDescriptor* field, const Type& value) const {
+ MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::AddField(
+ Message* message, const FieldDescriptor* field) const {
+ RepeatedPtrField<Type>* repeated =
+ MutableRaw<RepeatedPtrField<Type> >(message, field);
+ return repeated->Add();
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/generated_message_reflection.h b/src/third_party/protobuf/src/google/protobuf/generated_message_reflection.h
new file mode 100644
index 0000000..b545fa1
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/generated_message_reflection.h
@@ -0,0 +1,424 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/message.h>
+#include <google/protobuf/unknown_field_set.h>
+
+
+namespace google {
+namespace protobuf {
+ class DescriptorPool;
+ // Generated code needs these to have been forward-declared. Easier to do it
+ // here than to print them inside every .pb.h file.
+ class FileDescriptor;
+ class EnumDescriptor;
+}
+
+namespace protobuf {
+namespace internal {
+
+// Defined in this file.
+class GeneratedMessageReflection;
+
+// Defined in other files.
+class ExtensionSet; // extension_set.h
+
+// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use
+// by generated code. This class is just a big hack that reduces code
+// size.
+//
+// A GeneratedMessageReflection is an implementation of Reflection
+// which expects all fields to be backed by simple variables located in
+// memory. The locations are given using a base pointer and a set of
+// offsets.
+//
+// It is required that the user represents fields of each type in a standard
+// way, so that GeneratedMessageReflection can cast the void* pointer to
+// the appropriate type. For primitive fields and string fields, each field
+// should be represented using the obvious C++ primitive type. Enums and
+// Messages are different:
+// - Singular Message fields are stored as a pointer to a Message. These
+// should start out NULL, except for in the default instance where they
+// should start out pointing to other default instances.
+// - Enum fields are stored as an int. This int must always contain
+// a valid value, such that EnumDescriptor::FindValueByNumber() would
+// not return NULL.
+// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
+// of whatever type the individual field would be. Strings and
+// Messages use RepeatedPtrFields while everything else uses
+// RepeatedFields.
+class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
+ public:
+ // Constructs a GeneratedMessageReflection.
+ // Parameters:
+ // descriptor: The descriptor for the message type being implemented.
+ // default_instance: The default instance of the message. This is only
+ // used to obtain pointers to default instances of embedded
+ // messages, which GetMessage() will return if the particular
+ // sub-message has not been initialized yet. (Thus, all
+ // embedded message fields *must* have non-NULL pointers
+ // in the default instance.)
+ // offsets: An array of ints giving the byte offsets, relative to
+ // the start of the message object, of each field. These can
+ // be computed at compile time using the
+ // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
+ // below.
+ // has_bits_offset: Offset in the message of an array of uint32s of size
+ // descriptor->field_count()/32, rounded up. This is a
+ // bitfield where each bit indicates whether or not the
+ // corresponding field of the message has been initialized.
+ // The bit for field index i is obtained by the expression:
+ // has_bits[i / 32] & (1 << (i % 32))
+ // unknown_fields_offset: Offset in the message of the UnknownFieldSet for
+ // the message.
+ // extensions_offset: Offset in the message of the ExtensionSet for the
+ // message, or -1 if the message type has no extension
+ // ranges.
+ // pool: DescriptorPool to search for extension definitions. Only
+ // used by FindKnownExtensionByName() and
+ // FindKnownExtensionByNumber().
+ // factory: MessageFactory to use to construct extension messages.
+ // object_size: The size of a message object of this type, as measured
+ // by sizeof().
+ GeneratedMessageReflection(const Descriptor* descriptor,
+ const Message* default_instance,
+ const int offsets[],
+ int has_bits_offset,
+ int unknown_fields_offset,
+ int extensions_offset,
+ const DescriptorPool* pool,
+ MessageFactory* factory,
+ int object_size);
+ ~GeneratedMessageReflection();
+
+ // implements Reflection -------------------------------------------
+
+ const UnknownFieldSet& GetUnknownFields(const Message& message) const;
+ UnknownFieldSet* MutableUnknownFields(Message* message) const;
+
+ int SpaceUsed(const Message& message) const;
+
+ bool HasField(const Message& message, const FieldDescriptor* field) const;
+ int FieldSize(const Message& message, const FieldDescriptor* field) const;
+ void ClearField(Message* message, const FieldDescriptor* field) const;
+ void RemoveLast(Message* message, const FieldDescriptor* field) const;
+ void Swap(Message* message1, Message* message2) const;
+ void SwapElements(Message* message, const FieldDescriptor* field,
+ int index1, int index2) const;
+ void ListFields(const Message& message,
+ vector<const FieldDescriptor*>* output) const;
+
+ int32 GetInt32 (const Message& message,
+ const FieldDescriptor* field) const;
+ int64 GetInt64 (const Message& message,
+ const FieldDescriptor* field) const;
+ uint32 GetUInt32(const Message& message,
+ const FieldDescriptor* field) const;
+ uint64 GetUInt64(const Message& message,
+ const FieldDescriptor* field) const;
+ float GetFloat (const Message& message,
+ const FieldDescriptor* field) const;
+ double GetDouble(const Message& message,
+ const FieldDescriptor* field) const;
+ bool GetBool (const Message& message,
+ const FieldDescriptor* field) const;
+ string GetString(const Message& message,
+ const FieldDescriptor* field) const;
+ const string& GetStringReference(const Message& message,
+ const FieldDescriptor* field,
+ string* scratch) const;
+ const EnumValueDescriptor* GetEnum(const Message& message,
+ const FieldDescriptor* field) const;
+ const Message& GetMessage(const Message& message,
+ const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const;
+
+ void SetInt32 (Message* message,
+ const FieldDescriptor* field, int32 value) const;
+ void SetInt64 (Message* message,
+ const FieldDescriptor* field, int64 value) const;
+ void SetUInt32(Message* message,
+ const FieldDescriptor* field, uint32 value) const;
+ void SetUInt64(Message* message,
+ const FieldDescriptor* field, uint64 value) const;
+ void SetFloat (Message* message,
+ const FieldDescriptor* field, float value) const;
+ void SetDouble(Message* message,
+ const FieldDescriptor* field, double value) const;
+ void SetBool (Message* message,
+ const FieldDescriptor* field, bool value) const;
+ void SetString(Message* message,
+ const FieldDescriptor* field,
+ const string& value) const;
+ void SetEnum (Message* message, const FieldDescriptor* field,
+ const EnumValueDescriptor* value) const;
+ Message* MutableMessage(Message* message, const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const;
+
+ int32 GetRepeatedInt32 (const Message& message,
+ const FieldDescriptor* field, int index) const;
+ int64 GetRepeatedInt64 (const Message& message,
+ const FieldDescriptor* field, int index) const;
+ uint32 GetRepeatedUInt32(const Message& message,
+ const FieldDescriptor* field, int index) const;
+ uint64 GetRepeatedUInt64(const Message& message,
+ const FieldDescriptor* field, int index) const;
+ float GetRepeatedFloat (const Message& message,
+ const FieldDescriptor* field, int index) const;
+ double GetRepeatedDouble(const Message& message,
+ const FieldDescriptor* field, int index) const;
+ bool GetRepeatedBool (const Message& message,
+ const FieldDescriptor* field, int index) const;
+ string GetRepeatedString(const Message& message,
+ const FieldDescriptor* field, int index) const;
+ const string& GetRepeatedStringReference(const Message& message,
+ const FieldDescriptor* field,
+ int index, string* scratch) const;
+ const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
+ const FieldDescriptor* field,
+ int index) const;
+ const Message& GetRepeatedMessage(const Message& message,
+ const FieldDescriptor* field,
+ int index) const;
+
+ // Set the value of a field.
+ void SetRepeatedInt32 (Message* message,
+ const FieldDescriptor* field, int index, int32 value) const;
+ void SetRepeatedInt64 (Message* message,
+ const FieldDescriptor* field, int index, int64 value) const;
+ void SetRepeatedUInt32(Message* message,
+ const FieldDescriptor* field, int index, uint32 value) const;
+ void SetRepeatedUInt64(Message* message,
+ const FieldDescriptor* field, int index, uint64 value) const;
+ void SetRepeatedFloat (Message* message,
+ const FieldDescriptor* field, int index, float value) const;
+ void SetRepeatedDouble(Message* message,
+ const FieldDescriptor* field, int index, double value) const;
+ void SetRepeatedBool (Message* message,
+ const FieldDescriptor* field, int index, bool value) const;
+ void SetRepeatedString(Message* message,
+ const FieldDescriptor* field, int index,
+ const string& value) const;
+ void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
+ int index, const EnumValueDescriptor* value) const;
+ // Get a mutable pointer to a field with a message type.
+ Message* MutableRepeatedMessage(Message* message,
+ const FieldDescriptor* field,
+ int index) const;
+
+ void AddInt32 (Message* message,
+ const FieldDescriptor* field, int32 value) const;
+ void AddInt64 (Message* message,
+ const FieldDescriptor* field, int64 value) const;
+ void AddUInt32(Message* message,
+ const FieldDescriptor* field, uint32 value) const;
+ void AddUInt64(Message* message,
+ const FieldDescriptor* field, uint64 value) const;
+ void AddFloat (Message* message,
+ const FieldDescriptor* field, float value) const;
+ void AddDouble(Message* message,
+ const FieldDescriptor* field, double value) const;
+ void AddBool (Message* message,
+ const FieldDescriptor* field, bool value) const;
+ void AddString(Message* message,
+ const FieldDescriptor* field, const string& value) const;
+ void AddEnum(Message* message,
+ const FieldDescriptor* field,
+ const EnumValueDescriptor* value) const;
+ Message* AddMessage(Message* message, const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const;
+
+ const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
+ const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
+
+ private:
+ friend class GeneratedMessage;
+
+ const Descriptor* descriptor_;
+ const Message* default_instance_;
+ const int* offsets_;
+
+ int has_bits_offset_;
+ int unknown_fields_offset_;
+ int extensions_offset_;
+ int object_size_;
+
+ const DescriptorPool* descriptor_pool_;
+ MessageFactory* message_factory_;
+
+ template <typename Type>
+ inline const Type& GetRaw(const Message& message,
+ const FieldDescriptor* field) const;
+ template <typename Type>
+ inline Type* MutableRaw(Message* message,
+ const FieldDescriptor* field) const;
+ template <typename Type>
+ inline const Type& DefaultRaw(const FieldDescriptor* field) const;
+ inline const Message* GetMessagePrototype(const FieldDescriptor* field) const;
+
+ inline const uint32* GetHasBits(const Message& message) const;
+ inline uint32* MutableHasBits(Message* message) const;
+ inline const ExtensionSet& GetExtensionSet(const Message& message) const;
+ inline ExtensionSet* MutableExtensionSet(Message* message) const;
+
+ inline bool HasBit(const Message& message,
+ const FieldDescriptor* field) const;
+ inline void SetBit(Message* message,
+ const FieldDescriptor* field) const;
+ inline void ClearBit(Message* message,
+ const FieldDescriptor* field) const;
+
+ template <typename Type>
+ inline const Type& GetField(const Message& message,
+ const FieldDescriptor* field) const;
+ template <typename Type>
+ inline void SetField(Message* message,
+ const FieldDescriptor* field, const Type& value) const;
+ template <typename Type>
+ inline Type* MutableField(Message* message,
+ const FieldDescriptor* field) const;
+ template <typename Type>
+ inline const Type& GetRepeatedField(const Message& message,
+ const FieldDescriptor* field,
+ int index) const;
+ template <typename Type>
+ inline const Type& GetRepeatedPtrField(const Message& message,
+ const FieldDescriptor* field,
+ int index) const;
+ template <typename Type>
+ inline void SetRepeatedField(Message* message,
+ const FieldDescriptor* field, int index,
+ Type value) const;
+ template <typename Type>
+ inline Type* MutableRepeatedField(Message* message,
+ const FieldDescriptor* field,
+ int index) const;
+ template <typename Type>
+ inline void AddField(Message* message,
+ const FieldDescriptor* field, const Type& value) const;
+ template <typename Type>
+ inline Type* AddField(Message* message,
+ const FieldDescriptor* field) const;
+
+ int GetExtensionNumberOrDie(const Descriptor* type) const;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
+};
+
+// Returns the offset of the given field within the given aggregate type.
+// This is equivalent to the ANSI C offsetof() macro. However, according
+// to the C++ standard, offsetof() only works on POD types, and GCC
+// enforces this requirement with a warning. In practice, this rule is
+// unnecessarily strict; there is probably no compiler or platform on
+// which the offsets of the direct fields of a class are non-constant.
+// Fields inherited from superclasses *can* have non-constant offsets,
+// but that's not what this macro will be used for.
+//
+// Note that we calculate relative to the pointer value 16 here since if we
+// just use zero, GCC complains about dereferencing a NULL pointer. We
+// choose 16 rather than some other number just in case the compiler would
+// be confused by an unaligned pointer.
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
+ static_cast<int>( \
+ reinterpret_cast<const char*>( \
+ &reinterpret_cast<const TYPE*>(16)->FIELD) - \
+ reinterpret_cast<const char*>(16))
+
+// There are some places in proto2 where dynamic_cast would be useful as an
+// optimization. For example, take Message::MergeFrom(const Message& other).
+// For a given generated message FooMessage, we generate these two methods:
+// void MergeFrom(const FooMessage& other);
+// void MergeFrom(const Message& other);
+// The former method can be implemented directly in terms of FooMessage's
+// inline accessors, but the latter method must work with the reflection
+// interface. However, if the parameter to the latter method is actually of
+// type FooMessage, then we'd like to be able to just call the other method
+// as an optimization. So, we use dynamic_cast to check this.
+//
+// That said, dynamic_cast requires RTTI, which many people like to disable
+// for performance and code size reasons. When RTTI is not available, we
+// still need to produce correct results. So, in this case we have to fall
+// back to using reflection, which is what we would have done anyway if the
+// objects were not of the exact same class.
+//
+// dynamic_cast_if_available() implements this logic. If RTTI is
+// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns
+// NULL.
+//
+// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
+// On MSVC, this should be detected automatically.
+template<typename To, typename From>
+inline To dynamic_cast_if_available(From from) {
+#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
+ return NULL;
+#else
+ return dynamic_cast<To>(from);
+#endif
+}
+
+// Helper for EnumType_Parse functions: try to parse the string 'name' as an
+// enum name of the given type, returning true and filling in value on success,
+// or returning false and leaving value unchanged on failure.
+LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
+ const string& name,
+ int* value);
+
+template<typename EnumType>
+bool ParseNamedEnum(const EnumDescriptor* descriptor,
+ const string& name,
+ EnumType* value) {
+ int tmp;
+ if (!ParseNamedEnum(descriptor, name, &tmp)) return false;
+ *value = static_cast<EnumType>(tmp);
+ return true;
+}
+
+// Just a wrapper around printing the name of a value. The main point of this
+// function is not to be inlined, so that you can do this without including
+// descriptor.h.
+LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value);
+
+} // namespace internal
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/generated_message_reflection_unittest.cc b/src/third_party/protobuf/src/google/protobuf/generated_message_reflection_unittest.cc
new file mode 100644
index 0000000..a03bcdb
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -0,0 +1,384 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// To test GeneratedMessageReflection, we actually let the protocol compiler
+// generate a full protocol message implementation and then test its
+// reflection interface. This is much easier and more maintainable than
+// trying to create our own Message class for GeneratedMessageReflection
+// to wrap.
+//
+// The tests here closely mirror some of the tests in
+// compiler/cpp/unittest, except using the reflection interface
+// rather than generated accessors.
+
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/unittest.pb.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+const FieldDescriptor* F(const string& name) {
+ const FieldDescriptor* result =
+ unittest::TestAllTypes::descriptor()->FindFieldByName(name);
+ GOOGLE_CHECK(result != NULL);
+ return result;
+}
+
+TEST(GeneratedMessageReflectionTest, Defaults) {
+ // Check that all default values are set correctly in the initial message.
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ reflection_tester.ExpectClearViaReflection(message);
+
+ const Reflection* reflection = message.GetReflection();
+
+ // Messages should return pointers to default instances until first use.
+ // (This is not checked by ExpectClear() since it is not actually true after
+ // the fields have been set and then cleared.)
+ EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+ &reflection->GetMessage(message, F("optionalgroup")));
+ EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_nested_message")));
+ EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_foreign_message")));
+ EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_import_message")));
+}
+
+TEST(GeneratedMessageReflectionTest, Accessors) {
+ // Set every field to a unique value then go back and check all those
+ // values.
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ reflection_tester.SetAllFieldsViaReflection(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+ reflection_tester.ExpectAllFieldsSetViaReflection(message);
+
+ reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
+ TestUtil::ExpectRepeatedFieldsModified(message);
+}
+
+TEST(GeneratedMessageReflectionTest, GetStringReference) {
+ // Test that GetStringReference() returns the underlying string when it is
+ // a normal string field.
+ unittest::TestAllTypes message;
+ message.set_optional_string("foo");
+ message.add_repeated_string("foo");
+
+ const Reflection* reflection = message.GetReflection();
+ string scratch;
+
+ EXPECT_EQ(&message.optional_string(),
+ &reflection->GetStringReference(message, F("optional_string"), &scratch))
+ << "For simple string fields, GetStringReference() should return a "
+ "reference to the underlying string.";
+ EXPECT_EQ(&message.repeated_string(0),
+ &reflection->GetRepeatedStringReference(message, F("repeated_string"),
+ 0, &scratch))
+ << "For simple string fields, GetRepeatedStringReference() should return "
+ "a reference to the underlying string.";
+}
+
+
+TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) {
+ // Check that after setting all fields and then clearing, getting an
+ // embedded message does NOT return the default instance.
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ TestUtil::SetAllFields(&message);
+ message.Clear();
+
+ const Reflection* reflection = message.GetReflection();
+
+ EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+ &reflection->GetMessage(message, F("optionalgroup")));
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_nested_message")));
+ EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_foreign_message")));
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &reflection->GetMessage(message, F("optional_import_message")));
+}
+
+
+TEST(GeneratedMessageReflectionTest, Swap) {
+ unittest::TestAllTypes message1;
+ unittest::TestAllTypes message2;
+
+ TestUtil::SetAllFields(&message1);
+
+ const Reflection* reflection = message1.GetReflection();
+ reflection->Swap(&message1, &message2);
+
+ TestUtil::ExpectClear(message1);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapWithBothSet) {
+ unittest::TestAllTypes message1;
+ unittest::TestAllTypes message2;
+
+ TestUtil::SetAllFields(&message1);
+ TestUtil::SetAllFields(&message2);
+ TestUtil::ModifyRepeatedFields(&message2);
+
+ const Reflection* reflection = message1.GetReflection();
+ reflection->Swap(&message1, &message2);
+
+ TestUtil::ExpectRepeatedFieldsModified(message1);
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ message1.set_optional_int32(532819);
+
+ reflection->Swap(&message1, &message2);
+
+ EXPECT_EQ(532819, message2.optional_int32());
+}
+
+TEST(GeneratedMessageReflectionTest, SwapExtensions) {
+ unittest::TestAllExtensions message1;
+ unittest::TestAllExtensions message2;
+
+ TestUtil::SetAllExtensions(&message1);
+
+ const Reflection* reflection = message1.GetReflection();
+ reflection->Swap(&message1, &message2);
+
+ TestUtil::ExpectExtensionsClear(message1);
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapUnknown) {
+ unittest::TestEmptyMessage message1, message2;
+
+ message1.mutable_unknown_fields()->AddVarint(1234, 1);
+
+ EXPECT_EQ(1, message1.unknown_fields().field_count());
+ EXPECT_EQ(0, message2.unknown_fields().field_count());
+ const Reflection* reflection = message1.GetReflection();
+ reflection->Swap(&message1, &message2);
+ EXPECT_EQ(0, message1.unknown_fields().field_count());
+ EXPECT_EQ(1, message2.unknown_fields().field_count());
+}
+
+TEST(GeneratedMessageReflectionTest, RemoveLast) {
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ TestUtil::SetAllFields(&message);
+
+ reflection_tester.RemoveLastRepeatedsViaReflection(&message);
+
+ TestUtil::ExpectLastRepeatedsRemoved(message);
+}
+
+TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) {
+ unittest::TestAllExtensions message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ TestUtil::SetAllExtensions(&message);
+ reflection_tester.RemoveLastRepeatedsViaReflection(&message);
+
+ TestUtil::ExpectLastRepeatedExtensionsRemoved(message);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) {
+ unittest::TestAllTypes message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllTypes::descriptor());
+
+ TestUtil::SetAllFields(&message);
+
+ // Swap and test that fields are all swapped.
+ reflection_tester.SwapRepeatedsViaReflection(&message);
+ TestUtil::ExpectRepeatedsSwapped(message);
+
+ // Swap back and test that fields are all back to original values.
+ reflection_tester.SwapRepeatedsViaReflection(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) {
+ unittest::TestAllExtensions message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ TestUtil::SetAllExtensions(&message);
+
+ // Swap and test that fields are all swapped.
+ reflection_tester.SwapRepeatedsViaReflection(&message);
+ TestUtil::ExpectRepeatedExtensionsSwapped(message);
+
+ // Swap back and test that fields are all back to original values.
+ reflection_tester.SwapRepeatedsViaReflection(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, Extensions) {
+ // Set every extension to a unique value then go back and check all those
+ // values.
+ unittest::TestAllExtensions message;
+ TestUtil::ReflectionTester reflection_tester(
+ unittest::TestAllExtensions::descriptor());
+
+ reflection_tester.SetAllFieldsViaReflection(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+ reflection_tester.ExpectAllFieldsSetViaReflection(message);
+
+ reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
+ TestUtil::ExpectRepeatedExtensionsModified(message);
+}
+
+TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
+ const Reflection* reflection =
+ unittest::TestAllExtensions::default_instance().GetReflection();
+
+ const FieldDescriptor* extension1 =
+ unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+ "optional_int32_extension");
+ const FieldDescriptor* extension2 =
+ unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+ "repeated_string_extension");
+
+ EXPECT_EQ(extension1,
+ reflection->FindKnownExtensionByNumber(extension1->number()));
+ EXPECT_EQ(extension2,
+ reflection->FindKnownExtensionByNumber(extension2->number()));
+
+ // Non-existent extension.
+ EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL);
+
+ // Extensions of TestAllExtensions should not show up as extensions of
+ // other types.
+ EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()->
+ FindKnownExtensionByNumber(extension1->number()) == NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
+ const Reflection* reflection =
+ unittest::TestAllExtensions::default_instance().GetReflection();
+
+ const FieldDescriptor* extension1 =
+ unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+ "optional_int32_extension");
+ const FieldDescriptor* extension2 =
+ unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
+ "repeated_string_extension");
+
+ EXPECT_EQ(extension1,
+ reflection->FindKnownExtensionByName(extension1->full_name()));
+ EXPECT_EQ(extension2,
+ reflection->FindKnownExtensionByName(extension2->full_name()));
+
+ // Non-existent extension.
+ EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL);
+
+ // Extensions of TestAllExtensions should not show up as extensions of
+ // other types.
+ EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()->
+ FindKnownExtensionByName(extension1->full_name()) == NULL);
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(GeneratedMessageReflectionTest, UsageErrors) {
+ unittest::TestAllTypes message;
+ const Reflection* reflection = message.GetReflection();
+ const Descriptor* descriptor = message.GetDescriptor();
+
+#define f(NAME) descriptor->FindFieldByName(NAME)
+
+ // Testing every single failure mode would be too much work. Let's just
+ // check a few.
+ EXPECT_DEATH(
+ reflection->GetInt32(
+ message, descriptor->FindFieldByName("optional_int64")),
+ "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::GetInt32\n"
+ " Message type: protobuf_unittest\\.TestAllTypes\n"
+ " Field : protobuf_unittest\\.TestAllTypes\\.optional_int64\n"
+ " Problem : Field is not the right type for this message:\n"
+ " Expected : CPPTYPE_INT32\n"
+ " Field type: CPPTYPE_INT64");
+ EXPECT_DEATH(
+ reflection->GetInt32(
+ message, descriptor->FindFieldByName("repeated_int32")),
+ "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::GetInt32\n"
+ " Message type: protobuf_unittest.TestAllTypes\n"
+ " Field : protobuf_unittest.TestAllTypes.repeated_int32\n"
+ " Problem : Field is repeated; the method requires a singular field.");
+ EXPECT_DEATH(
+ reflection->GetInt32(
+ message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
+ "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::GetInt32\n"
+ " Message type: protobuf_unittest.TestAllTypes\n"
+ " Field : protobuf_unittest.ForeignMessage.c\n"
+ " Problem : Field does not match message type.");
+ EXPECT_DEATH(
+ reflection->HasField(
+ message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
+ "Protocol Buffer reflection usage error:\n"
+ " Method : google::protobuf::Reflection::HasField\n"
+ " Message type: protobuf_unittest.TestAllTypes\n"
+ " Field : protobuf_unittest.ForeignMessage.c\n"
+ " Problem : Field does not match message type.");
+
+#undef f
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/generated_message_util.cc b/src/third_party/protobuf/src/google/protobuf/generated_message_util.cc
new file mode 100644
index 0000000..76e547b
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/generated_message_util.cc
@@ -0,0 +1,55 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/generated_message_util.h>
+
+#include <limits>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+double Infinity() {
+ return std::numeric_limits<double>::infinity();
+}
+double NaN() {
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+const ::std::string kEmptyString;
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/generated_message_util.h b/src/third_party/protobuf/src/google/protobuf/generated_message_util.h
new file mode 100644
index 0000000..77ae106
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/generated_message_util.h
@@ -0,0 +1,82 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains miscellaneous helper code used by generated code --
+// including lite types -- but which should not be used directly by users.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class CodedInputStream; // coded_stream.h
+ }
+}
+
+namespace protobuf {
+namespace internal {
+
+// Annotation for the compiler to emit a deprecation message if a field marked
+// with option 'deprecated=true' is used in the code, or for other things in
+// generated code which are deprecated.
+//
+// For internal use in the pb.cc files, deprecation warnings are suppressed
+// there.
+#undef DEPRECATED_PROTOBUF_FIELD
+#if !defined(INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION)
+# define PROTOBUF_DEPRECATED GOOGLE_ATTRIBUTE_DEPRECATED
+#else
+# define PROTOBUF_DEPRECATED
+#endif
+
+
+// Constants for special floating point values.
+LIBPROTOBUF_EXPORT double Infinity();
+LIBPROTOBUF_EXPORT double NaN();
+
+// Constant used for empty default strings.
+LIBPROTOBUF_EXPORT extern const ::std::string kEmptyString;
+
+
+} // namespace internal
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/coded_stream.cc b/src/third_party/protobuf/src/google/protobuf/io/coded_stream.cc
new file mode 100644
index 0000000..402a3ad
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/coded_stream.cc
@@ -0,0 +1,839 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This implementation is heavily optimized to make reads and writes
+// of small values (especially varints) as fast as possible. In
+// particular, we optimize for the common case that a read or a write
+// will not cross the end of the buffer, since we can avoid a lot
+// of branching in this case.
+
+#include <google/protobuf/io/coded_stream_inl.h>
+#include <algorithm>
+#include <limits.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+namespace {
+
+static const int kMaxVarintBytes = 10;
+static const int kMaxVarint32Bytes = 5;
+
+
+inline bool NextNonEmpty(ZeroCopyInputStream* input,
+ const void** data, int* size) {
+ bool success;
+ do {
+ success = input->Next(data, size);
+ } while (success && *size == 0);
+ return success;
+}
+
+} // namespace
+
+// CodedInputStream ==================================================
+
+
+void CodedInputStream::BackUpInputToCurrentPosition() {
+ int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
+ if (backup_bytes > 0) {
+ input_->BackUp(backup_bytes);
+
+ // total_bytes_read_ doesn't include overflow_bytes_.
+ total_bytes_read_ -= BufferSize() + buffer_size_after_limit_;
+ buffer_end_ = buffer_;
+ buffer_size_after_limit_ = 0;
+ overflow_bytes_ = 0;
+ }
+}
+
+inline void CodedInputStream::RecomputeBufferLimits() {
+ buffer_end_ += buffer_size_after_limit_;
+ int closest_limit = min(current_limit_, total_bytes_limit_);
+ if (closest_limit < total_bytes_read_) {
+ // The limit position is in the current buffer. We must adjust
+ // the buffer size accordingly.
+ buffer_size_after_limit_ = total_bytes_read_ - closest_limit;
+ buffer_end_ -= buffer_size_after_limit_;
+ } else {
+ buffer_size_after_limit_ = 0;
+ }
+}
+
+CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
+ // Current position relative to the beginning of the stream.
+ int current_position = total_bytes_read_ -
+ (BufferSize() + buffer_size_after_limit_);
+
+ Limit old_limit = current_limit_;
+
+ // security: byte_limit is possibly evil, so check for negative values
+ // and overflow.
+ if (byte_limit >= 0 &&
+ byte_limit <= INT_MAX - current_position) {
+ current_limit_ = current_position + byte_limit;
+ } else {
+ // Negative or overflow.
+ current_limit_ = INT_MAX;
+ }
+
+ // We need to enforce all limits, not just the new one, so if the previous
+ // limit was before the new requested limit, we continue to enforce the
+ // previous limit.
+ current_limit_ = min(current_limit_, old_limit);
+
+ RecomputeBufferLimits();
+ return old_limit;
+}
+
+void CodedInputStream::PopLimit(Limit limit) {
+ // The limit passed in is actually the *old* limit, which we returned from
+ // PushLimit().
+ current_limit_ = limit;
+ RecomputeBufferLimits();
+
+ // We may no longer be at a legitimate message end. ReadTag() needs to be
+ // called again to find out.
+ legitimate_message_end_ = false;
+}
+
+int CodedInputStream::BytesUntilLimit() {
+ if (current_limit_ == INT_MAX) return -1;
+ int current_position = total_bytes_read_ -
+ (BufferSize() + buffer_size_after_limit_);
+
+ return current_limit_ - current_position;
+}
+
+void CodedInputStream::SetTotalBytesLimit(
+ int total_bytes_limit, int warning_threshold) {
+ // Make sure the limit isn't already past, since this could confuse other
+ // code.
+ int current_position = total_bytes_read_ -
+ (BufferSize() + buffer_size_after_limit_);
+ total_bytes_limit_ = max(current_position, total_bytes_limit);
+ total_bytes_warning_threshold_ = warning_threshold;
+ RecomputeBufferLimits();
+}
+
+void CodedInputStream::PrintTotalBytesLimitError() {
+ GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
+ "big (more than " << total_bytes_limit_
+ << " bytes). To increase the limit (or to disable these "
+ "warnings), see CodedInputStream::SetTotalBytesLimit() "
+ "in google/protobuf/io/coded_stream.h.";
+}
+
+bool CodedInputStream::Skip(int count) {
+ if (count < 0) return false; // security: count is often user-supplied
+
+ const int original_buffer_size = BufferSize();
+
+ if (count <= original_buffer_size) {
+ // Just skipping within the current buffer. Easy.
+ Advance(count);
+ return true;
+ }
+
+ if (buffer_size_after_limit_ > 0) {
+ // We hit a limit inside this buffer. Advance to the limit and fail.
+ Advance(original_buffer_size);
+ return false;
+ }
+
+ count -= original_buffer_size;
+ buffer_ = NULL;
+ buffer_end_ = buffer_;
+
+ // Make sure this skip doesn't try to skip past the current limit.
+ int closest_limit = min(current_limit_, total_bytes_limit_);
+ int bytes_until_limit = closest_limit - total_bytes_read_;
+ if (bytes_until_limit < count) {
+ // We hit the limit. Skip up to it then fail.
+ if (bytes_until_limit > 0) {
+ total_bytes_read_ = closest_limit;
+ input_->Skip(bytes_until_limit);
+ }
+ return false;
+ }
+
+ total_bytes_read_ += count;
+ return input_->Skip(count);
+}
+
+bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
+ if (BufferSize() == 0 && !Refresh()) return false;
+
+ *data = buffer_;
+ *size = BufferSize();
+ return true;
+}
+
+bool CodedInputStream::ReadRaw(void* buffer, int size) {
+ int current_buffer_size;
+ while ((current_buffer_size = BufferSize()) < size) {
+ // Reading past end of buffer. Copy what we have, then refresh.
+ memcpy(buffer, buffer_, current_buffer_size);
+ buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size;
+ size -= current_buffer_size;
+ Advance(current_buffer_size);
+ if (!Refresh()) return false;
+ }
+
+ memcpy(buffer, buffer_, size);
+ Advance(size);
+
+ return true;
+}
+
+bool CodedInputStream::ReadString(string* buffer, int size) {
+ if (size < 0) return false; // security: size is often user-supplied
+ return InternalReadStringInline(buffer, size);
+}
+
+bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
+ if (!buffer->empty()) {
+ buffer->clear();
+ }
+
+ int current_buffer_size;
+ while ((current_buffer_size = BufferSize()) < size) {
+ // Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
+ if (current_buffer_size != 0) {
+ // Note: string1.append(string2) is O(string2.size()) (as opposed to
+ // O(string1.size() + string2.size()), which would be bad).
+ buffer->append(reinterpret_cast<const char*>(buffer_),
+ current_buffer_size);
+ }
+ size -= current_buffer_size;
+ Advance(current_buffer_size);
+ if (!Refresh()) return false;
+ }
+
+ buffer->append(reinterpret_cast<const char*>(buffer_), size);
+ Advance(size);
+
+ return true;
+}
+
+
+bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) {
+ uint8 bytes[sizeof(*value)];
+
+ const uint8* ptr;
+ if (BufferSize() >= sizeof(*value)) {
+ // Fast path: Enough bytes in the buffer to read directly.
+ ptr = buffer_;
+ Advance(sizeof(*value));
+ } else {
+ // Slow path: Had to read past the end of the buffer.
+ if (!ReadRaw(bytes, sizeof(*value))) return false;
+ ptr = bytes;
+ }
+ ReadLittleEndian32FromArray(ptr, value);
+ return true;
+}
+
+bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
+ uint8 bytes[sizeof(*value)];
+
+ const uint8* ptr;
+ if (BufferSize() >= sizeof(*value)) {
+ // Fast path: Enough bytes in the buffer to read directly.
+ ptr = buffer_;
+ Advance(sizeof(*value));
+ } else {
+ // Slow path: Had to read past the end of the buffer.
+ if (!ReadRaw(bytes, sizeof(*value))) return false;
+ ptr = bytes;
+ }
+ ReadLittleEndian64FromArray(ptr, value);
+ return true;
+}
+
+namespace {
+
+inline const uint8* ReadVarint32FromArray(
+ const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) {
+ // Fast path: We have enough bytes left in the buffer to guarantee that
+ // this read won't cross the end, so we can skip the checks.
+ const uint8* ptr = buffer;
+ uint32 b;
+ uint32 result;
+
+ b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+ b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done;
+
+ // If the input is larger than 32 bits, we still need to read it all
+ // and discard the high-order bits.
+ for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
+ b = *(ptr++); if (!(b & 0x80)) goto done;
+ }
+
+ // We have overrun the maximum size of a varint (10 bytes). Assume
+ // the data is corrupt.
+ return NULL;
+
+ done:
+ *value = result;
+ return ptr;
+}
+
+} // namespace
+
+bool CodedInputStream::ReadVarint32Slow(uint32* value) {
+ uint64 result;
+ // Directly invoke ReadVarint64Fallback, since we already tried to optimize
+ // for one-byte varints.
+ if (!ReadVarint64Fallback(&result)) return false;
+ *value = (uint32)result;
+ return true;
+}
+
+bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
+ if (BufferSize() >= kMaxVarintBytes ||
+ // Optimization: If the varint ends at exactly the end of the buffer,
+ // we can detect that and still use the fast path.
+ (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
+ const uint8* end = ReadVarint32FromArray(buffer_, value);
+ if (end == NULL) return false;
+ buffer_ = end;
+ return true;
+ } else {
+ // Really slow case: we will incur the cost of an extra function call here,
+ // but moving this out of line reduces the size of this function, which
+ // improves the common case. In micro benchmarks, this is worth about 10-15%
+ return ReadVarint32Slow(value);
+ }
+}
+
+uint32 CodedInputStream::ReadTagSlow() {
+ if (buffer_ == buffer_end_) {
+ // Call refresh.
+ if (!Refresh()) {
+ // Refresh failed. Make sure that it failed due to EOF, not because
+ // we hit total_bytes_limit_, which, unlike normal limits, is not a
+ // valid place to end a message.
+ int current_position = total_bytes_read_ - buffer_size_after_limit_;
+ if (current_position >= total_bytes_limit_) {
+ // Hit total_bytes_limit_. But if we also hit the normal limit,
+ // we're still OK.
+ legitimate_message_end_ = current_limit_ == total_bytes_limit_;
+ } else {
+ legitimate_message_end_ = true;
+ }
+ return 0;
+ }
+ }
+
+ // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
+ // again, since we have now refreshed the buffer.
+ uint64 result;
+ if (!ReadVarint64(&result)) return 0;
+ return static_cast<uint32>(result);
+}
+
+uint32 CodedInputStream::ReadTagFallback() {
+ if (BufferSize() >= kMaxVarintBytes ||
+ // Optimization: If the varint ends at exactly the end of the buffer,
+ // we can detect that and still use the fast path.
+ (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
+ uint32 tag;
+ const uint8* end = ReadVarint32FromArray(buffer_, &tag);
+ if (end == NULL) {
+ return 0;
+ }
+ buffer_ = end;
+ return tag;
+ } else {
+ // We are commonly at a limit when attempting to read tags. Try to quickly
+ // detect this case without making another function call.
+ if (buffer_ == buffer_end_ && buffer_size_after_limit_ > 0 &&
+ // Make sure that the limit we hit is not total_bytes_limit_, since
+ // in that case we still need to call Refresh() so that it prints an
+ // error.
+ total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) {
+ // We hit a byte limit.
+ legitimate_message_end_ = true;
+ return 0;
+ }
+ return ReadTagSlow();
+ }
+}
+
+bool CodedInputStream::ReadVarint64Slow(uint64* value) {
+ // Slow path: This read might cross the end of the buffer, so we
+ // need to check and refresh the buffer if and when it does.
+
+ uint64 result = 0;
+ int count = 0;
+ uint32 b;
+
+ do {
+ if (count == kMaxVarintBytes) return false;
+ while (buffer_ == buffer_end_) {
+ if (!Refresh()) return false;
+ }
+ b = *buffer_;
+ result |= static_cast<uint64>(b & 0x7F) << (7 * count);
+ Advance(1);
+ ++count;
+ } while (b & 0x80);
+
+ *value = result;
+ return true;
+}
+
+bool CodedInputStream::ReadVarint64Fallback(uint64* value) {
+ if (BufferSize() >= kMaxVarintBytes ||
+ // Optimization: If the varint ends at exactly the end of the buffer,
+ // we can detect that and still use the fast path.
+ (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
+ // Fast path: We have enough bytes left in the buffer to guarantee that
+ // this read won't cross the end, so we can skip the checks.
+
+ const uint8* ptr = buffer_;
+ uint32 b;
+
+ // Splitting into 32-bit pieces gives better performance on 32-bit
+ // processors.
+ uint32 part0 = 0, part1 = 0, part2 = 0;
+
+ b = *(ptr++); part0 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part0 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part1 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part1 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part2 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
+ b = *(ptr++); part2 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
+
+ // We have overrun the maximum size of a varint (10 bytes). The data
+ // must be corrupt.
+ return false;
+
+ done:
+ Advance(ptr - buffer_);
+ *value = (static_cast<uint64>(part0) ) |
+ (static_cast<uint64>(part1) << 28) |
+ (static_cast<uint64>(part2) << 56);
+ return true;
+ } else {
+ return ReadVarint64Slow(value);
+ }
+}
+
+bool CodedInputStream::Refresh() {
+ GOOGLE_DCHECK_EQ(0, BufferSize());
+
+ if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
+ total_bytes_read_ == current_limit_) {
+ // We've hit a limit. Stop.
+ int current_position = total_bytes_read_ - buffer_size_after_limit_;
+
+ if (current_position >= total_bytes_limit_ &&
+ total_bytes_limit_ != current_limit_) {
+ // Hit total_bytes_limit_.
+ PrintTotalBytesLimitError();
+ }
+
+ return false;
+ }
+
+ if (total_bytes_warning_threshold_ >= 0 &&
+ total_bytes_read_ >= total_bytes_warning_threshold_) {
+ GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message. If the "
+ "message turns out to be larger than "
+ << total_bytes_limit_ << " bytes, parsing will be halted "
+ "for security reasons. To increase the limit (or to "
+ "disable these warnings), see "
+ "CodedInputStream::SetTotalBytesLimit() in "
+ "google/protobuf/io/coded_stream.h.";
+
+ // Don't warn again for this stream.
+ total_bytes_warning_threshold_ = -1;
+ }
+
+ const void* void_buffer;
+ int buffer_size;
+ if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
+ buffer_ = reinterpret_cast<const uint8*>(void_buffer);
+ buffer_end_ = buffer_ + buffer_size;
+ GOOGLE_CHECK_GE(buffer_size, 0);
+
+ if (total_bytes_read_ <= INT_MAX - buffer_size) {
+ total_bytes_read_ += buffer_size;
+ } else {
+ // Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX.
+ // We can't get that far anyway, because total_bytes_limit_ is guaranteed
+ // to be less than it. We need to keep track of the number of bytes
+ // we discarded, though, so that we can call input_->BackUp() to back
+ // up over them on destruction.
+
+ // The following line is equivalent to:
+ // overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX;
+ // except that it avoids overflows. Signed integer overflow has
+ // undefined results according to the C standard.
+ overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size);
+ buffer_end_ -= overflow_bytes_;
+ total_bytes_read_ = INT_MAX;
+ }
+
+ RecomputeBufferLimits();
+ return true;
+ } else {
+ buffer_ = NULL;
+ buffer_end_ = NULL;
+ return false;
+ }
+}
+
+// CodedOutputStream =================================================
+
+CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
+ : output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ total_bytes_(0),
+ had_error_(false) {
+ // Eagerly Refresh() so buffer space is immediately available.
+ Refresh();
+ // The Refresh() may have failed. If the client doesn't write any data,
+ // though, don't consider this an error. If the client does write data, then
+ // another Refresh() will be attempted and it will set the error once again.
+ had_error_ = false;
+}
+
+CodedOutputStream::~CodedOutputStream() {
+ if (buffer_size_ > 0) {
+ output_->BackUp(buffer_size_);
+ }
+}
+
+bool CodedOutputStream::Skip(int count) {
+ if (count < 0) return false;
+
+ while (count > buffer_size_) {
+ count -= buffer_size_;
+ if (!Refresh()) return false;
+ }
+
+ Advance(count);
+ return true;
+}
+
+bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
+ if (buffer_size_ == 0 && !Refresh()) return false;
+
+ *data = buffer_;
+ *size = buffer_size_;
+ return true;
+}
+
+void CodedOutputStream::WriteRaw(const void* data, int size) {
+ while (buffer_size_ < size) {
+ memcpy(buffer_, data, buffer_size_);
+ size -= buffer_size_;
+ data = reinterpret_cast<const uint8*>(data) + buffer_size_;
+ if (!Refresh()) return;
+ }
+
+ memcpy(buffer_, data, size);
+ Advance(size);
+}
+
+uint8* CodedOutputStream::WriteRawToArray(
+ const void* data, int size, uint8* target) {
+ memcpy(target, data, size);
+ return target + size;
+}
+
+
+void CodedOutputStream::WriteLittleEndian32(uint32 value) {
+ uint8 bytes[sizeof(value)];
+
+ bool use_fast = buffer_size_ >= sizeof(value);
+ uint8* ptr = use_fast ? buffer_ : bytes;
+
+ WriteLittleEndian32ToArray(value, ptr);
+
+ if (use_fast) {
+ Advance(sizeof(value));
+ } else {
+ WriteRaw(bytes, sizeof(value));
+ }
+}
+
+void CodedOutputStream::WriteLittleEndian64(uint64 value) {
+ uint8 bytes[sizeof(value)];
+
+ bool use_fast = buffer_size_ >= sizeof(value);
+ uint8* ptr = use_fast ? buffer_ : bytes;
+
+ WriteLittleEndian64ToArray(value, ptr);
+
+ if (use_fast) {
+ Advance(sizeof(value));
+ } else {
+ WriteRaw(bytes, sizeof(value));
+ }
+}
+
+inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
+ uint32 value, uint8* target) {
+ target[0] = static_cast<uint8>(value | 0x80);
+ if (value >= (1 << 7)) {
+ target[1] = static_cast<uint8>((value >> 7) | 0x80);
+ if (value >= (1 << 14)) {
+ target[2] = static_cast<uint8>((value >> 14) | 0x80);
+ if (value >= (1 << 21)) {
+ target[3] = static_cast<uint8>((value >> 21) | 0x80);
+ if (value >= (1 << 28)) {
+ target[4] = static_cast<uint8>(value >> 28);
+ return target + 5;
+ } else {
+ target[3] &= 0x7F;
+ return target + 4;
+ }
+ } else {
+ target[2] &= 0x7F;
+ return target + 3;
+ }
+ } else {
+ target[1] &= 0x7F;
+ return target + 2;
+ }
+ } else {
+ target[0] &= 0x7F;
+ return target + 1;
+ }
+}
+
+void CodedOutputStream::WriteVarint32(uint32 value) {
+ if (buffer_size_ >= kMaxVarint32Bytes) {
+ // Fast path: We have enough bytes left in the buffer to guarantee that
+ // this write won't cross the end, so we can skip the checks.
+ uint8* target = buffer_;
+ uint8* end = WriteVarint32FallbackToArrayInline(value, target);
+ int size = end - target;
+ Advance(size);
+ } else {
+ // Slow path: This write might cross the end of the buffer, so we
+ // compose the bytes first then use WriteRaw().
+ uint8 bytes[kMaxVarint32Bytes];
+ int size = 0;
+ while (value > 0x7F) {
+ bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
+ value >>= 7;
+ }
+ bytes[size++] = static_cast<uint8>(value) & 0x7F;
+ WriteRaw(bytes, size);
+ }
+}
+
+uint8* CodedOutputStream::WriteVarint32FallbackToArray(
+ uint32 value, uint8* target) {
+ return WriteVarint32FallbackToArrayInline(value, target);
+}
+
+inline uint8* CodedOutputStream::WriteVarint64ToArrayInline(
+ uint64 value, uint8* target) {
+ // Splitting into 32-bit pieces gives better performance on 32-bit
+ // processors.
+ uint32 part0 = static_cast<uint32>(value );
+ uint32 part1 = static_cast<uint32>(value >> 28);
+ uint32 part2 = static_cast<uint32>(value >> 56);
+
+ int size;
+
+ // Here we can't really optimize for small numbers, since the value is
+ // split into three parts. Cheking for numbers < 128, for instance,
+ // would require three comparisons, since you'd have to make sure part1
+ // and part2 are zero. However, if the caller is using 64-bit integers,
+ // it is likely that they expect the numbers to often be very large, so
+ // we probably don't want to optimize for small numbers anyway. Thus,
+ // we end up with a hardcoded binary search tree...
+ if (part2 == 0) {
+ if (part1 == 0) {
+ if (part0 < (1 << 14)) {
+ if (part0 < (1 << 7)) {
+ size = 1; goto size1;
+ } else {
+ size = 2; goto size2;
+ }
+ } else {
+ if (part0 < (1 << 21)) {
+ size = 3; goto size3;
+ } else {
+ size = 4; goto size4;
+ }
+ }
+ } else {
+ if (part1 < (1 << 14)) {
+ if (part1 < (1 << 7)) {
+ size = 5; goto size5;
+ } else {
+ size = 6; goto size6;
+ }
+ } else {
+ if (part1 < (1 << 21)) {
+ size = 7; goto size7;
+ } else {
+ size = 8; goto size8;
+ }
+ }
+ }
+ } else {
+ if (part2 < (1 << 7)) {
+ size = 9; goto size9;
+ } else {
+ size = 10; goto size10;
+ }
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+
+ size10: target[9] = static_cast<uint8>((part2 >> 7) | 0x80);
+ size9 : target[8] = static_cast<uint8>((part2 ) | 0x80);
+ size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80);
+ size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80);
+ size6 : target[5] = static_cast<uint8>((part1 >> 7) | 0x80);
+ size5 : target[4] = static_cast<uint8>((part1 ) | 0x80);
+ size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80);
+ size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80);
+ size2 : target[1] = static_cast<uint8>((part0 >> 7) | 0x80);
+ size1 : target[0] = static_cast<uint8>((part0 ) | 0x80);
+
+ target[size-1] &= 0x7F;
+ return target + size;
+}
+
+void CodedOutputStream::WriteVarint64(uint64 value) {
+ if (buffer_size_ >= kMaxVarintBytes) {
+ // Fast path: We have enough bytes left in the buffer to guarantee that
+ // this write won't cross the end, so we can skip the checks.
+ uint8* target = buffer_;
+
+ uint8* end = WriteVarint64ToArrayInline(value, target);
+ int size = end - target;
+ Advance(size);
+ } else {
+ // Slow path: This write might cross the end of the buffer, so we
+ // compose the bytes first then use WriteRaw().
+ uint8 bytes[kMaxVarintBytes];
+ int size = 0;
+ while (value > 0x7F) {
+ bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
+ value >>= 7;
+ }
+ bytes[size++] = static_cast<uint8>(value) & 0x7F;
+ WriteRaw(bytes, size);
+ }
+}
+
+uint8* CodedOutputStream::WriteVarint64ToArray(
+ uint64 value, uint8* target) {
+ return WriteVarint64ToArrayInline(value, target);
+}
+
+bool CodedOutputStream::Refresh() {
+ void* void_buffer;
+ if (output_->Next(&void_buffer, &buffer_size_)) {
+ buffer_ = reinterpret_cast<uint8*>(void_buffer);
+ total_bytes_ += buffer_size_;
+ return true;
+ } else {
+ buffer_ = NULL;
+ buffer_size_ = 0;
+ had_error_ = true;
+ return false;
+ }
+}
+
+int CodedOutputStream::VarintSize32Fallback(uint32 value) {
+ if (value < (1 << 7)) {
+ return 1;
+ } else if (value < (1 << 14)) {
+ return 2;
+ } else if (value < (1 << 21)) {
+ return 3;
+ } else if (value < (1 << 28)) {
+ return 4;
+ } else {
+ return 5;
+ }
+}
+
+int CodedOutputStream::VarintSize64(uint64 value) {
+ if (value < (1ull << 35)) {
+ if (value < (1ull << 7)) {
+ return 1;
+ } else if (value < (1ull << 14)) {
+ return 2;
+ } else if (value < (1ull << 21)) {
+ return 3;
+ } else if (value < (1ull << 28)) {
+ return 4;
+ } else {
+ return 5;
+ }
+ } else {
+ if (value < (1ull << 42)) {
+ return 6;
+ } else if (value < (1ull << 49)) {
+ return 7;
+ } else if (value < (1ull << 56)) {
+ return 8;
+ } else if (value < (1ull << 63)) {
+ return 9;
+ } else {
+ return 10;
+ }
+ }
+}
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/coded_stream.h b/src/third_party/protobuf/src/google/protobuf/io/coded_stream.h
new file mode 100644
index 0000000..9f2489a
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/coded_stream.h
@@ -0,0 +1,1118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains the CodedInputStream and CodedOutputStream classes,
+// which wrap a ZeroCopyInputStream or ZeroCopyOutputStream, respectively,
+// and allow you to read or write individual pieces of data in various
+// formats. In particular, these implement the varint encoding for
+// integers, a simple variable-length encoding in which smaller numbers
+// take fewer bytes.
+//
+// Typically these classes will only be used internally by the protocol
+// buffer library in order to encode and decode protocol buffers. Clients
+// of the library only need to know about this class if they wish to write
+// custom message parsing or serialization procedures.
+//
+// CodedOutputStream example:
+// // Write some data to "myfile". First we write a 4-byte "magic number"
+// // to identify the file type, then write a length-delimited string. The
+// // string is composed of a varint giving the length followed by the raw
+// // bytes.
+// int fd = open("myfile", O_WRONLY);
+// ZeroCopyOutputStream* raw_output = new FileOutputStream(fd);
+// CodedOutputStream* coded_output = new CodedOutputStream(raw_output);
+//
+// int magic_number = 1234;
+// char text[] = "Hello world!";
+// coded_output->WriteLittleEndian32(magic_number);
+// coded_output->WriteVarint32(strlen(text));
+// coded_output->WriteRaw(text, strlen(text));
+//
+// delete coded_output;
+// delete raw_output;
+// close(fd);
+//
+// CodedInputStream example:
+// // Read a file created by the above code.
+// int fd = open("myfile", O_RDONLY);
+// ZeroCopyInputStream* raw_input = new FileInputStream(fd);
+// CodedInputStream coded_input = new CodedInputStream(raw_input);
+//
+// coded_input->ReadLittleEndian32(&magic_number);
+// if (magic_number != 1234) {
+// cerr << "File not in expected format." << endl;
+// return;
+// }
+//
+// uint32 size;
+// coded_input->ReadVarint32(&size);
+//
+// char* text = new char[size + 1];
+// coded_input->ReadRaw(buffer, size);
+// text[size] = '\0';
+//
+// delete coded_input;
+// delete raw_input;
+// close(fd);
+//
+// cout << "Text is: " << text << endl;
+// delete [] text;
+//
+// For those who are interested, varint encoding is defined as follows:
+//
+// The encoding operates on unsigned integers of up to 64 bits in length.
+// Each byte of the encoded value has the format:
+// * bits 0-6: Seven bits of the number being encoded.
+// * bit 7: Zero if this is the last byte in the encoding (in which
+// case all remaining bits of the number are zero) or 1 if
+// more bytes follow.
+// The first byte contains the least-significant 7 bits of the number, the
+// second byte (if present) contains the next-least-significant 7 bits,
+// and so on. So, the binary number 1011000101011 would be encoded in two
+// bytes as "10101011 00101100".
+//
+// In theory, varint could be used to encode integers of any length.
+// However, for practicality we set a limit at 64 bits. The maximum encoded
+// length of a number is thus 10 bytes.
+
+#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
+#define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
+
+#include <string>
+#ifdef _MSC_VER
+ #if defined(_M_IX86) && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ #define PROTOBUF_LITTLE_ENDIAN 1
+ #endif
+ #if _MSC_VER >= 1300
+ // If MSVC has "/RTCc" set, it will complain about truncating casts at
+ // runtime. This file contains some intentional truncating casts.
+ #pragma runtime_checks("c", off)
+ #endif
+#else
+ #include <sys/param.h> // __BYTE_ORDER
+ #if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN && \
+ !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+ #define PROTOBUF_LITTLE_ENDIAN 1
+ #endif
+#endif
+#include <google/protobuf/stubs/common.h>
+
+#include "starboard/client_porting/poem/string_poem.h"
+
+namespace google {
+namespace protobuf {
+
+class DescriptorPool;
+class MessageFactory;
+
+namespace io {
+
+// Defined in this file.
+class CodedInputStream;
+class CodedOutputStream;
+
+// Defined in other files.
+class ZeroCopyInputStream; // zero_copy_stream.h
+class ZeroCopyOutputStream; // zero_copy_stream.h
+
+// Class which reads and decodes binary data which is composed of varint-
+// encoded integers and fixed-width pieces. Wraps a ZeroCopyInputStream.
+// Most users will not need to deal with CodedInputStream.
+//
+// Most methods of CodedInputStream that return a bool return false if an
+// underlying I/O error occurs or if the data is malformed. Once such a
+// failure occurs, the CodedInputStream is broken and is no longer useful.
+class LIBPROTOBUF_EXPORT CodedInputStream {
+ public:
+ // Create a CodedInputStream that reads from the given ZeroCopyInputStream.
+ explicit CodedInputStream(ZeroCopyInputStream* input);
+
+ // Create a CodedInputStream that reads from the given flat array. This is
+ // faster than using an ArrayInputStream. PushLimit(size) is implied by
+ // this constructor.
+ explicit CodedInputStream(const uint8* buffer, int size);
+
+ // Destroy the CodedInputStream and position the underlying
+ // ZeroCopyInputStream at the first unread byte. If an error occurred while
+ // reading (causing a method to return false), then the exact position of
+ // the input stream may be anywhere between the last value that was read
+ // successfully and the stream's byte limit.
+ ~CodedInputStream();
+
+
+ // Skips a number of bytes. Returns false if an underlying read error
+ // occurs.
+ bool Skip(int count);
+
+ // Sets *data to point directly at the unread part of the CodedInputStream's
+ // underlying buffer, and *size to the size of that buffer, but does not
+ // advance the stream's current position. This will always either produce
+ // a non-empty buffer or return false. If the caller consumes any of
+ // this data, it should then call Skip() to skip over the consumed bytes.
+ // This may be useful for implementing external fast parsing routines for
+ // types of data not covered by the CodedInputStream interface.
+ bool GetDirectBufferPointer(const void** data, int* size);
+
+ // Like GetDirectBufferPointer, but this method is inlined, and does not
+ // attempt to Refresh() if the buffer is currently empty.
+ inline void GetDirectBufferPointerInline(const void** data,
+ int* size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+ // Read raw bytes, copying them into the given buffer.
+ bool ReadRaw(void* buffer, int size);
+
+ // Like ReadRaw, but reads into a string.
+ //
+ // Implementation Note: ReadString() grows the string gradually as it
+ // reads in the data, rather than allocating the entire requested size
+ // upfront. This prevents denial-of-service attacks in which a client
+ // could claim that a string is going to be MAX_INT bytes long in order to
+ // crash the server because it can't allocate this much space at once.
+ bool ReadString(string* buffer, int size);
+ // Like the above, with inlined optimizations. This should only be used
+ // by the protobuf implementation.
+ inline bool InternalReadStringInline(string* buffer,
+ int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+
+ // Read a 32-bit little-endian integer.
+ bool ReadLittleEndian32(uint32* value);
+ // Read a 64-bit little-endian integer.
+ bool ReadLittleEndian64(uint64* value);
+
+ // These methods read from an externally provided buffer. The caller is
+ // responsible for ensuring that the buffer has sufficient space.
+ // Read a 32-bit little-endian integer.
+ static const uint8* ReadLittleEndian32FromArray(const uint8* buffer,
+ uint32* value);
+ // Read a 64-bit little-endian integer.
+ static const uint8* ReadLittleEndian64FromArray(const uint8* buffer,
+ uint64* value);
+
+ // Read an unsigned integer with Varint encoding, truncating to 32 bits.
+ // Reading a 32-bit value is equivalent to reading a 64-bit one and casting
+ // it to uint32, but may be more efficient.
+ bool ReadVarint32(uint32* value);
+ // Read an unsigned integer with Varint encoding.
+ bool ReadVarint64(uint64* value);
+
+ // Read a tag. This calls ReadVarint32() and returns the result, or returns
+ // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates
+ // the last tag value, which can be checked with LastTagWas().
+ // Always inline because this is only called in once place per parse loop
+ // but it is called for every iteration of said loop, so it should be fast.
+ // GCC doesn't want to inline this by default.
+ uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+ // Usually returns true if calling ReadVarint32() now would produce the given
+ // value. Will always return false if ReadVarint32() would not return the
+ // given value. If ExpectTag() returns true, it also advances past
+ // the varint. For best performance, use a compile-time constant as the
+ // parameter.
+ // Always inline because this collapses to a small number of instructions
+ // when given a constant parameter, but GCC doesn't want to inline by default.
+ bool ExpectTag(uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+ // Like above, except this reads from the specified buffer. The caller is
+ // responsible for ensuring that the buffer is large enough to read a varint
+ // of the expected size. For best performance, use a compile-time constant as
+ // the expected tag parameter.
+ //
+ // Returns a pointer beyond the expected tag if it was found, or NULL if it
+ // was not.
+ static const uint8* ExpectTagFromArray(
+ const uint8* buffer,
+ uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+ // Usually returns true if no more bytes can be read. Always returns false
+ // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent
+ // call to LastTagWas() will act as if ReadTag() had been called and returned
+ // zero, and ConsumedEntireMessage() will return true.
+ bool ExpectAtEnd();
+
+ // If the last call to ReadTag() returned the given value, returns true.
+ // Otherwise, returns false;
+ //
+ // This is needed because parsers for some types of embedded messages
+ // (with field type TYPE_GROUP) don't actually know that they've reached the
+ // end of a message until they see an ENDGROUP tag, which was actually part
+ // of the enclosing message. The enclosing message would like to check that
+ // tag to make sure it had the right number, so it calls LastTagWas() on
+ // return from the embedded parser to check.
+ bool LastTagWas(uint32 expected);
+
+ // When parsing message (but NOT a group), this method must be called
+ // immediately after MergeFromCodedStream() returns (if it returns true)
+ // to further verify that the message ended in a legitimate way. For
+ // example, this verifies that parsing did not end on an end-group tag.
+ // It also checks for some cases where, due to optimizations,
+ // MergeFromCodedStream() can incorrectly return true.
+ bool ConsumedEntireMessage();
+
+ // Limits ----------------------------------------------------------
+ // Limits are used when parsing length-delimited embedded messages.
+ // After the message's length is read, PushLimit() is used to prevent
+ // the CodedInputStream from reading beyond that length. Once the
+ // embedded message has been parsed, PopLimit() is called to undo the
+ // limit.
+
+ // Opaque type used with PushLimit() and PopLimit(). Do not modify
+ // values of this type yourself. The only reason that this isn't a
+ // struct with private internals is for efficiency.
+ typedef int Limit;
+
+ // Places a limit on the number of bytes that the stream may read,
+ // starting from the current position. Once the stream hits this limit,
+ // it will act like the end of the input has been reached until PopLimit()
+ // is called.
+ //
+ // As the names imply, the stream conceptually has a stack of limits. The
+ // shortest limit on the stack is always enforced, even if it is not the
+ // top limit.
+ //
+ // The value returned by PushLimit() is opaque to the caller, and must
+ // be passed unchanged to the corresponding call to PopLimit().
+ Limit PushLimit(int byte_limit);
+
+ // Pops the last limit pushed by PushLimit(). The input must be the value
+ // returned by that call to PushLimit().
+ void PopLimit(Limit limit);
+
+ // Returns the number of bytes left until the nearest limit on the
+ // stack is hit, or -1 if no limits are in place.
+ int BytesUntilLimit();
+
+ // Total Bytes Limit -----------------------------------------------
+ // To prevent malicious users from sending excessively large messages
+ // and causing integer overflows or memory exhaustion, CodedInputStream
+ // imposes a hard limit on the total number of bytes it will read.
+
+ // Sets the maximum number of bytes that this CodedInputStream will read
+ // before refusing to continue. To prevent integer overflows in the
+ // protocol buffers implementation, as well as to prevent servers from
+ // allocating enormous amounts of memory to hold parsed messages, the
+ // maximum message length should be limited to the shortest length that
+ // will not harm usability. The theoretical shortest message that could
+ // cause integer overflows is 512MB. The default limit is 64MB. Apps
+ // should set shorter limits if possible. If warning_threshold is not -1,
+ // a warning will be printed to stderr after warning_threshold bytes are
+ // read. An error will always be printed to stderr if the limit is
+ // reached.
+ //
+ // This is unrelated to PushLimit()/PopLimit().
+ //
+ // Hint: If you are reading this because your program is printing a
+ // warning about dangerously large protocol messages, you may be
+ // confused about what to do next. The best option is to change your
+ // design such that excessively large messages are not necessary.
+ // For example, try to design file formats to consist of many small
+ // messages rather than a single large one. If this is infeasible,
+ // you will need to increase the limit. Chances are, though, that
+ // your code never constructs a CodedInputStream on which the limit
+ // can be set. You probably parse messages by calling things like
+ // Message::ParseFromString(). In this case, you will need to change
+ // your code to instead construct some sort of ZeroCopyInputStream
+ // (e.g. an ArrayInputStream), construct a CodedInputStream around
+ // that, then call Message::ParseFromCodedStream() instead. Then
+ // you can adjust the limit. Yes, it's more work, but you're doing
+ // something unusual.
+ void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold);
+
+ // Recursion Limit -------------------------------------------------
+ // To prevent corrupt or malicious messages from causing stack overflows,
+ // we must keep track of the depth of recursion when parsing embedded
+ // messages and groups. CodedInputStream keeps track of this because it
+ // is the only object that is passed down the stack during parsing.
+
+ // Sets the maximum recursion depth. The default is 64.
+ void SetRecursionLimit(int limit);
+
+ // Increments the current recursion depth. Returns true if the depth is
+ // under the limit, false if it has gone over.
+ bool IncrementRecursionDepth();
+
+ // Decrements the recursion depth.
+ void DecrementRecursionDepth();
+
+ // Extension Registry ----------------------------------------------
+ // ADVANCED USAGE: 99.9% of people can ignore this section.
+ //
+ // By default, when parsing extensions, the parser looks for extension
+ // definitions in the pool which owns the outer message's Descriptor.
+ // However, you may call SetExtensionRegistry() to provide an alternative
+ // pool instead. This makes it possible, for example, to parse a message
+ // using a generated class, but represent some extensions using
+ // DynamicMessage.
+
+ // Set the pool used to look up extensions. Most users do not need to call
+ // this as the correct pool will be chosen automatically.
+ //
+ // WARNING: It is very easy to misuse this. Carefully read the requirements
+ // below. Do not use this unless you are sure you need it. Almost no one
+ // does.
+ //
+ // Let's say you are parsing a message into message object m, and you want
+ // to take advantage of SetExtensionRegistry(). You must follow these
+ // requirements:
+ //
+ // The given DescriptorPool must contain m->GetDescriptor(). It is not
+ // sufficient for it to simply contain a descriptor that has the same name
+ // and content -- it must be the *exact object*. In other words:
+ // assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) ==
+ // m->GetDescriptor());
+ // There are two ways to satisfy this requirement:
+ // 1) Use m->GetDescriptor()->pool() as the pool. This is generally useless
+ // because this is the pool that would be used anyway if you didn't call
+ // SetExtensionRegistry() at all.
+ // 2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an
+ // "underlay". Read the documentation for DescriptorPool for more
+ // information about underlays.
+ //
+ // You must also provide a MessageFactory. This factory will be used to
+ // construct Message objects representing extensions. The factory's
+ // GetPrototype() MUST return non-NULL for any Descriptor which can be found
+ // through the provided pool.
+ //
+ // If the provided factory might return instances of protocol-compiler-
+ // generated (i.e. compiled-in) types, or if the outer message object m is
+ // a generated type, then the given factory MUST have this property: If
+ // GetPrototype() is given a Descriptor which resides in
+ // DescriptorPool::generated_pool(), the factory MUST return the same
+ // prototype which MessageFactory::generated_factory() would return. That
+ // is, given a descriptor for a generated type, the factory must return an
+ // instance of the generated class (NOT DynamicMessage). However, when
+ // given a descriptor for a type that is NOT in generated_pool, the factory
+ // is free to return any implementation.
+ //
+ // The reason for this requirement is that generated sub-objects may be
+ // accessed via the standard (non-reflection) extension accessor methods,
+ // and these methods will down-cast the object to the generated class type.
+ // If the object is not actually of that type, the results would be undefined.
+ // On the other hand, if an extension is not compiled in, then there is no
+ // way the code could end up accessing it via the standard accessors -- the
+ // only way to access the extension is via reflection. When using reflection,
+ // DynamicMessage and generated messages are indistinguishable, so it's fine
+ // if these objects are represented using DynamicMessage.
+ //
+ // Using DynamicMessageFactory on which you have called
+ // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the
+ // above requirement.
+ //
+ // If either pool or factory is NULL, both must be NULL.
+ //
+ // Note that this feature is ignored when parsing "lite" messages as they do
+ // not have descriptors.
+ void SetExtensionRegistry(DescriptorPool* pool, MessageFactory* factory);
+
+ // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool
+ // has been provided.
+ const DescriptorPool* GetExtensionPool();
+
+ // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no
+ // factory has been provided.
+ MessageFactory* GetExtensionFactory();
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream);
+
+ ZeroCopyInputStream* input_;
+ const uint8* buffer_;
+ const uint8* buffer_end_; // pointer to the end of the buffer.
+ int total_bytes_read_; // total bytes read from input_, including
+ // the current buffer
+
+ // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here
+ // so that we can BackUp() on destruction.
+ int overflow_bytes_;
+
+ // LastTagWas() stuff.
+ uint32 last_tag_; // result of last ReadTag().
+
+ // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly
+ // at EOF, or by ExpectAtEnd() when it returns true. This happens when we
+ // reach the end of a message and attempt to read another tag.
+ bool legitimate_message_end_;
+
+ // See EnableAliasing().
+ bool aliasing_enabled_;
+
+ // Limits
+ Limit current_limit_; // if position = -1, no limit is applied
+
+ // For simplicity, if the current buffer crosses a limit (either a normal
+ // limit created by PushLimit() or the total bytes limit), buffer_size_
+ // only tracks the number of bytes before that limit. This field
+ // contains the number of bytes after it. Note that this implies that if
+ // buffer_size_ == 0 and buffer_size_after_limit_ > 0, we know we've
+ // hit a limit. However, if both are zero, it doesn't necessarily mean
+ // we aren't at a limit -- the buffer may have ended exactly at the limit.
+ int buffer_size_after_limit_;
+
+ // Maximum number of bytes to read, period. This is unrelated to
+ // current_limit_. Set using SetTotalBytesLimit().
+ int total_bytes_limit_;
+ int total_bytes_warning_threshold_;
+
+ // Current recursion depth, controlled by IncrementRecursionDepth() and
+ // DecrementRecursionDepth().
+ int recursion_depth_;
+ // Recursion depth limit, set by SetRecursionLimit().
+ int recursion_limit_;
+
+ // See SetExtensionRegistry().
+ const DescriptorPool* extension_pool_;
+ MessageFactory* extension_factory_;
+
+ // Private member functions.
+
+ // Advance the buffer by a given number of bytes.
+ void Advance(int amount);
+
+ // Back up input_ to the current buffer position.
+ void BackUpInputToCurrentPosition();
+
+ // Recomputes the value of buffer_size_after_limit_. Must be called after
+ // current_limit_ or total_bytes_limit_ changes.
+ void RecomputeBufferLimits();
+
+ // Writes an error message saying that we hit total_bytes_limit_.
+ void PrintTotalBytesLimitError();
+
+ // Called when the buffer runs out to request more data. Implies an
+ // Advance(BufferSize()).
+ bool Refresh();
+
+ // When parsing varints, we optimize for the common case of small values, and
+ // then optimize for the case when the varint fits within the current buffer
+ // piece. The Fallback method is used when we can't use the one-byte
+ // optimization. The Slow method is yet another fallback when the buffer is
+ // not large enough. Making the slow path out-of-line speeds up the common
+ // case by 10-15%. The slow path is fairly uncommon: it only triggers when a
+ // message crosses multiple buffers.
+ bool ReadVarint32Fallback(uint32* value);
+ bool ReadVarint64Fallback(uint64* value);
+ bool ReadVarint32Slow(uint32* value);
+ bool ReadVarint64Slow(uint64* value);
+ bool ReadLittleEndian32Fallback(uint32* value);
+ bool ReadLittleEndian64Fallback(uint64* value);
+ // Fallback/slow methods for reading tags. These do not update last_tag_,
+ // but will set legitimate_message_end_ if we are at the end of the input
+ // stream.
+ uint32 ReadTagFallback();
+ uint32 ReadTagSlow();
+ bool ReadStringFallback(string* buffer, int size);
+
+ // Return the size of the buffer.
+ int BufferSize() const;
+
+ static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB
+
+ static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB
+ static const int kDefaultRecursionLimit = 64;
+};
+
+// Class which encodes and writes binary data which is composed of varint-
+// encoded integers and fixed-width pieces. Wraps a ZeroCopyOutputStream.
+// Most users will not need to deal with CodedOutputStream.
+//
+// Most methods of CodedOutputStream which return a bool return false if an
+// underlying I/O error occurs. Once such a failure occurs, the
+// CodedOutputStream is broken and is no longer useful. The Write* methods do
+// not return the stream status, but will invalidate the stream if an error
+// occurs. The client can probe HadError() to determine the status.
+//
+// Note that every method of CodedOutputStream which writes some data has
+// a corresponding static "ToArray" version. These versions write directly
+// to the provided buffer, returning a pointer past the last written byte.
+// They require that the buffer has sufficient capacity for the encoded data.
+// This allows an optimization where we check if an output stream has enough
+// space for an entire message before we start writing and, if there is, we
+// call only the ToArray methods to avoid doing bound checks for each
+// individual value.
+// i.e., in the example above:
+//
+// CodedOutputStream coded_output = new CodedOutputStream(raw_output);
+// int magic_number = 1234;
+// char text[] = "Hello world!";
+//
+// int coded_size = sizeof(magic_number) +
+// CodedOutputStream::VarintSize32(strlen(text)) +
+// strlen(text);
+//
+// uint8* buffer =
+// coded_output->GetDirectBufferForNBytesAndAdvance(coded_size);
+// if (buffer != NULL) {
+// // The output stream has enough space in the buffer: write directly to
+// // the array.
+// buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number,
+// buffer);
+// buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer);
+// buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer);
+// } else {
+// // Make bound-checked writes, which will ask the underlying stream for
+// // more space as needed.
+// coded_output->WriteLittleEndian32(magic_number);
+// coded_output->WriteVarint32(strlen(text));
+// coded_output->WriteRaw(text, strlen(text));
+// }
+//
+// delete coded_output;
+class LIBPROTOBUF_EXPORT CodedOutputStream {
+ public:
+ // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream.
+ explicit CodedOutputStream(ZeroCopyOutputStream* output);
+
+ // Destroy the CodedOutputStream and position the underlying
+ // ZeroCopyOutputStream immediately after the last byte written.
+ ~CodedOutputStream();
+
+ // Skips a number of bytes, leaving the bytes unmodified in the underlying
+ // buffer. Returns false if an underlying write error occurs. This is
+ // mainly useful with GetDirectBufferPointer().
+ bool Skip(int count);
+
+ // Sets *data to point directly at the unwritten part of the
+ // CodedOutputStream's underlying buffer, and *size to the size of that
+ // buffer, but does not advance the stream's current position. This will
+ // always either produce a non-empty buffer or return false. If the caller
+ // writes any data to this buffer, it should then call Skip() to skip over
+ // the consumed bytes. This may be useful for implementing external fast
+ // serialization routines for types of data not covered by the
+ // CodedOutputStream interface.
+ bool GetDirectBufferPointer(void** data, int* size);
+
+ // If there are at least "size" bytes available in the current buffer,
+ // returns a pointer directly into the buffer and advances over these bytes.
+ // The caller may then write directly into this buffer (e.g. using the
+ // *ToArray static methods) rather than go through CodedOutputStream. If
+ // there are not enough bytes available, returns NULL. The return pointer is
+ // invalidated as soon as any other non-const method of CodedOutputStream
+ // is called.
+ inline uint8* GetDirectBufferForNBytesAndAdvance(int size);
+
+ // Write raw bytes, copying them from the given buffer.
+ void WriteRaw(const void* buffer, int size);
+ // Like WriteRaw() but writing directly to the target array.
+ // This is _not_ inlined, as the compiler often optimizes memcpy into inline
+ // copy loops. Since this gets called by every field with string or bytes
+ // type, inlining may lead to a significant amount of code bloat, with only a
+ // minor performance gain.
+ static uint8* WriteRawToArray(const void* buffer, int size, uint8* target);
+
+ // Equivalent to WriteRaw(str.data(), str.size()).
+ void WriteString(const string& str);
+ // Like WriteString() but writing directly to the target array.
+ static uint8* WriteStringToArray(const string& str, uint8* target);
+
+
+ // Write a 32-bit little-endian integer.
+ void WriteLittleEndian32(uint32 value);
+ // Like WriteLittleEndian32() but writing directly to the target array.
+ static uint8* WriteLittleEndian32ToArray(uint32 value, uint8* target);
+ // Write a 64-bit little-endian integer.
+ void WriteLittleEndian64(uint64 value);
+ // Like WriteLittleEndian64() but writing directly to the target array.
+ static uint8* WriteLittleEndian64ToArray(uint64 value, uint8* target);
+
+ // Write an unsigned integer with Varint encoding. Writing a 32-bit value
+ // is equivalent to casting it to uint64 and writing it as a 64-bit value,
+ // but may be more efficient.
+ void WriteVarint32(uint32 value);
+ // Like WriteVarint32() but writing directly to the target array.
+ static uint8* WriteVarint32ToArray(uint32 value, uint8* target);
+ // Write an unsigned integer with Varint encoding.
+ void WriteVarint64(uint64 value);
+ // Like WriteVarint64() but writing directly to the target array.
+ static uint8* WriteVarint64ToArray(uint64 value, uint8* target);
+
+ // Equivalent to WriteVarint32() except when the value is negative,
+ // in which case it must be sign-extended to a full 10 bytes.
+ void WriteVarint32SignExtended(int32 value);
+ // Like WriteVarint32SignExtended() but writing directly to the target array.
+ static uint8* WriteVarint32SignExtendedToArray(int32 value, uint8* target);
+
+ // This is identical to WriteVarint32(), but optimized for writing tags.
+ // In particular, if the input is a compile-time constant, this method
+ // compiles down to a couple instructions.
+ // Always inline because otherwise the aformentioned optimization can't work,
+ // but GCC by default doesn't want to inline this.
+ void WriteTag(uint32 value);
+ // Like WriteTag() but writing directly to the target array.
+ static uint8* WriteTagToArray(
+ uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+ // Returns the number of bytes needed to encode the given value as a varint.
+ static int VarintSize32(uint32 value);
+ // Returns the number of bytes needed to encode the given value as a varint.
+ static int VarintSize64(uint64 value);
+
+ // If negative, 10 bytes. Otheriwse, same as VarintSize32().
+ static int VarintSize32SignExtended(int32 value);
+
+ // Compile-time equivalent of VarintSize32().
+ template <uint32 Value>
+ struct StaticVarintSize32 {
+ static const int value =
+ (Value < (1 << 7))
+ ? 1
+ : (Value < (1 << 14))
+ ? 2
+ : (Value < (1 << 21))
+ ? 3
+ : (Value < (1 << 28))
+ ? 4
+ : 5;
+ };
+
+ // Returns the total number of bytes written since this object was created.
+ inline int ByteCount() const;
+
+ // Returns true if there was an underlying I/O error since this object was
+ // created.
+ bool HadError() const { return had_error_; }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream);
+
+ ZeroCopyOutputStream* output_;
+ uint8* buffer_;
+ int buffer_size_;
+ int total_bytes_; // Sum of sizes of all buffers seen so far.
+ bool had_error_; // Whether an error occurred during output.
+
+ // Advance the buffer by a given number of bytes.
+ void Advance(int amount);
+
+ // Called when the buffer runs out to request more data. Implies an
+ // Advance(buffer_size_).
+ bool Refresh();
+
+ static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target);
+
+ // Always-inlined versions of WriteVarint* functions so that code can be
+ // reused, while still controlling size. For instance, WriteVarint32ToArray()
+ // should not directly call this: since it is inlined itself, doing so
+ // would greatly increase the size of generated code. Instead, it should call
+ // WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already
+ // out-of-line, so it should just invoke this directly to avoid any extra
+ // function call overhead.
+ static uint8* WriteVarint32FallbackToArrayInline(
+ uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ static uint8* WriteVarint64ToArrayInline(
+ uint64 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+ static int VarintSize32Fallback(uint32 value);
+};
+
+// inline methods ====================================================
+// The vast majority of varints are only one byte. These inline
+// methods optimize for that case.
+
+inline bool CodedInputStream::ReadVarint32(uint32* value) {
+ if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) {
+ *value = *buffer_;
+ Advance(1);
+ return true;
+ } else {
+ return ReadVarint32Fallback(value);
+ }
+}
+
+inline bool CodedInputStream::ReadVarint64(uint64* value) {
+ if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) {
+ *value = *buffer_;
+ Advance(1);
+ return true;
+ } else {
+ return ReadVarint64Fallback(value);
+ }
+}
+
+// static
+inline const uint8* CodedInputStream::ReadLittleEndian32FromArray(
+ const uint8* buffer,
+ uint32* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ memcpy(value, buffer, sizeof(*value));
+ return buffer + sizeof(*value);
+#else
+ *value = (static_cast<uint32>(buffer[0]) ) |
+ (static_cast<uint32>(buffer[1]) << 8) |
+ (static_cast<uint32>(buffer[2]) << 16) |
+ (static_cast<uint32>(buffer[3]) << 24);
+ return buffer + sizeof(*value);
+#endif
+}
+// static
+inline const uint8* CodedInputStream::ReadLittleEndian64FromArray(
+ const uint8* buffer,
+ uint64* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ memcpy(value, buffer, sizeof(*value));
+ return buffer + sizeof(*value);
+#else
+ uint32 part0 = (static_cast<uint32>(buffer[0]) ) |
+ (static_cast<uint32>(buffer[1]) << 8) |
+ (static_cast<uint32>(buffer[2]) << 16) |
+ (static_cast<uint32>(buffer[3]) << 24);
+ uint32 part1 = (static_cast<uint32>(buffer[4]) ) |
+ (static_cast<uint32>(buffer[5]) << 8) |
+ (static_cast<uint32>(buffer[6]) << 16) |
+ (static_cast<uint32>(buffer[7]) << 24);
+ *value = static_cast<uint64>(part0) |
+ (static_cast<uint64>(part1) << 32);
+ return buffer + sizeof(*value);
+#endif
+}
+
+inline bool CodedInputStream::ReadLittleEndian32(uint32* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
+ memcpy(value, buffer_, sizeof(*value));
+ Advance(sizeof(*value));
+ return true;
+ } else {
+ return ReadLittleEndian32Fallback(value);
+ }
+#else
+ return ReadLittleEndian32Fallback(value);
+#endif
+}
+
+inline bool CodedInputStream::ReadLittleEndian64(uint64* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
+ memcpy(value, buffer_, sizeof(*value));
+ Advance(sizeof(*value));
+ return true;
+ } else {
+ return ReadLittleEndian64Fallback(value);
+ }
+#else
+ return ReadLittleEndian64Fallback(value);
+#endif
+}
+
+inline uint32 CodedInputStream::ReadTag() {
+ if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] < 0x80) {
+ last_tag_ = buffer_[0];
+ Advance(1);
+ return last_tag_;
+ } else {
+ last_tag_ = ReadTagFallback();
+ return last_tag_;
+ }
+}
+
+inline bool CodedInputStream::LastTagWas(uint32 expected) {
+ return last_tag_ == expected;
+}
+
+inline bool CodedInputStream::ConsumedEntireMessage() {
+ return legitimate_message_end_;
+}
+
+inline bool CodedInputStream::ExpectTag(uint32 expected) {
+ if (expected < (1 << 7)) {
+ if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) {
+ Advance(1);
+ return true;
+ } else {
+ return false;
+ }
+ } else if (expected < (1 << 14)) {
+ if (GOOGLE_PREDICT_TRUE(BufferSize() >= 2) &&
+ buffer_[0] == static_cast<uint8>(expected | 0x80) &&
+ buffer_[1] == static_cast<uint8>(expected >> 7)) {
+ Advance(2);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ // Don't bother optimizing for larger values.
+ return false;
+ }
+}
+
+inline const uint8* CodedInputStream::ExpectTagFromArray(
+ const uint8* buffer, uint32 expected) {
+ if (expected < (1 << 7)) {
+ if (buffer[0] == expected) {
+ return buffer + 1;
+ }
+ } else if (expected < (1 << 14)) {
+ if (buffer[0] == static_cast<uint8>(expected | 0x80) &&
+ buffer[1] == static_cast<uint8>(expected >> 7)) {
+ return buffer + 2;
+ }
+ }
+ return NULL;
+}
+
+inline void CodedInputStream::GetDirectBufferPointerInline(const void** data,
+ int* size) {
+ *data = buffer_;
+ *size = static_cast<int>(buffer_end_ - buffer_);
+}
+
+inline bool CodedInputStream::ExpectAtEnd() {
+ // If we are at a limit we know no more bytes can be read. Otherwise, it's
+ // hard to say without calling Refresh(), and we'd rather not do that.
+
+ if (buffer_ == buffer_end_ && buffer_size_after_limit_ != 0) {
+ last_tag_ = 0; // Pretend we called ReadTag()...
+ legitimate_message_end_ = true; // ... and it hit EOF.
+ return true;
+ } else {
+ return false;
+ }
+}
+
+inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) {
+ if (buffer_size_ < size) {
+ return NULL;
+ } else {
+ uint8* result = buffer_;
+ Advance(size);
+ return result;
+ }
+}
+
+inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value,
+ uint8* target) {
+ if (value < 0x80) {
+ *target = static_cast<uint8>(value);
+ return target + 1;
+ } else {
+ return WriteVarint32FallbackToArray(value, target);
+ }
+}
+
+inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) {
+ if (value < 0) {
+ WriteVarint64(static_cast<uint64>(value));
+ } else {
+ WriteVarint32(static_cast<uint32>(value));
+ }
+}
+
+inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray(
+ int32 value, uint8* target) {
+ if (value < 0) {
+ return WriteVarint64ToArray(static_cast<uint64>(value), target);
+ } else {
+ return WriteVarint32ToArray(static_cast<uint32>(value), target);
+ }
+}
+
+inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value,
+ uint8* target) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ memcpy(target, &value, sizeof(value));
+#else
+ target[0] = static_cast<uint8>(value);
+ target[1] = static_cast<uint8>(value >> 8);
+ target[2] = static_cast<uint8>(value >> 16);
+ target[3] = static_cast<uint8>(value >> 24);
+#endif
+ return target + sizeof(value);
+}
+
+inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value,
+ uint8* target) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+ memcpy(target, &value, sizeof(value));
+#else
+ uint32 part0 = static_cast<uint32>(value);
+ uint32 part1 = static_cast<uint32>(value >> 32);
+
+ target[0] = static_cast<uint8>(part0);
+ target[1] = static_cast<uint8>(part0 >> 8);
+ target[2] = static_cast<uint8>(part0 >> 16);
+ target[3] = static_cast<uint8>(part0 >> 24);
+ target[4] = static_cast<uint8>(part1);
+ target[5] = static_cast<uint8>(part1 >> 8);
+ target[6] = static_cast<uint8>(part1 >> 16);
+ target[7] = static_cast<uint8>(part1 >> 24);
+#endif
+ return target + sizeof(value);
+}
+
+inline void CodedOutputStream::WriteTag(uint32 value) {
+ WriteVarint32(value);
+}
+
+inline uint8* CodedOutputStream::WriteTagToArray(
+ uint32 value, uint8* target) {
+ if (value < (1 << 7)) {
+ target[0] = static_cast<uint8>(value);
+ return target + 1;
+ } else if (value < (1 << 14)) {
+ target[0] = static_cast<uint8>(value | 0x80);
+ target[1] = static_cast<uint8>(value >> 7);
+ return target + 2;
+ } else {
+ return WriteVarint32FallbackToArray(value, target);
+ }
+}
+
+inline int CodedOutputStream::VarintSize32(uint32 value) {
+ if (value < (1 << 7)) {
+ return 1;
+ } else {
+ return VarintSize32Fallback(value);
+ }
+}
+
+inline int CodedOutputStream::VarintSize32SignExtended(int32 value) {
+ if (value < 0) {
+ return 10; // TODO(kenton): Make this a symbolic constant.
+ } else {
+ return VarintSize32(static_cast<uint32>(value));
+ }
+}
+
+inline void CodedOutputStream::WriteString(const string& str) {
+ WriteRaw(str.data(), static_cast<int>(str.size()));
+}
+
+inline uint8* CodedOutputStream::WriteStringToArray(
+ const string& str, uint8* target) {
+ return WriteRawToArray(str.data(), static_cast<int>(str.size()), target);
+}
+
+inline int CodedOutputStream::ByteCount() const {
+ return total_bytes_ - buffer_size_;
+}
+
+inline void CodedInputStream::Advance(int amount) {
+ buffer_ += amount;
+}
+
+inline void CodedOutputStream::Advance(int amount) {
+ buffer_ += amount;
+ buffer_size_ -= amount;
+}
+
+inline void CodedInputStream::SetRecursionLimit(int limit) {
+ recursion_limit_ = limit;
+}
+
+inline bool CodedInputStream::IncrementRecursionDepth() {
+ ++recursion_depth_;
+ return recursion_depth_ <= recursion_limit_;
+}
+
+inline void CodedInputStream::DecrementRecursionDepth() {
+ if (recursion_depth_ > 0) --recursion_depth_;
+}
+
+inline void CodedInputStream::SetExtensionRegistry(DescriptorPool* pool,
+ MessageFactory* factory) {
+ extension_pool_ = pool;
+ extension_factory_ = factory;
+}
+
+inline const DescriptorPool* CodedInputStream::GetExtensionPool() {
+ return extension_pool_;
+}
+
+inline MessageFactory* CodedInputStream::GetExtensionFactory() {
+ return extension_factory_;
+}
+
+inline int CodedInputStream::BufferSize() const {
+ return static_cast<int>(buffer_end_ - buffer_);
+}
+
+inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
+ : input_(input),
+ buffer_(NULL),
+ buffer_end_(NULL),
+ total_bytes_read_(0),
+ overflow_bytes_(0),
+ last_tag_(0),
+ legitimate_message_end_(false),
+ aliasing_enabled_(false),
+ current_limit_(kint32max),
+ buffer_size_after_limit_(0),
+ total_bytes_limit_(kDefaultTotalBytesLimit),
+ total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
+ recursion_depth_(0),
+ recursion_limit_(kDefaultRecursionLimit),
+ extension_pool_(NULL),
+ extension_factory_(NULL) {
+ // Eagerly Refresh() so buffer space is immediately available.
+ Refresh();
+}
+
+inline CodedInputStream::CodedInputStream(const uint8* buffer, int size)
+ : input_(NULL),
+ buffer_(buffer),
+ buffer_end_(buffer + size),
+ total_bytes_read_(size),
+ overflow_bytes_(0),
+ last_tag_(0),
+ legitimate_message_end_(false),
+ aliasing_enabled_(false),
+ current_limit_(size),
+ buffer_size_after_limit_(0),
+ total_bytes_limit_(kDefaultTotalBytesLimit),
+ total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
+ recursion_depth_(0),
+ recursion_limit_(kDefaultRecursionLimit),
+ extension_pool_(NULL),
+ extension_factory_(NULL) {
+ // Note that setting current_limit_ == size is important to prevent some
+ // code paths from trying to access input_ and segfaulting.
+}
+
+inline CodedInputStream::~CodedInputStream() {
+ if (input_ != NULL) {
+ BackUpInputToCurrentPosition();
+ }
+}
+
+} // namespace io
+} // namespace protobuf
+
+
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+ #pragma runtime_checks("c", restore)
+#endif // _MSC_VER
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/coded_stream_inl.h b/src/third_party/protobuf/src/google/protobuf/io/coded_stream_inl.h
new file mode 100644
index 0000000..e9799d4
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/coded_stream_inl.h
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jasonh@google.com (Jason Hsueh)
+//
+// Implements methods of coded_stream.h that need to be inlined for performance
+// reasons, but should not be defined in a public header.
+
+#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
+#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
+
+#include <google/protobuf/io/coded_stream.h>
+#include <string>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+inline bool CodedInputStream::InternalReadStringInline(string* buffer,
+ int size) {
+ if (size < 0) return false; // security: size is often user-supplied
+
+ if (BufferSize() >= size) {
+ STLStringResizeUninitialized(buffer, size);
+ memcpy(string_as_array(buffer), buffer_, size);
+ Advance(size);
+ return true;
+ }
+
+ return ReadStringFallback(buffer, size);
+}
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc b/src/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc
new file mode 100644
index 0000000..ff268ab
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc
@@ -0,0 +1,1131 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains tests and benchmarks.
+
+#include <vector>
+
+#include <google/protobuf/io/coded_stream.h>
+
+#include <limits.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/strutil.h>
+
+
+// This declares an unsigned long long integer literal in a portable way.
+// (The original macro is way too big and ruins my formatting.)
+#undef ULL
+#define ULL(x) GOOGLE_ULONGLONG(x)
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// ===================================================================
+// Data-Driven Test Infrastructure
+
+// TEST_1D and TEST_2D are macros I'd eventually like to see added to
+// gTest. These macros can be used to declare tests which should be
+// run multiple times, once for each item in some input array. TEST_1D
+// tests all cases in a single input array. TEST_2D tests all
+// combinations of cases from two arrays. The arrays must be statically
+// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example:
+//
+// int kCases[] = {1, 2, 3, 4}
+// TEST_1D(MyFixture, MyTest, kCases) {
+// EXPECT_GT(kCases_case, 0);
+// }
+//
+// This test iterates through the numbers 1, 2, 3, and 4 and tests that
+// they are all grater than zero. In case of failure, the exact case
+// which failed will be printed. The case type must be printable using
+// ostream::operator<<.
+
+// TODO(kenton): gTest now supports "parameterized tests" which would be
+// a better way to accomplish this. Rewrite when time permits.
+
+#define TEST_1D(FIXTURE, NAME, CASES) \
+ class FIXTURE##_##NAME##_DD : public FIXTURE { \
+ protected: \
+ template <typename CaseType> \
+ void DoSingleCase(const CaseType& CASES##_case); \
+ }; \
+ \
+ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \
+ SCOPED_TRACE(testing::Message() \
+ << #CASES " case #" << i << ": " << CASES[i]); \
+ DoSingleCase(CASES[i]); \
+ } \
+ } \
+ \
+ template <typename CaseType> \
+ void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
+
+#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \
+ class FIXTURE##_##NAME##_DD : public FIXTURE { \
+ protected: \
+ template <typename CaseType1, typename CaseType2> \
+ void DoSingleCase(const CaseType1& CASES1##_case, \
+ const CaseType2& CASES2##_case); \
+ }; \
+ \
+ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \
+ for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \
+ SCOPED_TRACE(testing::Message() \
+ << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \
+ << #CASES2 " case #" << j << ": " << CASES2[j]); \
+ DoSingleCase(CASES1[i], CASES2[j]); \
+ } \
+ } \
+ } \
+ \
+ template <typename CaseType1, typename CaseType2> \
+ void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
+ const CaseType2& CASES2##_case)
+
+// ===================================================================
+
+class CodedStreamTest : public testing::Test {
+ protected:
+ static const int kBufferSize = 1024 * 64;
+ static uint8 buffer_[kBufferSize];
+};
+
+uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize];
+
+// We test each operation over a variety of block sizes to insure that
+// we test cases where reads or writes cross buffer boundaries, cases
+// where they don't, and cases where there is so much buffer left that
+// we can use special optimized paths that don't worry about bounds
+// checks.
+const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
+
+// -------------------------------------------------------------------
+// Varint tests.
+
+struct VarintCase {
+ uint8 bytes[10]; // Encoded bytes.
+ int size; // Encoded size, in bytes.
+ uint64 value; // Parsed value.
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) {
+ return os << c.value;
+}
+
+VarintCase kVarintCases[] = {
+ // 32-bit values
+ {{0x00} , 1, 0},
+ {{0x01} , 1, 1},
+ {{0x7f} , 1, 127},
+ {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)}, // 14882
+ {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5, // 2961488830
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (ULL(0x0b) << 28)},
+
+ // 64-bit
+ {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5, // 7256456126
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (ULL(0x1b) << 28)},
+ {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8, // 41256202580718336
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) |
+ (ULL(0x49) << 49)},
+ // 11964378330978735131
+ {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10,
+ (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) |
+ (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)},
+};
+
+TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) {
+ memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint32 value;
+ EXPECT_TRUE(coded_input.ReadVarint32(&value));
+ EXPECT_EQ(static_cast<uint32>(kVarintCases_case.value), value);
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
+ memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+ EXPECT_EQ(expected_value, coded_input.ReadTag());
+
+ EXPECT_TRUE(coded_input.LastTagWas(expected_value));
+ EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1));
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+// This is the regression test that verifies that there is no issues
+// with the empty input buffers handling.
+TEST_F(CodedStreamTest, EmptyInputBeforeEos) {
+ class In : public ZeroCopyInputStream {
+ public:
+ In() : count_(0) {}
+ private:
+ virtual bool Next(const void** data, int* size) {
+ *data = NULL;
+ *size = 0;
+ return count_++ < 2;
+ }
+ virtual void BackUp(int count) {
+ GOOGLE_LOG(FATAL) << "Tests never call this.";
+ }
+ virtual bool Skip(int count) {
+ GOOGLE_LOG(FATAL) << "Tests never call this.";
+ return false;
+ }
+ virtual int64 ByteCount() const { return 0; }
+ int count_;
+ } in;
+ CodedInputStream input(&in);
+ input.ReadTag();
+ EXPECT_TRUE(input.ConsumedEntireMessage());
+}
+
+TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
+ // Leave one byte at the beginning of the buffer so we can read it
+ // to force the first buffer to be loaded.
+ buffer_[0] = '\0';
+ memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size);
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+
+ {
+ CodedInputStream coded_input(&input);
+
+ // Read one byte to force coded_input.Refill() to be called. Otherwise,
+ // ExpectTag() will return a false negative.
+ uint8 dummy;
+ coded_input.ReadRaw(&dummy, 1);
+ EXPECT_EQ((uint)'\0', (uint)dummy);
+
+ uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+
+ // ExpectTag() produces false negatives for large values.
+ if (kVarintCases_case.size <= 2) {
+ EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1));
+ EXPECT_TRUE(coded_input.ExpectTag(expected_value));
+ } else {
+ EXPECT_FALSE(coded_input.ExpectTag(expected_value));
+ }
+ }
+
+ if (kVarintCases_case.size <= 2) {
+ EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount());
+ } else {
+ EXPECT_EQ(1, input.ByteCount());
+ }
+}
+
+TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) {
+ memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+
+ const uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+
+ // If the expectation succeeds, it should return a pointer past the tag.
+ if (kVarintCases_case.size <= 2) {
+ EXPECT_TRUE(NULL ==
+ CodedInputStream::ExpectTagFromArray(buffer_,
+ expected_value + 1));
+ EXPECT_TRUE(buffer_ + kVarintCases_case.size ==
+ CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
+ } else {
+ EXPECT_TRUE(NULL ==
+ CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
+ }
+}
+
+TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) {
+ memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint64 value;
+ EXPECT_TRUE(coded_input.ReadVarint64(&value));
+ EXPECT_EQ(kVarintCases_case.value, value);
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) {
+ if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) {
+ // Skip this test for the 64-bit values.
+ return;
+ }
+
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteVarint32(static_cast<uint32>(kVarintCases_case.value));
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
+ EXPECT_EQ(0,
+ memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
+}
+
+TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteVarint64(kVarintCases_case.value);
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
+ EXPECT_EQ(0,
+ memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
+}
+
+// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+// "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+int32 kSignExtendedVarintCases[] = {
+ 0, 1, -1, 1237894, -37895138
+};
+
+TEST_2D(CodedStreamTest, WriteVarint32SignExtended,
+ kSignExtendedVarintCases, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case);
+ EXPECT_FALSE(coded_output.HadError());
+
+ if (kSignExtendedVarintCases_case < 0) {
+ EXPECT_EQ(10, coded_output.ByteCount());
+ } else {
+ EXPECT_LE(coded_output.ByteCount(), 5);
+ }
+ }
+
+ if (kSignExtendedVarintCases_case < 0) {
+ EXPECT_EQ(10, output.ByteCount());
+ } else {
+ EXPECT_LE(output.ByteCount(), 5);
+ }
+
+ // Read value back in as a varint64 and insure it matches.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint64 value;
+ EXPECT_TRUE(coded_input.ReadVarint64(&value));
+
+ EXPECT_EQ(kSignExtendedVarintCases_case, static_cast<int64>(value));
+ }
+
+ EXPECT_EQ(output.ByteCount(), input.ByteCount());
+}
+
+#endif
+
+
+// -------------------------------------------------------------------
+// Varint failure test.
+
+struct VarintErrorCase {
+ uint8 bytes[12];
+ int size;
+ bool can_parse;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) {
+ return os << "size " << c.size;
+}
+
+const VarintErrorCase kVarintErrorCases[] = {
+ // Control case. (Insures that there isn't something else wrong that
+ // makes parsing always fail.)
+ {{0x00}, 1, true},
+
+ // No input data.
+ {{}, 0, false},
+
+ // Input ends unexpectedly.
+ {{0xf0, 0xab}, 2, false},
+
+ // Input ends unexpectedly after 32 bits.
+ {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false},
+
+ // Longer than 10 bytes.
+ {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
+ 11, false},
+};
+
+TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) {
+ memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
+ ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
+ kBlockSizes_case);
+ CodedInputStream coded_input(&input);
+
+ uint32 value;
+ EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value));
+}
+
+TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) {
+ memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
+ ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
+ kBlockSizes_case);
+ CodedInputStream coded_input(&input);
+
+ uint64 value;
+ EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value));
+}
+
+// -------------------------------------------------------------------
+// VarintSize
+
+struct VarintSizeCase {
+ uint64 value;
+ int size;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) {
+ return os << c.value;
+}
+
+VarintSizeCase kVarintSizeCases[] = {
+ {0u, 1},
+ {1u, 1},
+ {127u, 1},
+ {128u, 2},
+ {758923u, 3},
+ {4000000000u, 5},
+ {ULL(41256202580718336), 8},
+ {ULL(11964378330978735131), 10},
+};
+
+TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) {
+ if (kVarintSizeCases_case.value > 0xffffffffu) {
+ // Skip 64-bit values.
+ return;
+ }
+
+ EXPECT_EQ(kVarintSizeCases_case.size,
+ CodedOutputStream::VarintSize32(
+ static_cast<uint32>(kVarintSizeCases_case.value)));
+}
+
+TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) {
+ EXPECT_EQ(kVarintSizeCases_case.size,
+ CodedOutputStream::VarintSize64(kVarintSizeCases_case.value));
+}
+
+// -------------------------------------------------------------------
+// Fixed-size int tests
+
+struct Fixed32Case {
+ uint8 bytes[sizeof(uint32)]; // Encoded bytes.
+ uint32 value; // Parsed value.
+};
+
+struct Fixed64Case {
+ uint8 bytes[sizeof(uint64)]; // Encoded bytes.
+ uint64 value; // Parsed value.
+};
+
+inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) {
+ return os << "0x" << hex << c.value << dec;
+}
+
+inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) {
+ return os << "0x" << hex << c.value << dec;
+}
+
+Fixed32Case kFixed32Cases[] = {
+ {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu},
+ {{0x12, 0x34, 0x56, 0x78}, 0x78563412u},
+};
+
+Fixed64Case kFixed64Cases[] = {
+ {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)},
+ {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)},
+};
+
+TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) {
+ memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint32 value;
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(kFixed32Cases_case.value, value);
+ }
+
+ EXPECT_EQ(sizeof(uint32), input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) {
+ memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ uint64 value;
+ EXPECT_TRUE(coded_input.ReadLittleEndian64(&value));
+ EXPECT_EQ(kFixed64Cases_case.value, value);
+ }
+
+ EXPECT_EQ(sizeof(uint64), input.ByteCount());
+}
+
+TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteLittleEndian32(kFixed32Cases_case.value);
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(sizeof(uint32), coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(sizeof(uint32), output.ByteCount());
+ EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32)));
+}
+
+TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteLittleEndian64(kFixed64Cases_case.value);
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(sizeof(uint64), coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(sizeof(uint64), output.ByteCount());
+ EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64)));
+}
+
+// Tests using the static methods to read fixed-size values from raw arrays.
+
+TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) {
+ memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
+
+ uint32 value;
+ const uint8* end = CodedInputStream::ReadLittleEndian32FromArray(
+ buffer_, &value);
+ EXPECT_EQ(kFixed32Cases_case.value, value);
+ EXPECT_TRUE(end == buffer_ + sizeof(value));
+}
+
+TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) {
+ memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
+
+ uint64 value;
+ const uint8* end = CodedInputStream::ReadLittleEndian64FromArray(
+ buffer_, &value);
+ EXPECT_EQ(kFixed64Cases_case.value, value);
+ EXPECT_TRUE(end == buffer_ + sizeof(value));
+}
+
+// -------------------------------------------------------------------
+// Raw reads and writes
+
+const char kRawBytes[] = "Some bytes which will be written and read raw.";
+
+TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+ char read_buffer[sizeof(kRawBytes)];
+
+ {
+ CodedInputStream coded_input(&input);
+
+ EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes)));
+ EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes)));
+ }
+
+ EXPECT_EQ(sizeof(kRawBytes), input.ByteCount());
+}
+
+TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedOutputStream coded_output(&output);
+
+ coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes));
+ EXPECT_FALSE(coded_output.HadError());
+
+ EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount());
+ }
+
+ EXPECT_EQ(sizeof(kRawBytes), output.ByteCount());
+ EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes)));
+}
+
+TEST_1D(CodedStreamTest, ReadString, kBlockSizes) {
+ memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+ EXPECT_EQ(kRawBytes, str);
+ }
+
+ EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+// Check to make sure ReadString doesn't crash on impossibly large strings.
+TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ string str;
+ // Try to read a gigabyte.
+ EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+ }
+}
+
+TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) {
+ // Same test as above, except directly use a buffer. This used to cause
+ // crashes while the above did not.
+ uint8 buffer[8];
+ CodedInputStream coded_input(buffer, 8);
+ string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+}
+
+TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) {
+ scoped_array<uint8> buffer(new uint8[8]);
+ CodedInputStream coded_input(buffer.get(), 8);
+ string str;
+ EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+}
+
+
+// -------------------------------------------------------------------
+// Skip
+
+const char kSkipTestBytes[] =
+ "<Before skipping><To be skipped><After skipping>";
+const char kSkipOutputTestBytes[] =
+ "-----------------<To be skipped>----------------";
+
+TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
+ memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes));
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen("<Before skipping>")));
+ EXPECT_EQ("<Before skipping>", str);
+ EXPECT_TRUE(coded_input.Skip(strlen("<To be skipped>")));
+ EXPECT_TRUE(coded_input.ReadString(&str, strlen("<After skipping>")));
+ EXPECT_EQ("<After skipping>", str);
+ }
+
+ EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount());
+}
+
+// -------------------------------------------------------------------
+// GetDirectBufferPointer
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerInput) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), 8);
+ CodedInputStream coded_input(&input);
+
+ const void* ptr;
+ int size;
+
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Peeking again should return the same pointer.
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip forward in the same buffer then peek again.
+ EXPECT_TRUE(coded_input.Skip(3));
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 3, ptr);
+ EXPECT_EQ(5, size);
+
+ // Skip to end of buffer and peek -- should get next buffer.
+ EXPECT_TRUE(coded_input.Skip(5));
+ EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 8, ptr);
+ EXPECT_EQ(8, size);
+}
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), 8);
+ CodedInputStream coded_input(&input);
+
+ const void* ptr;
+ int size;
+
+ coded_input.GetDirectBufferPointerInline(&ptr, &size);
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Peeking again should return the same pointer.
+ coded_input.GetDirectBufferPointerInline(&ptr, &size);
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip forward in the same buffer then peek again.
+ EXPECT_TRUE(coded_input.Skip(3));
+ coded_input.GetDirectBufferPointerInline(&ptr, &size);
+ EXPECT_EQ(buffer_ + 3, ptr);
+ EXPECT_EQ(5, size);
+
+ // Skip to end of buffer and peek -- should return false and provide an empty
+ // buffer. It does not try to Refresh().
+ EXPECT_TRUE(coded_input.Skip(5));
+ coded_input.GetDirectBufferPointerInline(&ptr, &size);
+ EXPECT_EQ(buffer_ + 8, ptr);
+ EXPECT_EQ(0, size);
+}
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) {
+ ArrayOutputStream output(buffer_, sizeof(buffer_), 8);
+ CodedOutputStream coded_output(&output);
+
+ void* ptr;
+ int size;
+
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Peeking again should return the same pointer.
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip forward in the same buffer then peek again.
+ EXPECT_TRUE(coded_output.Skip(3));
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 3, ptr);
+ EXPECT_EQ(5, size);
+
+ // Skip to end of buffer and peek -- should get next buffer.
+ EXPECT_TRUE(coded_output.Skip(5));
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 8, ptr);
+ EXPECT_EQ(8, size);
+
+ // Skip over multiple buffers.
+ EXPECT_TRUE(coded_output.Skip(22));
+ EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+ EXPECT_EQ(buffer_ + 30, ptr);
+ EXPECT_EQ(2, size);
+}
+
+// -------------------------------------------------------------------
+// Limits
+
+TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit = coded_input.PushLimit(8);
+
+ // Read until we hit the limit.
+ uint32 value;
+ EXPECT_EQ(8, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit);
+
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ }
+
+ EXPECT_EQ(12, input.ByteCount());
+}
+
+// Test what happens when we push two limits where the second (top) one is
+// shorter.
+TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit1 = coded_input.PushLimit(8);
+ EXPECT_EQ(8, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit2 = coded_input.PushLimit(4);
+
+ uint32 value;
+
+ // Read until we hit limit2, the top and shortest limit.
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit2);
+
+ // Read until we hit limit1.
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit1);
+
+ // No more limits.
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ }
+
+ EXPECT_EQ(12, input.ByteCount());
+}
+
+// Test what happens when we push two limits where the second (top) one is
+// longer. In this case, the top limit is shortened to match the previous
+// limit.
+TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) {
+ ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+ {
+ CodedInputStream coded_input(&input);
+
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit1 = coded_input.PushLimit(4);
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ CodedInputStream::Limit limit2 = coded_input.PushLimit(8);
+
+ uint32 value;
+
+ // Read until we hit limit2. Except, wait! limit1 is shorter, so
+ // we end up hitting that first, despite having 4 bytes to go on
+ // limit2.
+ EXPECT_EQ(4, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit2);
+
+ // OK, popped limit2, now limit1 is on top, which we've already hit.
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+ EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_EQ(0, coded_input.BytesUntilLimit());
+
+ coded_input.PopLimit(limit1);
+
+ // No more limits.
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ }
+
+ EXPECT_EQ(8, input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ExpectAtEnd) {
+ // Test ExpectAtEnd(), which is based on limits.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+
+ EXPECT_FALSE(coded_input.ExpectAtEnd());
+
+ CodedInputStream::Limit limit = coded_input.PushLimit(4);
+
+ uint32 value;
+ EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
+ EXPECT_TRUE(coded_input.ExpectAtEnd());
+
+ coded_input.PopLimit(limit);
+ EXPECT_FALSE(coded_input.ExpectAtEnd());
+}
+
+TEST_F(CodedStreamTest, NegativeLimit) {
+ // Check what happens when we push a negative limit.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+
+ CodedInputStream::Limit limit = coded_input.PushLimit(-1234);
+ // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+ // "the limit is INT_MAX relative to the beginning of the stream".
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, NegativeLimitAfterReading) {
+ // Check what happens when we push a negative limit.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+ ASSERT_TRUE(coded_input.Skip(128));
+
+ CodedInputStream::Limit limit = coded_input.PushLimit(-64);
+ // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+ // "the limit is INT_MAX relative to the beginning of the stream".
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, OverflowLimit) {
+ // Check what happens when we push a limit large enough that its absolute
+ // position is more than 2GB into the stream.
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+ ASSERT_TRUE(coded_input.Skip(128));
+
+ CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX);
+ // BytesUntilLimit() returns -1 to mean "no limit", which actually means
+ // "the limit is INT_MAX relative to the beginning of the stream".
+ EXPECT_EQ(-1, coded_input.BytesUntilLimit());
+ coded_input.PopLimit(limit);
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimit) {
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+ coded_input.SetTotalBytesLimit(16, -1);
+
+ string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, 16));
+
+ vector<string> errors;
+
+ {
+ ScopedMemoryLog error_log;
+ EXPECT_FALSE(coded_input.ReadString(&str, 1));
+ errors = error_log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(1, errors.size());
+ EXPECT_PRED_FORMAT2(testing::IsSubstring,
+ "A protocol message was rejected because it was too big", errors[0]);
+
+ coded_input.SetTotalBytesLimit(32, -1);
+ EXPECT_TRUE(coded_input.ReadString(&str, 16));
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
+ // total_bytes_limit_ is not a valid place for a message to end.
+
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+
+ // Set both total_bytes_limit and a regular limit at 16 bytes.
+ coded_input.SetTotalBytesLimit(16, -1);
+ CodedInputStream::Limit limit = coded_input.PushLimit(16);
+
+ // Read 16 bytes.
+ string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, 16));
+
+ // Read a tag. Should fail, but report being a valid endpoint since it's
+ // a regular limit.
+ EXPECT_EQ(0, coded_input.ReadTag());
+ EXPECT_TRUE(coded_input.ConsumedEntireMessage());
+
+ // Pop the limit.
+ coded_input.PopLimit(limit);
+
+ // Read a tag. Should fail, and report *not* being a valid endpoint, since
+ // this time we're hitting the total bytes limit.
+ EXPECT_EQ(0, coded_input.ReadTag());
+ EXPECT_FALSE(coded_input.ConsumedEntireMessage());
+}
+
+
+TEST_F(CodedStreamTest, RecursionLimit) {
+ ArrayInputStream input(buffer_, sizeof(buffer_));
+ CodedInputStream coded_input(&input);
+ coded_input.SetRecursionLimit(4);
+
+ // This is way too much testing for a counter.
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6
+ coded_input.DecrementRecursionDepth(); // 5
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 6
+ coded_input.DecrementRecursionDepth(); // 5
+ coded_input.DecrementRecursionDepth(); // 4
+ coded_input.DecrementRecursionDepth(); // 3
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
+ coded_input.DecrementRecursionDepth(); // 4
+ coded_input.DecrementRecursionDepth(); // 3
+ coded_input.DecrementRecursionDepth(); // 2
+ coded_input.DecrementRecursionDepth(); // 1
+ coded_input.DecrementRecursionDepth(); // 0
+ coded_input.DecrementRecursionDepth(); // 0
+ coded_input.DecrementRecursionDepth(); // 0
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 1
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 2
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 3
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 4
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 5
+
+ coded_input.SetRecursionLimit(6);
+ EXPECT_TRUE(coded_input.IncrementRecursionDepth()); // 6
+ EXPECT_FALSE(coded_input.IncrementRecursionDepth()); // 7
+}
+
+class ReallyBigInputStream : public ZeroCopyInputStream {
+ public:
+ ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {}
+ ~ReallyBigInputStream() {}
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) {
+ // We only expect BackUp() to be called at the end.
+ EXPECT_EQ(0, backup_amount_);
+
+ switch (buffer_count_++) {
+ case 0:
+ *data = buffer_;
+ *size = sizeof(buffer_);
+ return true;
+ case 1:
+ // Return an enormously large buffer that, when combined with the 1k
+ // returned already, should overflow the total_bytes_read_ counter in
+ // CodedInputStream. Note that we'll only read the first 1024 bytes
+ // of this buffer so it's OK that we have it point at buffer_.
+ *data = buffer_;
+ *size = INT_MAX;
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ void BackUp(int count) {
+ backup_amount_ = count;
+ }
+
+ bool Skip(int count) { GOOGLE_LOG(FATAL) << "Not implemented."; return false; }
+ int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; }
+
+ int backup_amount_;
+
+ private:
+ char buffer_[1024];
+ int64 buffer_count_;
+};
+
+TEST_F(CodedStreamTest, InputOver2G) {
+ // CodedInputStream should gracefully handle input over 2G and call
+ // input.BackUp() with the correct number of bytes on destruction.
+ ReallyBigInputStream input;
+
+ vector<string> errors;
+
+ {
+ ScopedMemoryLog error_log;
+ CodedInputStream coded_input(&input);
+ string str;
+ EXPECT_TRUE(coded_input.ReadString(&str, 512));
+ EXPECT_TRUE(coded_input.ReadString(&str, 1024));
+ errors = error_log.GetMessages(ERROR);
+ }
+
+ EXPECT_EQ(INT_MAX - 512, input.backup_amount_);
+ EXPECT_EQ(0, errors.size());
+}
+
+// ===================================================================
+
+
+} // namespace
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/gzip_stream.cc b/src/third_party/protobuf/src/google/protobuf/io/gzip_stream.cc
new file mode 100644
index 0000000..0f1ff87
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/gzip_stream.cc
@@ -0,0 +1,335 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+//
+// This file contains the implementation of classes GzipInputStream and
+// GzipOutputStream.
+
+#include "config.h"
+
+#if HAVE_ZLIB
+#include <google/protobuf/io/gzip_stream.h>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+static const int kDefaultBufferSize = 65536;
+
+GzipInputStream::GzipInputStream(
+ ZeroCopyInputStream* sub_stream, Format format, int buffer_size)
+ : format_(format), sub_stream_(sub_stream), zerror_(Z_OK) {
+ zcontext_.zalloc = Z_NULL;
+ zcontext_.zfree = Z_NULL;
+ zcontext_.opaque = Z_NULL;
+ zcontext_.total_out = 0;
+ zcontext_.next_in = NULL;
+ zcontext_.avail_in = 0;
+ zcontext_.total_in = 0;
+ zcontext_.msg = NULL;
+ if (buffer_size == -1) {
+ output_buffer_length_ = kDefaultBufferSize;
+ } else {
+ output_buffer_length_ = buffer_size;
+ }
+ output_buffer_ = operator new(output_buffer_length_);
+ GOOGLE_CHECK(output_buffer_ != NULL);
+ zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
+ zcontext_.avail_out = output_buffer_length_;
+ output_position_ = output_buffer_;
+}
+GzipInputStream::~GzipInputStream() {
+ operator delete(output_buffer_);
+ zerror_ = inflateEnd(&zcontext_);
+}
+
+static inline int internalInflateInit2(
+ z_stream* zcontext, GzipInputStream::Format format) {
+ int windowBitsFormat = 0;
+ switch (format) {
+ case GzipInputStream::GZIP: windowBitsFormat = 16; break;
+ case GzipInputStream::AUTO: windowBitsFormat = 32; break;
+ case GzipInputStream::ZLIB: windowBitsFormat = 0; break;
+ }
+ return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat);
+}
+
+int GzipInputStream::Inflate(int flush) {
+ if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
+ // previous inflate filled output buffer. don't change input params yet.
+ } else if (zcontext_.avail_in == 0) {
+ const void* in;
+ int in_size;
+ bool first = zcontext_.next_in == NULL;
+ bool ok = sub_stream_->Next(&in, &in_size);
+ if (!ok) {
+ zcontext_.next_out = NULL;
+ zcontext_.avail_out = 0;
+ return Z_STREAM_END;
+ }
+ zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in));
+ zcontext_.avail_in = in_size;
+ if (first) {
+ int error = internalInflateInit2(&zcontext_, format_);
+ if (error != Z_OK) {
+ return error;
+ }
+ }
+ }
+ zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
+ zcontext_.avail_out = output_buffer_length_;
+ output_position_ = output_buffer_;
+ int error = inflate(&zcontext_, flush);
+ return error;
+}
+
+void GzipInputStream::DoNextOutput(const void** data, int* size) {
+ *data = output_position_;
+ *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_);
+ output_position_ = zcontext_.next_out;
+}
+
+// implements ZeroCopyInputStream ----------------------------------
+bool GzipInputStream::Next(const void** data, int* size) {
+ bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
+ || (zerror_ == Z_BUF_ERROR);
+ if ((!ok) || (zcontext_.next_out == NULL)) {
+ return false;
+ }
+ if (zcontext_.next_out != output_position_) {
+ DoNextOutput(data, size);
+ return true;
+ }
+ if (zerror_ == Z_STREAM_END) {
+ if (zcontext_.next_out != NULL) {
+ // sub_stream_ may have concatenated streams to follow
+ zerror_ = inflateEnd(&zcontext_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ zerror_ = internalInflateInit2(&zcontext_, format_);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ } else {
+ *data = NULL;
+ *size = 0;
+ return false;
+ }
+ }
+ zerror_ = Inflate(Z_NO_FLUSH);
+ if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
+ // The underlying stream's Next returned false inside Inflate.
+ return false;
+ }
+ ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
+ || (zerror_ == Z_BUF_ERROR);
+ if (!ok) {
+ return false;
+ }
+ DoNextOutput(data, size);
+ return true;
+}
+void GzipInputStream::BackUp(int count) {
+ output_position_ = reinterpret_cast<void*>(
+ reinterpret_cast<uintptr_t>(output_position_) - count);
+}
+bool GzipInputStream::Skip(int count) {
+ const void* data;
+ int size;
+ bool ok = Next(&data, &size);
+ while (ok && (size < count)) {
+ count -= size;
+ ok = Next(&data, &size);
+ }
+ if (size > count) {
+ BackUp(size - count);
+ }
+ return ok;
+}
+int64 GzipInputStream::ByteCount() const {
+ return zcontext_.total_out +
+ (((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_));
+}
+
+// =========================================================================
+
+GzipOutputStream::Options::Options()
+ : format(GZIP),
+ buffer_size(kDefaultBufferSize),
+ compression_level(Z_DEFAULT_COMPRESSION),
+ compression_strategy(Z_DEFAULT_STRATEGY) {}
+
+GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) {
+ Init(sub_stream, Options());
+}
+
+GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream,
+ const Options& options) {
+ Init(sub_stream, options);
+}
+
+GzipOutputStream::GzipOutputStream(
+ ZeroCopyOutputStream* sub_stream, Format format, int buffer_size) {
+ Options options;
+ options.format = format;
+ if (buffer_size != -1) {
+ options.buffer_size = buffer_size;
+ }
+ Init(sub_stream, options);
+}
+
+void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
+ const Options& options) {
+ sub_stream_ = sub_stream;
+ sub_data_ = NULL;
+ sub_data_size_ = 0;
+
+ input_buffer_length_ = options.buffer_size;
+ input_buffer_ = operator new(input_buffer_length_);
+ GOOGLE_CHECK(input_buffer_ != NULL);
+
+ zcontext_.zalloc = Z_NULL;
+ zcontext_.zfree = Z_NULL;
+ zcontext_.opaque = Z_NULL;
+ zcontext_.next_out = NULL;
+ zcontext_.avail_out = 0;
+ zcontext_.total_out = 0;
+ zcontext_.next_in = NULL;
+ zcontext_.avail_in = 0;
+ zcontext_.total_in = 0;
+ zcontext_.msg = NULL;
+ // default to GZIP format
+ int windowBitsFormat = 16;
+ if (options.format == ZLIB) {
+ windowBitsFormat = 0;
+ }
+ zerror_ = deflateInit2(
+ &zcontext_,
+ options.compression_level,
+ Z_DEFLATED,
+ /* windowBits */15 | windowBitsFormat,
+ /* memLevel (default) */8,
+ options.compression_strategy);
+}
+
+GzipOutputStream::~GzipOutputStream() {
+ Close();
+ if (input_buffer_ != NULL) {
+ operator delete(input_buffer_);
+ }
+}
+
+// private
+int GzipOutputStream::Deflate(int flush) {
+ int error = Z_OK;
+ do {
+ if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) {
+ bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_);
+ if (!ok) {
+ sub_data_ = NULL;
+ sub_data_size_ = 0;
+ return Z_BUF_ERROR;
+ }
+ GOOGLE_CHECK_GT(sub_data_size_, 0);
+ zcontext_.next_out = static_cast<Bytef*>(sub_data_);
+ zcontext_.avail_out = sub_data_size_;
+ }
+ error = deflate(&zcontext_, flush);
+ } while (error == Z_OK && zcontext_.avail_out == 0);
+ if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
+ // Notify lower layer of data.
+ sub_stream_->BackUp(zcontext_.avail_out);
+ // We don't own the buffer anymore.
+ sub_data_ = NULL;
+ sub_data_size_ = 0;
+ }
+ return error;
+}
+
+// implements ZeroCopyOutputStream ---------------------------------
+bool GzipOutputStream::Next(void** data, int* size) {
+ if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
+ return false;
+ }
+ if (zcontext_.avail_in != 0) {
+ zerror_ = Deflate(Z_NO_FLUSH);
+ if (zerror_ != Z_OK) {
+ return false;
+ }
+ }
+ if (zcontext_.avail_in == 0) {
+ // all input was consumed. reset the buffer.
+ zcontext_.next_in = static_cast<Bytef*>(input_buffer_);
+ zcontext_.avail_in = input_buffer_length_;
+ *data = input_buffer_;
+ *size = input_buffer_length_;
+ } else {
+ // The loop in Deflate should consume all avail_in
+ GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed";
+ }
+ return true;
+}
+void GzipOutputStream::BackUp(int count) {
+ GOOGLE_CHECK_GE(zcontext_.avail_in, count);
+ zcontext_.avail_in -= count;
+}
+int64 GzipOutputStream::ByteCount() const {
+ return zcontext_.total_in + zcontext_.avail_in;
+}
+
+bool GzipOutputStream::Flush() {
+ do {
+ zerror_ = Deflate(Z_FULL_FLUSH);
+ } while (zerror_ == Z_OK);
+ return zerror_ == Z_OK;
+}
+
+bool GzipOutputStream::Close() {
+ if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
+ return false;
+ }
+ do {
+ zerror_ = Deflate(Z_FINISH);
+ } while (zerror_ == Z_OK);
+ zerror_ = deflateEnd(&zcontext_);
+ bool ok = zerror_ == Z_OK;
+ zerror_ = Z_STREAM_END;
+ return ok;
+}
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
+
+#endif // HAVE_ZLIB
diff --git a/src/third_party/protobuf/src/google/protobuf/io/gzip_stream.h b/src/third_party/protobuf/src/google/protobuf/io/gzip_stream.h
new file mode 100644
index 0000000..65dbc5b
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/gzip_stream.h
@@ -0,0 +1,207 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+//
+// This file contains the definition for classes GzipInputStream and
+// GzipOutputStream.
+//
+// GzipInputStream decompresses data from an underlying
+// ZeroCopyInputStream and provides the decompressed data as a
+// ZeroCopyInputStream.
+//
+// GzipOutputStream is an ZeroCopyOutputStream that compresses data to
+// an underlying ZeroCopyOutputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
+#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
+
+#include <zlib.h>
+
+#include <google/protobuf/io/zero_copy_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// A ZeroCopyInputStream that reads compressed data through zlib
+class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream {
+ public:
+ // Format key for constructor
+ enum Format {
+ // zlib will autodetect gzip header or deflate stream
+ AUTO = 0,
+
+ // GZIP streams have some extra header data for file attributes.
+ GZIP = 1,
+
+ // Simpler zlib stream format.
+ ZLIB = 2,
+ };
+
+ // buffer_size and format may be -1 for default of 64kB and GZIP format
+ explicit GzipInputStream(
+ ZeroCopyInputStream* sub_stream,
+ Format format = AUTO,
+ int buffer_size = -1);
+ virtual ~GzipInputStream();
+
+ // Return last error message or NULL if no error.
+ inline const char* ZlibErrorMessage() const {
+ return zcontext_.msg;
+ }
+ inline int ZlibErrorCode() const {
+ return zerror_;
+ }
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size);
+ void BackUp(int count);
+ bool Skip(int count);
+ int64 ByteCount() const;
+
+ private:
+ Format format_;
+
+ ZeroCopyInputStream* sub_stream_;
+
+ z_stream zcontext_;
+ int zerror_;
+
+ void* output_buffer_;
+ void* output_position_;
+ size_t output_buffer_length_;
+
+ int Inflate(int flush);
+ void DoNextOutput(const void** data, int* size);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
+};
+
+
+class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Format key for constructor
+ enum Format {
+ // GZIP streams have some extra header data for file attributes.
+ GZIP = 1,
+
+ // Simpler zlib stream format.
+ ZLIB = 2,
+ };
+
+ struct Options {
+ // Defaults to GZIP.
+ Format format;
+
+ // What size buffer to use internally. Defaults to 64kB.
+ int buffer_size;
+
+ // A number between 0 and 9, where 0 is no compression and 9 is best
+ // compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).
+ int compression_level;
+
+ // Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED,
+ // Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in
+ // zlib.h for definitions of these constants.
+ int compression_strategy;
+
+ Options(); // Initializes with default values.
+ };
+
+ // Create a GzipOutputStream with default options.
+ explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream);
+
+ // Create a GzipOutputStream with the given options.
+ GzipOutputStream(
+ ZeroCopyOutputStream* sub_stream,
+ const Options& options);
+
+ // DEPRECATED: Use one of the above constructors instead.
+ GzipOutputStream(
+ ZeroCopyOutputStream* sub_stream,
+ Format format,
+ int buffer_size = -1) GOOGLE_ATTRIBUTE_DEPRECATED;
+
+ virtual ~GzipOutputStream();
+
+ // Return last error message or NULL if no error.
+ inline const char* ZlibErrorMessage() const {
+ return zcontext_.msg;
+ }
+ inline int ZlibErrorCode() const {
+ return zerror_;
+ }
+
+ // Flushes data written so far to zipped data in the underlying stream.
+ // It is the caller's responsibility to flush the underlying stream if
+ // necessary.
+ // Compression may be less efficient stopping and starting around flushes.
+ // Returns true if no error.
+ bool Flush();
+
+ // Writes out all data and closes the gzip stream.
+ // It is the caller's responsibility to close the underlying stream if
+ // necessary.
+ // Returns true if no error.
+ bool Close();
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size);
+ void BackUp(int count);
+ int64 ByteCount() const;
+
+ private:
+ ZeroCopyOutputStream* sub_stream_;
+ // Result from calling Next() on sub_stream_
+ void* sub_data_;
+ int sub_data_size_;
+
+ z_stream zcontext_;
+ int zerror_;
+ void* input_buffer_;
+ size_t input_buffer_length_;
+
+ // Shared constructor code.
+ void Init(ZeroCopyOutputStream* sub_stream, const Options& options);
+
+ // Do some compression.
+ // Takes zlib flush mode.
+ // Returns zlib error code.
+ int Deflate(int flush);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream);
+};
+
+} // namespace io
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/gzip_stream_unittest.sh b/src/third_party/protobuf/src/google/protobuf/io/gzip_stream_unittest.sh
new file mode 100755
index 0000000..6e8a094
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/gzip_stream_unittest.sh
@@ -0,0 +1,44 @@
+#!/bin/sh -x
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2009 Google Inc. All rights reserved.
+# http://code.google.com/p/protobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: brianolson@google.com (Brian Olson)
+#
+# Test compatibility between command line gzip/gunzip binaries and
+# ZeroCopyStream versions.
+
+TESTFILE=Makefile
+
+(./zcgzip < ${TESTFILE} | gunzip | cmp - ${TESTFILE}) && \
+(gzip < ${TESTFILE} | ./zcgunzip | cmp - ${TESTFILE})
+
+# Result of "(cmd) && (cmd)" implicitly becomes result of this script
+# and thus the test.
diff --git a/src/third_party/protobuf/src/google/protobuf/io/package_info.h b/src/third_party/protobuf/src/google/protobuf/io/package_info.h
new file mode 100644
index 0000000..7a7a4e7
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/package_info.h
@@ -0,0 +1,54 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file exists solely to document the google::protobuf::io namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+
+namespace protobuf {
+
+// Auxiliary classes used for I/O.
+//
+// The Protocol Buffer library uses the classes in this package to deal with
+// I/O and encoding/decoding raw bytes. Most users will not need to
+// deal with this package. However, users who want to adapt the system to
+// work with their own I/O abstractions -- e.g., to allow Protocol Buffers
+// to be read from a different kind of input stream without the need for a
+// temporary buffer -- should take a closer look.
+namespace io {}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/printer.cc b/src/third_party/protobuf/src/google/protobuf/io/printer.cc
new file mode 100644
index 0000000..9ab90de
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/printer.cc
@@ -0,0 +1,199 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
+ : variable_delimiter_(variable_delimiter),
+ output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ at_start_of_line_(true),
+ failed_(false) {
+}
+
+Printer::~Printer() {
+ // Only BackUp() if we're sure we've successfully called Next() at least once.
+ if (buffer_size_ > 0) {
+ output_->BackUp(buffer_size_);
+ }
+}
+
+void Printer::Print(const map<string, string>& variables, const char* text) {
+ int size = strlen(text);
+ int pos = 0; // The number of bytes we've written so far.
+
+ for (int i = 0; i < size; i++) {
+ if (text[i] == '\n') {
+ // Saw newline. If there is more text, we may need to insert an indent
+ // here. So, write what we have so far, including the '\n'.
+ WriteRaw(text + pos, i - pos + 1);
+ pos = i + 1;
+
+ // Setting this true will cause the next WriteRaw() to insert an indent
+ // first.
+ at_start_of_line_ = true;
+
+ } else if (text[i] == variable_delimiter_) {
+ // Saw the start of a variable name.
+
+ // Write what we have so far.
+ WriteRaw(text + pos, i - pos);
+ pos = i + 1;
+
+ // Find closing delimiter.
+ const char* end = strchr(text + pos, variable_delimiter_);
+ if (end == NULL) {
+ GOOGLE_LOG(DFATAL) << " Unclosed variable name.";
+ end = text + pos;
+ }
+ int endpos = end - text;
+
+ string varname(text + pos, endpos - pos);
+ if (varname.empty()) {
+ // Two delimiters in a row reduce to a literal delimiter character.
+ WriteRaw(&variable_delimiter_, 1);
+ } else {
+ // Replace with the variable's value.
+ map<string, string>::const_iterator iter = variables.find(varname);
+ if (iter == variables.end()) {
+ GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname;
+ } else {
+ WriteRaw(iter->second.data(), iter->second.size());
+ }
+ }
+
+ // Advance past this variable.
+ i = endpos;
+ pos = endpos + 1;
+ }
+ }
+
+ // Write the rest.
+ WriteRaw(text + pos, size - pos);
+}
+
+void Printer::Print(const char* text) {
+ static map<string, string> empty;
+ Print(empty, text);
+}
+
+void Printer::Print(const char* text,
+ const char* variable, const string& value) {
+ map<string, string> vars;
+ vars[variable] = value;
+ Print(vars, text);
+}
+
+void Printer::Print(const char* text,
+ const char* variable1, const string& value1,
+ const char* variable2, const string& value2) {
+ map<string, string> vars;
+ vars[variable1] = value1;
+ vars[variable2] = value2;
+ Print(vars, text);
+}
+
+void Printer::Print(const char* text,
+ const char* variable1, const string& value1,
+ const char* variable2, const string& value2,
+ const char* variable3, const string& value3) {
+ map<string, string> vars;
+ vars[variable1] = value1;
+ vars[variable2] = value2;
+ vars[variable3] = value3;
+ Print(vars, text);
+}
+
+void Printer::Indent() {
+ indent_ += " ";
+}
+
+void Printer::Outdent() {
+ if (indent_.empty()) {
+ GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
+ return;
+ }
+
+ indent_.resize(indent_.size() - 2);
+}
+
+void Printer::PrintRaw(const string& data) {
+ WriteRaw(data.data(), data.size());
+}
+
+void Printer::PrintRaw(const char* data) {
+ if (failed_) return;
+ WriteRaw(data, strlen(data));
+}
+
+void Printer::WriteRaw(const char* data, int size) {
+ if (failed_) return;
+ if (size == 0) return;
+
+ if (at_start_of_line_) {
+ // Insert an indent.
+ at_start_of_line_ = false;
+ WriteRaw(indent_.data(), indent_.size());
+ if (failed_) return;
+ }
+
+ while (size > buffer_size_) {
+ // Data exceeds space in the buffer. Copy what we can and request a
+ // new buffer.
+ memcpy(buffer_, data, buffer_size_);
+ data += buffer_size_;
+ size -= buffer_size_;
+ void* void_buffer;
+ failed_ = !output_->Next(&void_buffer, &buffer_size_);
+ if (failed_) return;
+ buffer_ = reinterpret_cast<char*>(void_buffer);
+ }
+
+ // Buffer is big enough to receive the data; copy it.
+ memcpy(buffer_, data, size);
+ buffer_ += size;
+ buffer_size_ -= size;
+}
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/printer.h b/src/third_party/protobuf/src/google/protobuf/io/printer.h
new file mode 100644
index 0000000..5be4854
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/printer.h
@@ -0,0 +1,136 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Utility class for writing text to a ZeroCopyOutputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__
+#define GOOGLE_PROTOBUF_IO_PRINTER_H__
+
+#include <string>
+#include <map>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+class ZeroCopyOutputStream; // zero_copy_stream.h
+
+// This simple utility class assists in code generation. It basically
+// allows the caller to define a set of variables and then output some
+// text with variable substitutions. Example usage:
+//
+// Printer printer(output, '$');
+// map<string, string> vars;
+// vars["name"] = "Bob";
+// printer.Print(vars, "My name is $name$.");
+//
+// The above writes "My name is Bob." to the output stream.
+//
+// Printer aggressively enforces correct usage, crashing (with assert failures)
+// in the case of undefined variables in debug builds. This helps greatly in
+// debugging code which uses it.
+class LIBPROTOBUF_EXPORT Printer {
+ public:
+ // Create a printer that writes text to the given output stream. Use the
+ // given character as the delimiter for variables.
+ Printer(ZeroCopyOutputStream* output, char variable_delimiter);
+ ~Printer();
+
+ // Print some text after applying variable substitutions. If a particular
+ // variable in the text is not defined, this will crash. Variables to be
+ // substituted are identified by their names surrounded by delimiter
+ // characters (as given to the constructor). The variable bindings are
+ // defined by the given map.
+ void Print(const map<string, string>& variables, const char* text);
+
+ // Like the first Print(), except the substitutions are given as parameters.
+ void Print(const char* text);
+ // Like the first Print(), except the substitutions are given as parameters.
+ void Print(const char* text, const char* variable, const string& value);
+ // Like the first Print(), except the substitutions are given as parameters.
+ void Print(const char* text, const char* variable1, const string& value1,
+ const char* variable2, const string& value2);
+ // Like the first Print(), except the substitutions are given as parameters.
+ void Print(const char* text, const char* variable1, const string& value1,
+ const char* variable2, const string& value2,
+ const char* variable3, const string& value3);
+ // TODO(kenton): Overloaded versions with more variables? Three seems
+ // to be enough.
+
+ // Indent text by two spaces. After calling Indent(), two spaces will be
+ // inserted at the beginning of each line of text. Indent() may be called
+ // multiple times to produce deeper indents.
+ void Indent();
+
+ // Reduces the current indent level by two spaces, or crashes if the indent
+ // level is zero.
+ void Outdent();
+
+ // Write a string to the output buffer.
+ // This method does not look for newlines to add indentation.
+ void PrintRaw(const string& data);
+
+ // Write a zero-delimited string to output buffer.
+ // This method does not look for newlines to add indentation.
+ void PrintRaw(const char* data);
+
+ // Write some bytes to the output buffer.
+ // This method does not look for newlines to add indentation.
+ void WriteRaw(const char* data, int size);
+
+ // True if any write to the underlying stream failed. (We don't just
+ // crash in this case because this is an I/O failure, not a programming
+ // error.)
+ bool failed() const { return failed_; }
+
+ private:
+ const char variable_delimiter_;
+
+ ZeroCopyOutputStream* const output_;
+ char* buffer_;
+ int buffer_size_;
+
+ string indent_;
+ bool at_start_of_line_;
+ bool failed_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer);
+};
+
+} // namespace io
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/printer_unittest.cc b/src/third_party/protobuf/src/google/protobuf/io/printer_unittest.cc
new file mode 100644
index 0000000..580a53d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/printer_unittest.cc
@@ -0,0 +1,261 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// Each test repeats over several block sizes in order to test both cases
+// where particular writes cross a buffer boundary and cases where they do
+// not.
+
+TEST(Printer, EmptyPrinter) {
+ char buffer[8192];
+ const int block_size = 100;
+ ArrayOutputStream output(buffer, GOOGLE_ARRAYSIZE(buffer), block_size);
+ Printer printer(&output, '\0');
+ EXPECT_TRUE(!printer.failed());
+}
+
+TEST(Printer, BasicPrinting) {
+ char buffer[8192];
+
+ for (int block_size = 1; block_size < 512; block_size *= 2) {
+ ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+ {
+ Printer printer(&output, '\0');
+
+ printer.Print("Hello World!");
+ printer.Print(" This is the same line.\n");
+ printer.Print("But this is a new one.\nAnd this is another one.");
+
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ("Hello World! This is the same line.\n"
+ "But this is a new one.\n"
+ "And this is another one.",
+ buffer);
+ }
+}
+
+TEST(Printer, WriteRaw) {
+ char buffer[8192];
+
+ for (int block_size = 1; block_size < 512; block_size *= 2) {
+ ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+ {
+ string string_obj = "From an object\n";
+ Printer printer(&output, '$');
+ printer.WriteRaw("Hello World!", 12);
+ printer.PrintRaw(" This is the same line.\n");
+ printer.PrintRaw("But this is a new one.\nAnd this is another one.");
+ printer.WriteRaw("\n", 1);
+ printer.PrintRaw(string_obj);
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ("Hello World! This is the same line.\n"
+ "But this is a new one.\n"
+ "And this is another one."
+ "\n"
+ "From an object\n",
+ buffer);
+ }
+}
+
+TEST(Printer, VariableSubstitution) {
+ char buffer[8192];
+
+ for (int block_size = 1; block_size < 512; block_size *= 2) {
+ ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+ {
+ Printer printer(&output, '$');
+ map<string, string> vars;
+
+ vars["foo"] = "World";
+ vars["bar"] = "$foo$";
+ vars["abcdefg"] = "1234";
+
+ printer.Print(vars, "Hello $foo$!\nbar = $bar$\n");
+ printer.PrintRaw("RawBit\n");
+ printer.Print(vars, "$abcdefg$\nA literal dollar sign: $$");
+
+ vars["foo"] = "blah";
+ printer.Print(vars, "\nNow foo = $foo$.");
+
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ("Hello World!\n"
+ "bar = $foo$\n"
+ "RawBit\n"
+ "1234\n"
+ "A literal dollar sign: $\n"
+ "Now foo = blah.",
+ buffer);
+ }
+}
+
+TEST(Printer, InlineVariableSubstitution) {
+ char buffer[8192];
+
+ ArrayOutputStream output(buffer, sizeof(buffer));
+
+ {
+ Printer printer(&output, '$');
+ printer.Print("Hello $foo$!\n", "foo", "World");
+ printer.PrintRaw("RawBit\n");
+ printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two");
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ("Hello World!\n"
+ "RawBit\n"
+ "one two\n",
+ buffer);
+}
+
+TEST(Printer, Indenting) {
+ char buffer[8192];
+
+ for (int block_size = 1; block_size < 512; block_size *= 2) {
+ ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+ {
+ Printer printer(&output, '$');
+ map<string, string> vars;
+
+ vars["newline"] = "\n";
+
+ printer.Print("This is not indented.\n");
+ printer.Indent();
+ printer.Print("This is indented\nAnd so is this\n");
+ printer.Outdent();
+ printer.Print("But this is not.");
+ printer.Indent();
+ printer.Print(" And this is still the same line.\n"
+ "But this is indented.\n");
+ printer.PrintRaw("RawBit has indent at start\n");
+ printer.PrintRaw("but not after a raw newline\n");
+ printer.Print(vars, "Note that a newline in a variable will break "
+ "indenting, as we see$newline$here.\n");
+ printer.Indent();
+ printer.Print("And this");
+ printer.Outdent();
+ printer.Outdent();
+ printer.Print(" is double-indented\nBack to normal.");
+
+ EXPECT_FALSE(printer.failed());
+ }
+
+ buffer[output.ByteCount()] = '\0';
+
+ EXPECT_STREQ(
+ "This is not indented.\n"
+ " This is indented\n"
+ " And so is this\n"
+ "But this is not. And this is still the same line.\n"
+ " But this is indented.\n"
+ " RawBit has indent at start\n"
+ "but not after a raw newline\n"
+ "Note that a newline in a variable will break indenting, as we see\n"
+ "here.\n"
+ " And this is double-indented\n"
+ "Back to normal.",
+ buffer);
+ }
+}
+
+// Death tests do not work on Windows as of yet.
+#ifdef GTEST_HAS_DEATH_TEST
+TEST(Printer, Death) {
+ char buffer[8192];
+
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ Printer printer(&output, '$');
+
+ EXPECT_DEBUG_DEATH(printer.Print("$nosuchvar$"), "Undefined variable");
+ EXPECT_DEBUG_DEATH(printer.Print("$unclosed"), "Unclosed variable name");
+ EXPECT_DEBUG_DEATH(printer.Outdent(), "without matching Indent");
+}
+#endif // GTEST_HAS_DEATH_TEST
+
+TEST(Printer, WriteFailure) {
+ char buffer[16];
+
+ ArrayOutputStream output(buffer, sizeof(buffer));
+ Printer printer(&output, '$');
+
+ // Print 16 bytes to fill the buffer exactly (should not fail).
+ printer.Print("0123456789abcdef");
+ EXPECT_FALSE(printer.failed());
+
+ // Try to print one more byte (should fail).
+ printer.Print(" ");
+ EXPECT_TRUE(printer.failed());
+
+ // Should not crash
+ printer.Print("blah");
+ EXPECT_TRUE(printer.failed());
+
+ // Buffer should contain the first 16 bytes written.
+ EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer)));
+}
+
+} // namespace
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/tokenizer.cc b/src/third_party/protobuf/src/google/protobuf/io/tokenizer.cc
new file mode 100644
index 0000000..513831d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/tokenizer.cc
@@ -0,0 +1,694 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Here we have a hand-written lexer. At first you might ask yourself,
+// "Hand-written text processing? Is Kenton crazy?!" Well, first of all,
+// yes I am crazy, but that's beside the point. There are actually reasons
+// why I ended up writing this this way.
+//
+// The traditional approach to lexing is to use lex to generate a lexer for
+// you. Unfortunately, lex's output is ridiculously ugly and difficult to
+// integrate cleanly with C++ code, especially abstract code or code meant
+// as a library. Better parser-generators exist but would add dependencies
+// which most users won't already have, which we'd like to avoid. (GNU flex
+// has a C++ output option, but it's still ridiculously ugly, non-abstract,
+// and not library-friendly.)
+//
+// The next approach that any good software engineer should look at is to
+// use regular expressions. And, indeed, I did. I have code which
+// implements this same class using regular expressions. It's about 200
+// lines shorter. However:
+// - Rather than error messages telling you "This string has an invalid
+// escape sequence at line 5, column 45", you get error messages like
+// "Parse error on line 5". Giving more precise errors requires adding
+// a lot of code that ends up basically as complex as the hand-coded
+// version anyway.
+// - The regular expression to match a string literal looks like this:
+// kString = new RE("(\"([^\"\\\\]|" // non-escaped
+// "\\\\[abfnrtv?\"'\\\\0-7]|" // normal escape
+// "\\\\x[0-9a-fA-F])*\"|" // hex escape
+// "\'([^\'\\\\]|" // Also support single-quotes.
+// "\\\\[abfnrtv?\"'\\\\0-7]|"
+// "\\\\x[0-9a-fA-F])*\')");
+// Verifying the correctness of this line noise is actually harder than
+// verifying the correctness of ConsumeString(), defined below. I'm not
+// even confident that the above is correct, after staring at it for some
+// time.
+// - PCRE is fast, but there's still more overhead involved than the code
+// below.
+// - Sadly, regular expressions are not part of the C standard library, so
+// using them would require depending on some other library. For the
+// open source release, this could be really annoying. Nobody likes
+// downloading one piece of software just to find that they need to
+// download something else to make it work, and in all likelihood
+// people downloading Protocol Buffers will already be doing so just
+// to make something else work. We could include a copy of PCRE with
+// our code, but that obligates us to keep it up-to-date and just seems
+// like a big waste just to save 200 lines of code.
+//
+// On a similar but unrelated note, I'm even scared to use ctype.h.
+// Apparently functions like isalpha() are locale-dependent. So, if we used
+// that, then if this code is being called from some program that doesn't
+// have its locale set to "C", it would behave strangely. We can't just set
+// the locale to "C" ourselves since we might break the calling program that
+// way, particularly if it is multi-threaded. WTF? Someone please let me
+// (Kenton) know if I'm missing something here...
+//
+// I'd love to hear about other alternatives, though, as this code isn't
+// exactly pretty.
+
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// As mentioned above, I don't trust ctype.h due to the presence of "locales".
+// So, I have written replacement functions here. Someone please smack me if
+// this is a bad idea or if there is some way around this.
+//
+// These "character classes" are designed to be used in template methods.
+// For instance, Tokenizer::ConsumeZeroOrMore<Whitespace>() will eat
+// whitespace.
+
+// Note: No class is allowed to contain '\0', since this is used to mark end-
+// of-input and is handled specially.
+
+#define CHARACTER_CLASS(NAME, EXPRESSION) \
+ class NAME { \
+ public: \
+ static inline bool InClass(char c) { \
+ return EXPRESSION; \
+ } \
+ }
+
+CHARACTER_CLASS(Whitespace, c == ' ' || c == '\n' || c == '\t' ||
+ c == '\r' || c == '\v' || c == '\f');
+
+CHARACTER_CLASS(Unprintable, c < ' ' && c > '\0');
+
+CHARACTER_CLASS(Digit, '0' <= c && c <= '9');
+CHARACTER_CLASS(OctalDigit, '0' <= c && c <= '7');
+CHARACTER_CLASS(HexDigit, ('0' <= c && c <= '9') ||
+ ('a' <= c && c <= 'f') ||
+ ('A' <= c && c <= 'F'));
+
+CHARACTER_CLASS(Letter, ('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ (c == '_'));
+
+CHARACTER_CLASS(Alphanumeric, ('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ ('0' <= c && c <= '9') ||
+ (c == '_'));
+
+CHARACTER_CLASS(Escape, c == 'a' || c == 'b' || c == 'f' || c == 'n' ||
+ c == 'r' || c == 't' || c == 'v' || c == '\\' ||
+ c == '?' || c == '\'' || c == '\"');
+
+#undef CHARACTER_CLASS
+
+// Given a char, interpret it as a numeric digit and return its value.
+// This supports any number base up to 36.
+inline int DigitValue(char digit) {
+ if ('0' <= digit && digit <= '9') return digit - '0';
+ if ('a' <= digit && digit <= 'z') return digit - 'a' + 10;
+ if ('A' <= digit && digit <= 'Z') return digit - 'A' + 10;
+ return -1;
+}
+
+// Inline because it's only used in one place.
+inline char TranslateEscape(char c) {
+ switch (c) {
+ case 'a': return '\a';
+ case 'b': return '\b';
+ case 'f': return '\f';
+ case 'n': return '\n';
+ case 'r': return '\r';
+ case 't': return '\t';
+ case 'v': return '\v';
+ case '\\': return '\\';
+ case '?': return '\?'; // Trigraphs = :(
+ case '\'': return '\'';
+ case '"': return '\"';
+
+ // We expect escape sequences to have been validated separately.
+ default: return '?';
+ }
+}
+
+} // anonymous namespace
+
+ErrorCollector::~ErrorCollector() {}
+
+// ===================================================================
+
+Tokenizer::Tokenizer(ZeroCopyInputStream* input,
+ ErrorCollector* error_collector)
+ : input_(input),
+ error_collector_(error_collector),
+ buffer_(NULL),
+ buffer_size_(0),
+ buffer_pos_(0),
+ read_error_(false),
+ line_(0),
+ column_(0),
+ token_start_(-1),
+ allow_f_after_float_(false),
+ comment_style_(CPP_COMMENT_STYLE) {
+
+ current_.line = 0;
+ current_.column = 0;
+ current_.end_column = 0;
+ current_.type = TYPE_START;
+
+ Refresh();
+}
+
+Tokenizer::~Tokenizer() {
+ // If we had any buffer left unread, return it to the underlying stream
+ // so that someone else can read it.
+ if (buffer_size_ > buffer_pos_) {
+ input_->BackUp(buffer_size_ - buffer_pos_);
+ }
+}
+
+// -------------------------------------------------------------------
+// Internal helpers.
+
+void Tokenizer::NextChar() {
+ // Update our line and column counters based on the character being
+ // consumed.
+ if (current_char_ == '\n') {
+ ++line_;
+ column_ = 0;
+ } else if (current_char_ == '\t') {
+ column_ += kTabWidth - column_ % kTabWidth;
+ } else {
+ ++column_;
+ }
+
+ // Advance to the next character.
+ ++buffer_pos_;
+ if (buffer_pos_ < buffer_size_) {
+ current_char_ = buffer_[buffer_pos_];
+ } else {
+ Refresh();
+ }
+}
+
+void Tokenizer::Refresh() {
+ if (read_error_) {
+ current_char_ = '\0';
+ return;
+ }
+
+ // If we're in a token, append the rest of the buffer to it.
+ if (token_start_ >= 0 && token_start_ < buffer_size_) {
+ current_.text.append(buffer_ + token_start_, buffer_size_ - token_start_);
+ token_start_ = 0;
+ }
+
+ const void* data = NULL;
+ buffer_ = NULL;
+ buffer_pos_ = 0;
+ do {
+ if (!input_->Next(&data, &buffer_size_)) {
+ // end of stream (or read error)
+ buffer_size_ = 0;
+ read_error_ = true;
+ current_char_ = '\0';
+ return;
+ }
+ } while (buffer_size_ == 0);
+
+ buffer_ = static_cast<const char*>(data);
+
+ current_char_ = buffer_[0];
+}
+
+inline void Tokenizer::StartToken() {
+ token_start_ = buffer_pos_;
+ current_.type = TYPE_START; // Just for the sake of initializing it.
+ current_.text.clear();
+ current_.line = line_;
+ current_.column = column_;
+}
+
+inline void Tokenizer::EndToken() {
+ // Note: The if() is necessary because some STL implementations crash when
+ // you call string::append(NULL, 0), presumably because they are trying to
+ // be helpful by detecting the NULL pointer, even though there's nothing
+ // wrong with reading zero bytes from NULL.
+ if (buffer_pos_ != token_start_) {
+ current_.text.append(buffer_ + token_start_, buffer_pos_ - token_start_);
+ }
+ token_start_ = -1;
+ current_.end_column = column_;
+}
+
+// -------------------------------------------------------------------
+// Helper methods that consume characters.
+
+template<typename CharacterClass>
+inline bool Tokenizer::LookingAt() {
+ return CharacterClass::InClass(current_char_);
+}
+
+template<typename CharacterClass>
+inline bool Tokenizer::TryConsumeOne() {
+ if (CharacterClass::InClass(current_char_)) {
+ NextChar();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+inline bool Tokenizer::TryConsume(char c) {
+ if (current_char_ == c) {
+ NextChar();
+ return true;
+ } else {
+ return false;
+ }
+}
+
+template<typename CharacterClass>
+inline void Tokenizer::ConsumeZeroOrMore() {
+ while (CharacterClass::InClass(current_char_)) {
+ NextChar();
+ }
+}
+
+template<typename CharacterClass>
+inline void Tokenizer::ConsumeOneOrMore(const char* error) {
+ if (!CharacterClass::InClass(current_char_)) {
+ AddError(error);
+ } else {
+ do {
+ NextChar();
+ } while (CharacterClass::InClass(current_char_));
+ }
+}
+
+// -------------------------------------------------------------------
+// Methods that read whole patterns matching certain kinds of tokens
+// or comments.
+
+void Tokenizer::ConsumeString(char delimiter) {
+ while (true) {
+ switch (current_char_) {
+ case '\0':
+ case '\n': {
+ AddError("String literals cannot cross line boundaries.");
+ return;
+ }
+
+ case '\\': {
+ // An escape sequence.
+ NextChar();
+ if (TryConsumeOne<Escape>()) {
+ // Valid escape sequence.
+ } else if (TryConsumeOne<OctalDigit>()) {
+ // Possibly followed by two more octal digits, but these will
+ // just be consumed by the main loop anyway so we don't need
+ // to do so explicitly here.
+ } else if (TryConsume('x') || TryConsume('X')) {
+ if (!TryConsumeOne<HexDigit>()) {
+ AddError("Expected hex digits for escape sequence.");
+ }
+ // Possibly followed by another hex digit, but again we don't care.
+ } else {
+ AddError("Invalid escape sequence in string literal.");
+ }
+ break;
+ }
+
+ default: {
+ if (current_char_ == delimiter) {
+ NextChar();
+ return;
+ }
+ NextChar();
+ break;
+ }
+ }
+ }
+}
+
+Tokenizer::TokenType Tokenizer::ConsumeNumber(bool started_with_zero,
+ bool started_with_dot) {
+ bool is_float = false;
+
+ if (started_with_zero && (TryConsume('x') || TryConsume('X'))) {
+ // A hex number (started with "0x").
+ ConsumeOneOrMore<HexDigit>("\"0x\" must be followed by hex digits.");
+
+ } else if (started_with_zero && LookingAt<Digit>()) {
+ // An octal number (had a leading zero).
+ ConsumeZeroOrMore<OctalDigit>();
+ if (LookingAt<Digit>()) {
+ AddError("Numbers starting with leading zero must be in octal.");
+ ConsumeZeroOrMore<Digit>();
+ }
+
+ } else {
+ // A decimal number.
+ if (started_with_dot) {
+ is_float = true;
+ ConsumeZeroOrMore<Digit>();
+ } else {
+ ConsumeZeroOrMore<Digit>();
+
+ if (TryConsume('.')) {
+ is_float = true;
+ ConsumeZeroOrMore<Digit>();
+ }
+ }
+
+ if (TryConsume('e') || TryConsume('E')) {
+ is_float = true;
+ TryConsume('-') || TryConsume('+');
+ ConsumeOneOrMore<Digit>("\"e\" must be followed by exponent.");
+ }
+
+ if (allow_f_after_float_ && (TryConsume('f') || TryConsume('F'))) {
+ is_float = true;
+ }
+ }
+
+ if (LookingAt<Letter>()) {
+ AddError("Need space between number and identifier.");
+ } else if (current_char_ == '.') {
+ if (is_float) {
+ AddError(
+ "Already saw decimal point or exponent; can't have another one.");
+ } else {
+ AddError("Hex and octal numbers must be integers.");
+ }
+ }
+
+ return is_float ? TYPE_FLOAT : TYPE_INTEGER;
+}
+
+void Tokenizer::ConsumeLineComment() {
+ while (current_char_ != '\0' && current_char_ != '\n') {
+ NextChar();
+ }
+ TryConsume('\n');
+}
+
+void Tokenizer::ConsumeBlockComment() {
+ int start_line = line_;
+ int start_column = column_ - 2;
+
+ while (true) {
+ while (current_char_ != '\0' &&
+ current_char_ != '*' &&
+ current_char_ != '/') {
+ NextChar();
+ }
+
+ if (TryConsume('*') && TryConsume('/')) {
+ // End of comment.
+ break;
+ } else if (TryConsume('/') && current_char_ == '*') {
+ // Note: We didn't consume the '*' because if there is a '/' after it
+ // we want to interpret that as the end of the comment.
+ AddError(
+ "\"/*\" inside block comment. Block comments cannot be nested.");
+ } else if (current_char_ == '\0') {
+ AddError("End-of-file inside block comment.");
+ error_collector_->AddError(
+ start_line, start_column, " Comment started here.");
+ break;
+ }
+ }
+}
+
+// -------------------------------------------------------------------
+
+bool Tokenizer::Next() {
+ previous_ = current_;
+
+ // Did we skip any characters after the last token?
+ bool skipped_stuff = false;
+
+ while (!read_error_) {
+ if (TryConsumeOne<Whitespace>()) {
+ ConsumeZeroOrMore<Whitespace>();
+
+ } else if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) {
+ // Starting a comment?
+ if (TryConsume('/')) {
+ ConsumeLineComment();
+ } else if (TryConsume('*')) {
+ ConsumeBlockComment();
+ } else {
+ // Oops, it was just a slash. Return it.
+ current_.type = TYPE_SYMBOL;
+ current_.text = "/";
+ current_.line = line_;
+ current_.column = column_ - 1;
+ return true;
+ }
+
+ } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) {
+ ConsumeLineComment();
+
+ } else if (LookingAt<Unprintable>() || current_char_ == '\0') {
+ AddError("Invalid control characters encountered in text.");
+ NextChar();
+ // Skip more unprintable characters, too. But, remember that '\0' is
+ // also what current_char_ is set to after EOF / read error. We have
+ // to be careful not to go into an infinite loop of trying to consume
+ // it, so make sure to check read_error_ explicitly before consuming
+ // '\0'.
+ while (TryConsumeOne<Unprintable>() ||
+ (!read_error_ && TryConsume('\0'))) {
+ // Ignore.
+ }
+
+ } else {
+ // Reading some sort of token.
+ StartToken();
+
+ if (TryConsumeOne<Letter>()) {
+ ConsumeZeroOrMore<Alphanumeric>();
+ current_.type = TYPE_IDENTIFIER;
+ } else if (TryConsume('0')) {
+ current_.type = ConsumeNumber(true, false);
+ } else if (TryConsume('.')) {
+ // This could be the beginning of a floating-point number, or it could
+ // just be a '.' symbol.
+
+ if (TryConsumeOne<Digit>()) {
+ // It's a floating-point number.
+ if (previous_.type == TYPE_IDENTIFIER && !skipped_stuff) {
+ // We don't accept syntax like "blah.123".
+ error_collector_->AddError(line_, column_ - 2,
+ "Need space between identifier and decimal point.");
+ }
+ current_.type = ConsumeNumber(false, true);
+ } else {
+ current_.type = TYPE_SYMBOL;
+ }
+ } else if (TryConsumeOne<Digit>()) {
+ current_.type = ConsumeNumber(false, false);
+ } else if (TryConsume('\"')) {
+ ConsumeString('\"');
+ current_.type = TYPE_STRING;
+ } else if (TryConsume('\'')) {
+ ConsumeString('\'');
+ current_.type = TYPE_STRING;
+ } else {
+ NextChar();
+ current_.type = TYPE_SYMBOL;
+ }
+
+ EndToken();
+ return true;
+ }
+
+ skipped_stuff = true;
+ }
+
+ // EOF
+ current_.type = TYPE_END;
+ current_.text.clear();
+ current_.line = line_;
+ current_.column = column_;
+ current_.end_column = column_;
+ return false;
+}
+
+// -------------------------------------------------------------------
+// Token-parsing helpers. Remember that these don't need to report
+// errors since any errors should already have been reported while
+// tokenizing. Also, these can assume that whatever text they
+// are given is text that the tokenizer actually parsed as a token
+// of the given type.
+
+bool Tokenizer::ParseInteger(const string& text, uint64 max_value,
+ uint64* output) {
+ // Sadly, we can't just use strtoul() since it is only 32-bit and strtoull()
+ // is non-standard. I hate the C standard library. :(
+
+// return strtoull(text.c_str(), NULL, 0);
+
+ const char* ptr = text.c_str();
+ int base = 10;
+ if (ptr[0] == '0') {
+ if (ptr[1] == 'x' || ptr[1] == 'X') {
+ // This is hex.
+ base = 16;
+ ptr += 2;
+ } else {
+ // This is octal.
+ base = 8;
+ }
+ }
+
+ uint64 result = 0;
+ for (; *ptr != '\0'; ptr++) {
+ int digit = DigitValue(*ptr);
+ GOOGLE_LOG_IF(DFATAL, digit < 0 || digit >= base)
+ << " Tokenizer::ParseInteger() passed text that could not have been"
+ " tokenized as an integer: " << CEscape(text);
+ if (digit > max_value || result > (max_value - digit) / base) {
+ // Overflow.
+ return false;
+ }
+ result = result * base + digit;
+ }
+
+ *output = result;
+ return true;
+}
+
+double Tokenizer::ParseFloat(const string& text) {
+ const char* start = text.c_str();
+ char* end;
+ double result = NoLocaleStrtod(start, &end);
+
+ // "1e" is not a valid float, but if the tokenizer reads it, it will
+ // report an error but still return it as a valid token. We need to
+ // accept anything the tokenizer could possibly return, error or not.
+ if (*end == 'e' || *end == 'E') {
+ ++end;
+ if (*end == '-' || *end == '+') ++end;
+ }
+
+ // If the Tokenizer had allow_f_after_float_ enabled, the float may be
+ // suffixed with the letter 'f'.
+ if (*end == 'f' || *end == 'F') {
+ ++end;
+ }
+
+ GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-')
+ << " Tokenizer::ParseFloat() passed text that could not have been"
+ " tokenized as a float: " << CEscape(text);
+ return result;
+}
+
+void Tokenizer::ParseStringAppend(const string& text, string* output) {
+ // Reminder: text[0] is always the quote character. (If text is
+ // empty, it's invalid, so we'll just return.)
+ if (text.empty()) {
+ GOOGLE_LOG(DFATAL)
+ << " Tokenizer::ParseStringAppend() passed text that could not"
+ " have been tokenized as a string: " << CEscape(text);
+ return;
+ }
+
+ output->reserve(output->size() + text.size());
+
+ // Loop through the string copying characters to "output" and
+ // interpreting escape sequences. Note that any invalid escape
+ // sequences or other errors were already reported while tokenizing.
+ // In this case we do not need to produce valid results.
+ for (const char* ptr = text.c_str() + 1; *ptr != '\0'; ptr++) {
+ if (*ptr == '\\' && ptr[1] != '\0') {
+ // An escape sequence.
+ ++ptr;
+
+ if (OctalDigit::InClass(*ptr)) {
+ // An octal escape. May one, two, or three digits.
+ int code = DigitValue(*ptr);
+ if (OctalDigit::InClass(ptr[1])) {
+ ++ptr;
+ code = code * 8 + DigitValue(*ptr);
+ }
+ if (OctalDigit::InClass(ptr[1])) {
+ ++ptr;
+ code = code * 8 + DigitValue(*ptr);
+ }
+ output->push_back(static_cast<char>(code));
+
+ } else if (*ptr == 'x') {
+ // A hex escape. May zero, one, or two digits. (The zero case
+ // will have been caught as an error earlier.)
+ int code = 0;
+ if (HexDigit::InClass(ptr[1])) {
+ ++ptr;
+ code = DigitValue(*ptr);
+ }
+ if (HexDigit::InClass(ptr[1])) {
+ ++ptr;
+ code = code * 16 + DigitValue(*ptr);
+ }
+ output->push_back(static_cast<char>(code));
+
+ } else {
+ // Some other escape code.
+ output->push_back(TranslateEscape(*ptr));
+ }
+
+ } else if (*ptr == text[0]) {
+ // Ignore quote matching the starting quote.
+ } else {
+ output->push_back(*ptr);
+ }
+ }
+
+ return;
+}
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/tokenizer.h b/src/third_party/protobuf/src/google/protobuf/io/tokenizer.h
new file mode 100644
index 0000000..8f759ab
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/tokenizer.h
@@ -0,0 +1,313 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Class for parsing tokenized text from a ZeroCopyInputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__
+#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+class ZeroCopyInputStream; // zero_copy_stream.h
+
+// Defined in this file.
+class ErrorCollector;
+class Tokenizer;
+
+// Abstract interface for an object which collects the errors that occur
+// during parsing. A typical implementation might simply print the errors
+// to stdout.
+class LIBPROTOBUF_EXPORT ErrorCollector {
+ public:
+ inline ErrorCollector() {}
+ virtual ~ErrorCollector();
+
+ // Indicates that there was an error in the input at the given line and
+ // column numbers. The numbers are zero-based, so you may want to add
+ // 1 to each before printing them.
+ virtual void AddError(int line, int column, const string& message) = 0;
+
+ // Indicates that there was a warning in the input at the given line and
+ // column numbers. The numbers are zero-based, so you may want to add
+ // 1 to each before printing them.
+ virtual void AddWarning(int line, int column, const string& message) { }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
+};
+
+// This class converts a stream of raw text into a stream of tokens for
+// the protocol definition parser to parse. The tokens recognized are
+// similar to those that make up the C language; see the TokenType enum for
+// precise descriptions. Whitespace and comments are skipped. By default,
+// C- and C++-style comments are recognized, but other styles can be used by
+// calling set_comment_style().
+class LIBPROTOBUF_EXPORT Tokenizer {
+ public:
+ // Construct a Tokenizer that reads and tokenizes text from the given
+ // input stream and writes errors to the given error_collector.
+ // The caller keeps ownership of input and error_collector.
+ Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector);
+ ~Tokenizer();
+
+ enum TokenType {
+ TYPE_START, // Next() has not yet been called.
+ TYPE_END, // End of input reached. "text" is empty.
+
+ TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not
+ // starting with a digit. It is an error for a number
+ // to be followed by an identifier with no space in
+ // between.
+ TYPE_INTEGER, // A sequence of digits representing an integer. Normally
+ // the digits are decimal, but a prefix of "0x" indicates
+ // a hex number and a leading zero indicates octal, just
+ // like with C numeric literals. A leading negative sign
+ // is NOT included in the token; it's up to the parser to
+ // interpret the unary minus operator on its own.
+ TYPE_FLOAT, // A floating point literal, with a fractional part and/or
+ // an exponent. Always in decimal. Again, never
+ // negative.
+ TYPE_STRING, // A quoted sequence of escaped characters. Either single
+ // or double quotes can be used, but they must match.
+ // A string literal cannot cross a line break.
+ TYPE_SYMBOL, // Any other printable character, like '!' or '+'.
+ // Symbols are always a single character, so "!+$%" is
+ // four tokens.
+ };
+
+ // Structure representing a token read from the token stream.
+ struct Token {
+ TokenType type;
+ string text; // The exact text of the token as it appeared in
+ // the input. e.g. tokens of TYPE_STRING will still
+ // be escaped and in quotes.
+
+ // "line" and "column" specify the position of the first character of
+ // the token within the input stream. They are zero-based.
+ int line;
+ int column;
+ int end_column;
+ };
+
+ // Get the current token. This is updated when Next() is called. Before
+ // the first call to Next(), current() has type TYPE_START and no contents.
+ const Token& current();
+
+ // Return the previous token -- i.e. what current() returned before the
+ // previous call to Next().
+ const Token& previous();
+
+ // Advance to the next token. Returns false if the end of the input is
+ // reached.
+ bool Next();
+
+ // Parse helpers ---------------------------------------------------
+
+ // Parses a TYPE_FLOAT token. This never fails, so long as the text actually
+ // comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the
+ // result is undefined (possibly an assert failure).
+ static double ParseFloat(const string& text);
+
+ // Parses a TYPE_STRING token. This never fails, so long as the text actually
+ // comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the
+ // result is undefined (possibly an assert failure).
+ static void ParseString(const string& text, string* output);
+
+ // Identical to ParseString, but appends to output.
+ static void ParseStringAppend(const string& text, string* output);
+
+ // Parses a TYPE_INTEGER token. Returns false if the result would be
+ // greater than max_value. Otherwise, returns true and sets *output to the
+ // result. If the text is not from a Token of type TYPE_INTEGER originally
+ // parsed by a Tokenizer, the result is undefined (possibly an assert
+ // failure).
+ static bool ParseInteger(const string& text, uint64 max_value,
+ uint64* output);
+
+ // Options ---------------------------------------------------------
+
+ // Set true to allow floats to be suffixed with the letter 'f'. Tokens
+ // which would otherwise be integers but which have the 'f' suffix will be
+ // forced to be interpreted as floats. For all other purposes, the 'f' is
+ // ignored.
+ void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; }
+
+ // Valid values for set_comment_style().
+ enum CommentStyle {
+ // Line comments begin with "//", block comments are delimited by "/*" and
+ // "*/".
+ CPP_COMMENT_STYLE,
+ // Line comments begin with "#". No way to write block comments.
+ SH_COMMENT_STYLE
+ };
+
+ // Sets the comment style.
+ void set_comment_style(CommentStyle style) { comment_style_ = style; }
+
+ // -----------------------------------------------------------------
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
+
+ Token current_; // Returned by current().
+ Token previous_; // Returned by previous().
+
+ ZeroCopyInputStream* input_;
+ ErrorCollector* error_collector_;
+
+ char current_char_; // == buffer_[buffer_pos_], updated by NextChar().
+ const char* buffer_; // Current buffer returned from input_.
+ int buffer_size_; // Size of buffer_.
+ int buffer_pos_; // Current position within the buffer.
+ bool read_error_; // Did we previously encounter a read error?
+
+ // Line and column number of current_char_ within the whole input stream.
+ int line_;
+ int column_;
+
+ // Position in buffer_ where StartToken() was called. If the token
+ // started in the previous buffer, this is zero, and current_.text already
+ // contains the part of the token from the previous buffer. If not
+ // currently parsing a token, this is -1.
+ int token_start_;
+
+ // Options.
+ bool allow_f_after_float_;
+ CommentStyle comment_style_;
+
+ // Since we count columns we need to interpret tabs somehow. We'll take
+ // the standard 8-character definition for lack of any way to do better.
+ static const int kTabWidth = 8;
+
+ // -----------------------------------------------------------------
+ // Helper methods.
+
+ // Consume this character and advance to the next one.
+ void NextChar();
+
+ // Read a new buffer from the input.
+ void Refresh();
+
+ // Called when the current character is the first character of a new
+ // token (not including whitespace or comments).
+ inline void StartToken();
+ // Called when the current character is the first character after the
+ // end of the last token. After this returns, current_.text will
+ // contain all text consumed since StartToken() was called.
+ inline void EndToken();
+
+ // Convenience method to add an error at the current line and column.
+ void AddError(const string& message) {
+ error_collector_->AddError(line_, column_, message);
+ }
+
+ // -----------------------------------------------------------------
+ // The following four methods are used to consume tokens of specific
+ // types. They are actually used to consume all characters *after*
+ // the first, since the calling function consumes the first character
+ // in order to decide what kind of token is being read.
+
+ // Read and consume a string, ending when the given delimiter is
+ // consumed.
+ void ConsumeString(char delimiter);
+
+ // Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER
+ // depending on what was read. This needs to know if the first
+ // character was a zero in order to correctly recognize hex and octal
+ // numbers.
+ // It also needs to know if the first characted was a . to parse floating
+ // point correctly.
+ TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot);
+
+ // Consume the rest of a line.
+ void ConsumeLineComment();
+ // Consume until "*/".
+ void ConsumeBlockComment();
+
+ // -----------------------------------------------------------------
+ // These helper methods make the parsing code more readable. The
+ // "character classes" refered to are defined at the top of the .cc file.
+ // Basically it is a C++ class with one method:
+ // static bool InClass(char c);
+ // The method returns true if c is a member of this "class", like "Letter"
+ // or "Digit".
+
+ // Returns true if the current character is of the given character
+ // class, but does not consume anything.
+ template<typename CharacterClass>
+ inline bool LookingAt();
+
+ // If the current character is in the given class, consume it and return
+ // true. Otherwise return false.
+ // e.g. TryConsumeOne<Letter>()
+ template<typename CharacterClass>
+ inline bool TryConsumeOne();
+
+ // Like above, but try to consume the specific character indicated.
+ inline bool TryConsume(char c);
+
+ // Consume zero or more of the given character class.
+ template<typename CharacterClass>
+ inline void ConsumeZeroOrMore();
+
+ // Consume one or more of the given character class or log the given
+ // error message.
+ // e.g. ConsumeOneOrMore<Digit>("Expected digits.");
+ template<typename CharacterClass>
+ inline void ConsumeOneOrMore(const char* error);
+};
+
+// inline methods ====================================================
+inline const Tokenizer::Token& Tokenizer::current() {
+ return current_;
+}
+
+inline const Tokenizer::Token& Tokenizer::previous() {
+ return previous_;
+}
+
+inline void Tokenizer::ParseString(const string& text, string* output) {
+ output->clear();
+ ParseStringAppend(text, output);
+}
+
+} // namespace io
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc b/src/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc
new file mode 100644
index 0000000..106d080
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc
@@ -0,0 +1,766 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <vector>
+#include <math.h>
+#include <limits.h>
+
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+// ===================================================================
+// Data-Driven Test Infrastructure
+
+// TODO(kenton): This is copied from coded_stream_unittest. This is
+// temporary until these fetaures are integrated into gTest itself.
+
+// TEST_1D and TEST_2D are macros I'd eventually like to see added to
+// gTest. These macros can be used to declare tests which should be
+// run multiple times, once for each item in some input array. TEST_1D
+// tests all cases in a single input array. TEST_2D tests all
+// combinations of cases from two arrays. The arrays must be statically
+// defined such that the GOOGLE_ARRAYSIZE() macro works on them. Example:
+//
+// int kCases[] = {1, 2, 3, 4}
+// TEST_1D(MyFixture, MyTest, kCases) {
+// EXPECT_GT(kCases_case, 0);
+// }
+//
+// This test iterates through the numbers 1, 2, 3, and 4 and tests that
+// they are all grater than zero. In case of failure, the exact case
+// which failed will be printed. The case type must be printable using
+// ostream::operator<<.
+
+#define TEST_1D(FIXTURE, NAME, CASES) \
+ class FIXTURE##_##NAME##_DD : public FIXTURE { \
+ protected: \
+ template <typename CaseType> \
+ void DoSingleCase(const CaseType& CASES##_case); \
+ }; \
+ \
+ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) { \
+ SCOPED_TRACE(testing::Message() \
+ << #CASES " case #" << i << ": " << CASES[i]); \
+ DoSingleCase(CASES[i]); \
+ } \
+ } \
+ \
+ template <typename CaseType> \
+ void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
+
+#define TEST_2D(FIXTURE, NAME, CASES1, CASES2) \
+ class FIXTURE##_##NAME##_DD : public FIXTURE { \
+ protected: \
+ template <typename CaseType1, typename CaseType2> \
+ void DoSingleCase(const CaseType1& CASES1##_case, \
+ const CaseType2& CASES2##_case); \
+ }; \
+ \
+ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) { \
+ for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) { \
+ SCOPED_TRACE(testing::Message() \
+ << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \
+ << #CASES2 " case #" << j << ": " << CASES2[j]); \
+ DoSingleCase(CASES1[i], CASES2[j]); \
+ } \
+ } \
+ } \
+ \
+ template <typename CaseType1, typename CaseType2> \
+ void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
+ const CaseType2& CASES2##_case)
+
+// -------------------------------------------------------------------
+
+// An input stream that is basically like an ArrayInputStream but sometimes
+// returns empty buffers, just to throw us off.
+class TestInputStream : public ZeroCopyInputStream {
+ public:
+ TestInputStream(const void* data, int size, int block_size)
+ : array_stream_(data, size, block_size), counter_(0) {}
+ ~TestInputStream() {}
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size) {
+ // We'll return empty buffers starting with the first buffer, and every
+ // 3 and 5 buffers after that.
+ if (counter_ % 3 == 0 || counter_ % 5 == 0) {
+ *data = NULL;
+ *size = 0;
+ ++counter_;
+ return true;
+ } else {
+ ++counter_;
+ return array_stream_.Next(data, size);
+ }
+ }
+
+ void BackUp(int count) { return array_stream_.BackUp(count); }
+ bool Skip(int count) { return array_stream_.Skip(count); }
+ int64 ByteCount() const { return array_stream_.ByteCount(); }
+
+ private:
+ ArrayInputStream array_stream_;
+ int counter_;
+};
+
+// -------------------------------------------------------------------
+
+// An error collector which simply concatenates all its errors into a big
+// block of text which can be checked.
+class TestErrorCollector : public ErrorCollector {
+ public:
+ TestErrorCollector() {}
+ ~TestErrorCollector() {}
+
+ string text_;
+
+ // implements ErrorCollector ---------------------------------------
+ void AddError(int line, int column, const string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
+ line, column, message);
+ }
+};
+
+// -------------------------------------------------------------------
+
+// We test each operation over a variety of block sizes to insure that
+// we test cases where reads cross buffer boundaries as well as cases
+// where they don't. This is sort of a brute-force approach to this,
+// but it's easy to write and easy to understand.
+const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
+
+class TokenizerTest : public testing::Test {
+ protected:
+ // For easy testing.
+ uint64 ParseInteger(const string& text) {
+ uint64 result;
+ EXPECT_TRUE(Tokenizer::ParseInteger(text, kuint64max, &result));
+ return result;
+ }
+};
+
+// ===================================================================
+
+// These tests causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+// "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+// In each test case, the entire input text should parse as a single token
+// of the given type.
+struct SimpleTokenCase {
+ string input;
+ Tokenizer::TokenType type;
+};
+
+inline ostream& operator<<(ostream& out,
+ const SimpleTokenCase& test_case) {
+ return out << CEscape(test_case.input);
+}
+
+SimpleTokenCase kSimpleTokenCases[] = {
+ // Test identifiers.
+ { "hello", Tokenizer::TYPE_IDENTIFIER },
+
+ // Test integers.
+ { "123", Tokenizer::TYPE_INTEGER },
+ { "0xab6", Tokenizer::TYPE_INTEGER },
+ { "0XAB6", Tokenizer::TYPE_INTEGER },
+ { "0X1234567", Tokenizer::TYPE_INTEGER },
+ { "0x89abcdef", Tokenizer::TYPE_INTEGER },
+ { "0x89ABCDEF", Tokenizer::TYPE_INTEGER },
+ { "01234567", Tokenizer::TYPE_INTEGER },
+
+ // Test floats.
+ { "123.45", Tokenizer::TYPE_FLOAT },
+ { "1.", Tokenizer::TYPE_FLOAT },
+ { "1e3", Tokenizer::TYPE_FLOAT },
+ { "1E3", Tokenizer::TYPE_FLOAT },
+ { "1e-3", Tokenizer::TYPE_FLOAT },
+ { "1e+3", Tokenizer::TYPE_FLOAT },
+ { "1.e3", Tokenizer::TYPE_FLOAT },
+ { "1.2e3", Tokenizer::TYPE_FLOAT },
+ { ".1", Tokenizer::TYPE_FLOAT },
+ { ".1e3", Tokenizer::TYPE_FLOAT },
+ { ".1e-3", Tokenizer::TYPE_FLOAT },
+ { ".1e+3", Tokenizer::TYPE_FLOAT },
+
+ // Test strings.
+ { "'hello'", Tokenizer::TYPE_STRING },
+ { "\"foo\"", Tokenizer::TYPE_STRING },
+ { "'a\"b'", Tokenizer::TYPE_STRING },
+ { "\"a'b\"", Tokenizer::TYPE_STRING },
+ { "'a\\'b'", Tokenizer::TYPE_STRING },
+ { "\"a\\\"b\"", Tokenizer::TYPE_STRING },
+ { "'\\xf'", Tokenizer::TYPE_STRING },
+ { "'\\0'", Tokenizer::TYPE_STRING },
+
+ // Test symbols.
+ { "+", Tokenizer::TYPE_SYMBOL },
+ { ".", Tokenizer::TYPE_SYMBOL },
+};
+
+TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kSimpleTokenCases_case.input.data(),
+ kSimpleTokenCases_case.input.size(),
+ kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ // Before Next() is called, the initial token should always be TYPE_START.
+ EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
+ EXPECT_EQ("", tokenizer.current().text);
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
+
+ // Parse the token.
+ ASSERT_TRUE(tokenizer.Next());
+
+ // Check that it has the right type.
+ EXPECT_EQ(kSimpleTokenCases_case.type, tokenizer.current().type);
+ // Check that it contains the complete input text.
+ EXPECT_EQ(kSimpleTokenCases_case.input, tokenizer.current().text);
+ // Check that it is located at the beginning of the input
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+ tokenizer.current().end_column);
+
+ // There should be no more input.
+ EXPECT_FALSE(tokenizer.Next());
+
+ // After Next() returns false, the token should have type TYPE_END.
+ EXPECT_EQ(Tokenizer::TYPE_END, tokenizer.current().type);
+ EXPECT_EQ("", tokenizer.current().text);
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column);
+ EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+ tokenizer.current().end_column);
+
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+TEST_1D(TokenizerTest, FloatSuffix, kBlockSizes) {
+ // Test the "allow_f_after_float" option.
+
+ // Set up the tokenizer.
+ const char* text = "1f 2.5f 6e3f 7F";
+ TestInputStream input(text, strlen(text), kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+ tokenizer.set_allow_f_after_float(true);
+
+ // Advance through tokens and check that they are parsed as expected.
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, "1f");
+ EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, "2.5f");
+ EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, "6e3f");
+ EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+ ASSERT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, "7F");
+ EXPECT_EQ(tokenizer.current().type, Tokenizer::TYPE_FLOAT);
+
+ // There should be no more input.
+ EXPECT_FALSE(tokenizer.Next());
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+#endif
+
+// -------------------------------------------------------------------
+
+// In each case, the input is parsed to produce a list of tokens. The
+// last token in "output" must have type TYPE_END.
+struct MultiTokenCase {
+ string input;
+ Tokenizer::Token output[10]; // The compiler wants a constant array
+ // size for initialization to work. There
+ // is no reason this can't be increased if
+ // needed.
+};
+
+inline ostream& operator<<(ostream& out,
+ const MultiTokenCase& test_case) {
+ return out << CEscape(test_case.input);
+}
+
+MultiTokenCase kMultiTokenCases[] = {
+ // Test empty input.
+ { "", {
+ { Tokenizer::TYPE_END , "" , 0, 0 },
+ }},
+
+ // Test all token types at the same time.
+ { "foo 1 1.2 + 'bar'", {
+ { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0, 3 },
+ { Tokenizer::TYPE_INTEGER , "1" , 0, 4, 5 },
+ { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6, 9 },
+ { Tokenizer::TYPE_SYMBOL , "+" , 0, 10, 11 },
+ { Tokenizer::TYPE_STRING , "'bar'", 0, 12, 17 },
+ { Tokenizer::TYPE_END , "" , 0, 17, 17 },
+ }},
+
+ // Test that consecutive symbols are parsed as separate tokens.
+ { "!@+%", {
+ { Tokenizer::TYPE_SYMBOL , "!" , 0, 0, 1 },
+ { Tokenizer::TYPE_SYMBOL , "@" , 0, 1, 2 },
+ { Tokenizer::TYPE_SYMBOL , "+" , 0, 2, 3 },
+ { Tokenizer::TYPE_SYMBOL , "%" , 0, 3, 4 },
+ { Tokenizer::TYPE_END , "" , 0, 4, 4 },
+ }},
+
+ // Test that newlines affect line numbers correctly.
+ { "foo bar\nrab oof", {
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4, 7 },
+ { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4, 7 },
+ { Tokenizer::TYPE_END , "" , 1, 7, 7 },
+ }},
+
+ // Test that tabs affect column numbers correctly.
+ { "foo\tbar \tbaz", {
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8, 11 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16, 19 },
+ { Tokenizer::TYPE_END , "" , 0, 19, 19 },
+ }},
+
+ // Test that tabs in string literals affect column numbers correctly.
+ { "\"foo\tbar\" baz", {
+ { Tokenizer::TYPE_STRING , "\"foo\tbar\"", 0, 0, 12 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz" , 0, 13, 16 },
+ { Tokenizer::TYPE_END , "" , 0, 16, 16 },
+ }},
+
+ // Test that line comments are ignored.
+ { "foo // This is a comment\n"
+ "bar // This is another comment", {
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0, 3 },
+ { Tokenizer::TYPE_END , "" , 1, 30, 30 },
+ }},
+
+ // Test that block comments are ignored.
+ { "foo /* This is a block comment */ bar", {
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34, 37 },
+ { Tokenizer::TYPE_END , "" , 0, 37, 37 },
+ }},
+
+ // Test that sh-style comments are not ignored by default.
+ { "foo # bar\n"
+ "baz", {
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_SYMBOL , "#" , 0, 4, 5 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 },
+ { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 },
+ { Tokenizer::TYPE_END , "" , 1, 3, 3 },
+ }},
+
+ // Bytes with the high-order bit set should not be seen as control characters.
+ { "\300", {
+ { Tokenizer::TYPE_SYMBOL, "\300", 0, 0, 1 },
+ { Tokenizer::TYPE_END , "" , 0, 1, 1 },
+ }},
+
+ // Test all whitespace chars
+ { "foo\n\t\r\v\fbar", {
+ { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+ { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 },
+ { Tokenizer::TYPE_END , "" , 1, 14, 14 },
+ }},
+};
+
+TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kMultiTokenCases_case.input.data(),
+ kMultiTokenCases_case.input.size(),
+ kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ // Before Next() is called, the initial token should always be TYPE_START.
+ EXPECT_EQ(Tokenizer::TYPE_START, tokenizer.current().type);
+ EXPECT_EQ("", tokenizer.current().text);
+ EXPECT_EQ(0, tokenizer.current().line);
+ EXPECT_EQ(0, tokenizer.current().column);
+ EXPECT_EQ(0, tokenizer.current().end_column);
+
+ // Loop through all expected tokens.
+ int i = 0;
+ Tokenizer::Token token;
+ do {
+ token = kMultiTokenCases_case.output[i++];
+
+ SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text);
+
+ Tokenizer::Token previous = tokenizer.current();
+
+ // Next() should only return false when it hits the end token.
+ if (token.type != Tokenizer::TYPE_END) {
+ ASSERT_TRUE(tokenizer.Next());
+ } else {
+ ASSERT_FALSE(tokenizer.Next());
+ }
+
+ // Check that the previous token is set correctly.
+ EXPECT_EQ(previous.type, tokenizer.previous().type);
+ EXPECT_EQ(previous.text, tokenizer.previous().text);
+ EXPECT_EQ(previous.line, tokenizer.previous().line);
+ EXPECT_EQ(previous.column, tokenizer.previous().column);
+ EXPECT_EQ(previous.end_column, tokenizer.previous().end_column);
+
+ // Check that the token matches the expected one.
+ EXPECT_EQ(token.type, tokenizer.current().type);
+ EXPECT_EQ(token.text, tokenizer.current().text);
+ EXPECT_EQ(token.line, tokenizer.current().line);
+ EXPECT_EQ(token.column, tokenizer.current().column);
+ EXPECT_EQ(token.end_column, tokenizer.current().end_column);
+
+ } while (token.type != Tokenizer::TYPE_END);
+
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
+// "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
+#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
+
+TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) {
+ // Test the "comment_style" option.
+
+ const char* text = "foo # bar\n"
+ "baz // qux\n"
+ "corge /* grault */\n"
+ "garply";
+ const char* const kTokens[] = {"foo", // "# bar" is ignored
+ "baz", "/", "/", "qux",
+ "corge", "/", "*", "grault", "*", "/",
+ "garply"};
+
+ // Set up the tokenizer.
+ TestInputStream input(text, strlen(text), kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+ tokenizer.set_comment_style(Tokenizer::SH_COMMENT_STYLE);
+
+ // Advance through tokens and check that they are parsed as expected.
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(kTokens); i++) {
+ EXPECT_TRUE(tokenizer.Next());
+ EXPECT_EQ(tokenizer.current().text, kTokens[i]);
+ }
+
+ // There should be no more input.
+ EXPECT_FALSE(tokenizer.Next());
+ // There should be no errors.
+ EXPECT_TRUE(error_collector.text_.empty());
+}
+
+#endif
+
+// -------------------------------------------------------------------
+
+// Test parse helpers. It's not really worth setting up a full data-driven
+// test here.
+TEST_F(TokenizerTest, ParseInteger) {
+ EXPECT_EQ(0, ParseInteger("0"));
+ EXPECT_EQ(123, ParseInteger("123"));
+ EXPECT_EQ(0xabcdef12u, ParseInteger("0xabcdef12"));
+ EXPECT_EQ(0xabcdef12u, ParseInteger("0xABCDEF12"));
+ EXPECT_EQ(kuint64max, ParseInteger("0xFFFFFFFFFFFFFFFF"));
+ EXPECT_EQ(01234567, ParseInteger("01234567"));
+ EXPECT_EQ(0X123, ParseInteger("0X123"));
+
+ // Test invalid integers that may still be tokenized as integers.
+ EXPECT_EQ(0, ParseInteger("0x"));
+
+ uint64 i;
+#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
+ // Test invalid integers that will never be tokenized as integers.
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("zxy", kuint64max, &i),
+ "passed text that could not have been tokenized as an integer");
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i),
+ "passed text that could not have been tokenized as an integer");
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i),
+ "passed text that could not have been tokenized as an integer");
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i),
+ "passed text that could not have been tokenized as an integer");
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i),
+ "passed text that could not have been tokenized as an integer");
+#endif // GTEST_HAS_DEATH_TEST
+
+ // Test overflows.
+ EXPECT_TRUE (Tokenizer::ParseInteger("0", 0, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("1", 0, &i));
+ EXPECT_TRUE (Tokenizer::ParseInteger("1", 1, &i));
+ EXPECT_TRUE (Tokenizer::ParseInteger("12345", 12345, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("12346", 12345, &i));
+ EXPECT_TRUE (Tokenizer::ParseInteger("0xFFFFFFFFFFFFFFFF" , kuint64max, &i));
+ EXPECT_FALSE(Tokenizer::ParseInteger("0x10000000000000000", kuint64max, &i));
+}
+
+TEST_F(TokenizerTest, ParseFloat) {
+ EXPECT_DOUBLE_EQ(1 , Tokenizer::ParseFloat("1."));
+ EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1e3"));
+ EXPECT_DOUBLE_EQ(1e3 , Tokenizer::ParseFloat("1E3"));
+ EXPECT_DOUBLE_EQ(1.5e3, Tokenizer::ParseFloat("1.5e3"));
+ EXPECT_DOUBLE_EQ(.1 , Tokenizer::ParseFloat(".1"));
+ EXPECT_DOUBLE_EQ(.25 , Tokenizer::ParseFloat(".25"));
+ EXPECT_DOUBLE_EQ(.1e3 , Tokenizer::ParseFloat(".1e3"));
+ EXPECT_DOUBLE_EQ(.25e3, Tokenizer::ParseFloat(".25e3"));
+ EXPECT_DOUBLE_EQ(.1e+3, Tokenizer::ParseFloat(".1e+3"));
+ EXPECT_DOUBLE_EQ(.1e-3, Tokenizer::ParseFloat(".1e-3"));
+ EXPECT_DOUBLE_EQ(5 , Tokenizer::ParseFloat("5"));
+ EXPECT_DOUBLE_EQ(6e-12, Tokenizer::ParseFloat("6e-12"));
+ EXPECT_DOUBLE_EQ(1.2 , Tokenizer::ParseFloat("1.2"));
+ EXPECT_DOUBLE_EQ(1.e2 , Tokenizer::ParseFloat("1.e2"));
+
+ // Test invalid integers that may still be tokenized as integers.
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e"));
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1e-"));
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.e"));
+
+ // Test 'f' suffix.
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1f"));
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1.0f"));
+ EXPECT_DOUBLE_EQ(1, Tokenizer::ParseFloat("1F"));
+
+ // These should parse successfully even though they are out of range.
+ // Overflows become infinity and underflows become zero.
+ EXPECT_EQ( 0.0, Tokenizer::ParseFloat("1e-9999999999999999999999999999"));
+ EXPECT_EQ(HUGE_VAL, Tokenizer::ParseFloat("1e+9999999999999999999999999999"));
+
+#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
+ // Test invalid integers that will never be tokenized as integers.
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("zxy"),
+ "passed text that could not have been tokenized as a float");
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("1-e0"),
+ "passed text that could not have been tokenized as a float");
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseFloat("-1.0"),
+ "passed text that could not have been tokenized as a float");
+#endif // GTEST_HAS_DEATH_TEST
+}
+
+TEST_F(TokenizerTest, ParseString) {
+ string output;
+ Tokenizer::ParseString("'hello'", &output);
+ EXPECT_EQ("hello", output);
+ Tokenizer::ParseString("\"blah\\nblah2\"", &output);
+ EXPECT_EQ("blah\nblah2", output);
+ Tokenizer::ParseString("'\\1x\\1\\123\\739\\52\\334n\\3'", &output);
+ EXPECT_EQ("\1x\1\123\739\52\334n\3", output);
+ Tokenizer::ParseString("'\\x20\\x4'", &output);
+ EXPECT_EQ("\x20\x4", output);
+
+ // Test invalid strings that may still be tokenized as strings.
+ Tokenizer::ParseString("\"\\a\\l\\v\\t", &output); // \l is invalid
+ EXPECT_EQ("\a?\v\t", output);
+ Tokenizer::ParseString("'", &output);
+ EXPECT_EQ("", output);
+ Tokenizer::ParseString("'\\", &output);
+ EXPECT_EQ("\\", output);
+
+ // Test invalid strings that will never be tokenized as strings.
+#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet
+ EXPECT_DEBUG_DEATH(Tokenizer::ParseString("", &output),
+ "passed text that could not have been tokenized as a string");
+#endif // GTEST_HAS_DEATH_TEST
+}
+
+TEST_F(TokenizerTest, ParseStringAppend) {
+ // Check that ParseString and ParseStringAppend differ.
+ string output("stuff+");
+ Tokenizer::ParseStringAppend("'hello'", &output);
+ EXPECT_EQ("stuff+hello", output);
+ Tokenizer::ParseString("'hello'", &output);
+ EXPECT_EQ("hello", output);
+}
+
+// -------------------------------------------------------------------
+
+// Each case parses some input text, ignoring the tokens produced, and
+// checks that the error output matches what is expected.
+struct ErrorCase {
+ string input;
+ bool recoverable; // True if the tokenizer should be able to recover and
+ // parse more tokens after seeing this error. Cases
+ // for which this is true must end with "foo" as
+ // the last token, which the test will check for.
+ const char* errors;
+};
+
+inline ostream& operator<<(ostream& out,
+ const ErrorCase& test_case) {
+ return out << CEscape(test_case.input);
+}
+
+ErrorCase kErrorCases[] = {
+ // String errors.
+ { "'\\l' foo", true,
+ "0:2: Invalid escape sequence in string literal.\n" },
+ { "'\\x' foo", true,
+ "0:3: Expected hex digits for escape sequence.\n" },
+ { "'foo", false,
+ "0:4: String literals cannot cross line boundaries.\n" },
+ { "'bar\nfoo", true,
+ "0:4: String literals cannot cross line boundaries.\n" },
+
+ // Integer errors.
+ { "123foo", true,
+ "0:3: Need space between number and identifier.\n" },
+
+ // Hex/octal errors.
+ { "0x foo", true,
+ "0:2: \"0x\" must be followed by hex digits.\n" },
+ { "0541823 foo", true,
+ "0:4: Numbers starting with leading zero must be in octal.\n" },
+ { "0x123z foo", true,
+ "0:5: Need space between number and identifier.\n" },
+ { "0x123.4 foo", true,
+ "0:5: Hex and octal numbers must be integers.\n" },
+ { "0123.4 foo", true,
+ "0:4: Hex and octal numbers must be integers.\n" },
+
+ // Float errors.
+ { "1e foo", true,
+ "0:2: \"e\" must be followed by exponent.\n" },
+ { "1e- foo", true,
+ "0:3: \"e\" must be followed by exponent.\n" },
+ { "1.2.3 foo", true,
+ "0:3: Already saw decimal point or exponent; can't have another one.\n" },
+ { "1e2.3 foo", true,
+ "0:3: Already saw decimal point or exponent; can't have another one.\n" },
+ { "a.1 foo", true,
+ "0:1: Need space between identifier and decimal point.\n" },
+ // allow_f_after_float not enabled, so this should be an error.
+ { "1.0f foo", true,
+ "0:3: Need space between number and identifier.\n" },
+
+ // Block comment errors.
+ { "/*", false,
+ "0:2: End-of-file inside block comment.\n"
+ "0:0: Comment started here.\n"},
+ { "/*/*/ foo", true,
+ "0:3: \"/*\" inside block comment. Block comments cannot be nested.\n"},
+
+ // Control characters. Multiple consecutive control characters should only
+ // produce one error.
+ { "\b foo", true,
+ "0:0: Invalid control characters encountered in text.\n" },
+ { "\b\b foo", true,
+ "0:0: Invalid control characters encountered in text.\n" },
+
+ // Check that control characters at end of input don't result in an
+ // infinite loop.
+ { "\b", false,
+ "0:0: Invalid control characters encountered in text.\n" },
+
+ // Check recovery from '\0'. We have to explicitly specify the length of
+ // these strings because otherwise the string constructor will just call
+ // strlen() which will see the first '\0' and think that is the end of the
+ // string.
+ { string("\0foo", 4), true,
+ "0:0: Invalid control characters encountered in text.\n" },
+ { string("\0\0foo", 5), true,
+ "0:0: Invalid control characters encountered in text.\n" },
+};
+
+TEST_2D(TokenizerTest, Errors, kErrorCases, kBlockSizes) {
+ // Set up the tokenizer.
+ TestInputStream input(kErrorCases_case.input.data(),
+ kErrorCases_case.input.size(),
+ kBlockSizes_case);
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ // Ignore all input, except remember if the last token was "foo".
+ bool last_was_foo = false;
+ while (tokenizer.Next()) {
+ last_was_foo = tokenizer.current().text == "foo";
+ }
+
+ // Check that the errors match what was expected.
+ EXPECT_EQ(error_collector.text_, kErrorCases_case.errors);
+
+ // If the error was recoverable, make sure we saw "foo" after it.
+ if (kErrorCases_case.recoverable) {
+ EXPECT_TRUE(last_was_foo);
+ }
+}
+
+// -------------------------------------------------------------------
+
+TEST_1D(TokenizerTest, BackUpOnDestruction, kBlockSizes) {
+ string text = "foo bar";
+ TestInputStream input(text.data(), text.size(), kBlockSizes_case);
+
+ // Create a tokenizer, read one token, then destroy it.
+ {
+ TestErrorCollector error_collector;
+ Tokenizer tokenizer(&input, &error_collector);
+
+ tokenizer.Next();
+ }
+
+ // Only "foo" should have been read.
+ EXPECT_EQ(strlen("foo"), input.ByteCount());
+}
+
+} // namespace
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream.cc b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream.cc
new file mode 100644
index 0000000..dad6ff1
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream.cc
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/io/zero_copy_stream.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+ZeroCopyInputStream::~ZeroCopyInputStream() {}
+ZeroCopyOutputStream::~ZeroCopyOutputStream() {}
+
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h
new file mode 100644
index 0000000..db5326f
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream.h
@@ -0,0 +1,238 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream
+// interfaces, which represent abstract I/O streams to and from which
+// protocol buffers can be read and written. For a few simple
+// implementations of these interfaces, see zero_copy_stream_impl.h.
+//
+// These interfaces are different from classic I/O streams in that they
+// try to minimize the amount of data copying that needs to be done.
+// To accomplish this, responsibility for allocating buffers is moved to
+// the stream object, rather than being the responsibility of the caller.
+// So, the stream can return a buffer which actually points directly into
+// the final data structure where the bytes are to be stored, and the caller
+// can interact directly with that buffer, eliminating an intermediate copy
+// operation.
+//
+// As an example, consider the common case in which you are reading bytes
+// from an array that is already in memory (or perhaps an mmap()ed file).
+// With classic I/O streams, you would do something like:
+// char buffer[BUFFER_SIZE];
+// input->Read(buffer, BUFFER_SIZE);
+// DoSomething(buffer, BUFFER_SIZE);
+// Then, the stream basically just calls memcpy() to copy the data from
+// the array into your buffer. With a ZeroCopyInputStream, you would do
+// this instead:
+// const void* buffer;
+// int size;
+// input->Next(&buffer, &size);
+// DoSomething(buffer, size);
+// Here, no copy is performed. The input stream returns a pointer directly
+// into the backing array, and the caller ends up reading directly from it.
+//
+// If you want to be able to read the old-fashion way, you can create
+// a CodedInputStream or CodedOutputStream wrapping these objects and use
+// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy
+// step, but Coded*Stream will handle buffering so at least it will be
+// reasonably efficient.
+//
+// ZeroCopyInputStream example:
+// // Read in a file and print its contents to stdout.
+// int fd = open("myfile", O_RDONLY);
+// ZeroCopyInputStream* input = new FileInputStream(fd);
+//
+// const void* buffer;
+// int size;
+// while (input->Next(&buffer, &size)) {
+// cout.write(buffer, size);
+// }
+//
+// delete input;
+// close(fd);
+//
+// ZeroCopyOutputStream example:
+// // Copy the contents of "infile" to "outfile", using plain read() for
+// // "infile" but a ZeroCopyOutputStream for "outfile".
+// int infd = open("infile", O_RDONLY);
+// int outfd = open("outfile", O_WRONLY);
+// ZeroCopyOutputStream* output = new FileOutputStream(outfd);
+//
+// void* buffer;
+// int size;
+// while (output->Next(&buffer, &size)) {
+// int bytes = read(infd, buffer, size);
+// if (bytes < size) {
+// // Reached EOF.
+// output->BackUp(size - bytes);
+// break;
+// }
+// }
+//
+// delete output;
+// close(infd);
+// close(outfd);
+
+#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+
+namespace protobuf {
+namespace io {
+
+// Defined in this file.
+class ZeroCopyInputStream;
+class ZeroCopyOutputStream;
+
+// Abstract interface similar to an input stream but designed to minimize
+// copying.
+class LIBPROTOBUF_EXPORT ZeroCopyInputStream {
+ public:
+ inline ZeroCopyInputStream() {}
+ virtual ~ZeroCopyInputStream();
+
+ // Obtains a chunk of data from the stream.
+ //
+ // Preconditions:
+ // * "size" and "data" are not NULL.
+ //
+ // Postconditions:
+ // * If the returned value is false, there is no more data to return or
+ // an error occurred. All errors are permanent.
+ // * Otherwise, "size" points to the actual number of bytes read and "data"
+ // points to a pointer to a buffer containing these bytes.
+ // * Ownership of this buffer remains with the stream, and the buffer
+ // remains valid only until some other method of the stream is called
+ // or the stream is destroyed.
+ // * It is legal for the returned buffer to have zero size, as long
+ // as repeatedly calling Next() eventually yields a buffer with non-zero
+ // size.
+ virtual bool Next(const void** data, int* size) = 0;
+
+ // Backs up a number of bytes, so that the next call to Next() returns
+ // data again that was already returned by the last call to Next(). This
+ // is useful when writing procedures that are only supposed to read up
+ // to a certain point in the input, then return. If Next() returns a
+ // buffer that goes beyond what you wanted to read, you can use BackUp()
+ // to return to the point where you intended to finish.
+ //
+ // Preconditions:
+ // * The last method called must have been Next().
+ // * count must be less than or equal to the size of the last buffer
+ // returned by Next().
+ //
+ // Postconditions:
+ // * The last "count" bytes of the last buffer returned by Next() will be
+ // pushed back into the stream. Subsequent calls to Next() will return
+ // the same data again before producing new data.
+ virtual void BackUp(int count) = 0;
+
+ // Skips a number of bytes. Returns false if the end of the stream is
+ // reached or some input error occurred. In the end-of-stream case, the
+ // stream is advanced to the end of the stream (so ByteCount() will return
+ // the total size of the stream).
+ virtual bool Skip(int count) = 0;
+
+ // Returns the total number of bytes read since this object was created.
+ virtual int64 ByteCount() const = 0;
+
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream);
+};
+
+// Abstract interface similar to an output stream but designed to minimize
+// copying.
+class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
+ public:
+ inline ZeroCopyOutputStream() {}
+ virtual ~ZeroCopyOutputStream();
+
+ // Obtains a buffer into which data can be written. Any data written
+ // into this buffer will eventually (maybe instantly, maybe later on)
+ // be written to the output.
+ //
+ // Preconditions:
+ // * "size" and "data" are not NULL.
+ //
+ // Postconditions:
+ // * If the returned value is false, an error occurred. All errors are
+ // permanent.
+ // * Otherwise, "size" points to the actual number of bytes in the buffer
+ // and "data" points to the buffer.
+ // * Ownership of this buffer remains with the stream, and the buffer
+ // remains valid only until some other method of the stream is called
+ // or the stream is destroyed.
+ // * Any data which the caller stores in this buffer will eventually be
+ // written to the output (unless BackUp() is called).
+ // * It is legal for the returned buffer to have zero size, as long
+ // as repeatedly calling Next() eventually yields a buffer with non-zero
+ // size.
+ virtual bool Next(void** data, int* size) = 0;
+
+ // Backs up a number of bytes, so that the end of the last buffer returned
+ // by Next() is not actually written. This is needed when you finish
+ // writing all the data you want to write, but the last buffer was bigger
+ // than you needed. You don't want to write a bunch of garbage after the
+ // end of your data, so you use BackUp() to back up.
+ //
+ // Preconditions:
+ // * The last method called must have been Next().
+ // * count must be less than or equal to the size of the last buffer
+ // returned by Next().
+ // * The caller must not have written anything to the last "count" bytes
+ // of that buffer.
+ //
+ // Postconditions:
+ // * The last "count" bytes of the last buffer returned by Next() will be
+ // ignored.
+ virtual void BackUp(int count) = 0;
+
+ // Returns the total number of bytes written since this object was created.
+ virtual int64 ByteCount() const = 0;
+
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
+};
+
+} // namespace io
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc
new file mode 100644
index 0000000..1384c74
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc
@@ -0,0 +1,470 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#include <iostream>
+#include <algorithm>
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+#ifdef _WIN32
+// Win32 lseek is broken: If invoked on a non-seekable file descriptor, its
+// return value is undefined. We re-define it to always produce an error.
+#define lseek(fd, offset, origin) ((off_t)-1)
+#endif
+
+namespace {
+
+// EINTR sucks.
+int close_no_eintr(int fd) {
+ int result;
+ do {
+ result = close(fd);
+ } while (result < 0 && errno == EINTR);
+ return result;
+}
+
+} // namespace
+
+
+// ===================================================================
+
+FileInputStream::FileInputStream(int file_descriptor, int block_size)
+ : copying_input_(file_descriptor),
+ impl_(©ing_input_, block_size) {
+}
+
+FileInputStream::~FileInputStream() {}
+
+bool FileInputStream::Close() {
+ return copying_input_.Close();
+}
+
+bool FileInputStream::Next(const void** data, int* size) {
+ return impl_.Next(data, size);
+}
+
+void FileInputStream::BackUp(int count) {
+ impl_.BackUp(count);
+}
+
+bool FileInputStream::Skip(int count) {
+ return impl_.Skip(count);
+}
+
+int64 FileInputStream::ByteCount() const {
+ return impl_.ByteCount();
+}
+
+FileInputStream::CopyingFileInputStream::CopyingFileInputStream(
+ int file_descriptor)
+ : file_(file_descriptor),
+ close_on_delete_(false),
+ is_closed_(false),
+ errno_(0),
+ previous_seek_failed_(false) {
+}
+
+FileInputStream::CopyingFileInputStream::~CopyingFileInputStream() {
+ if (close_on_delete_) {
+ if (!Close()) {
+ GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_);
+ }
+ }
+}
+
+bool FileInputStream::CopyingFileInputStream::Close() {
+ GOOGLE_CHECK(!is_closed_);
+
+ is_closed_ = true;
+ if (close_no_eintr(file_) != 0) {
+ // The docs on close() do not specify whether a file descriptor is still
+ // open after close() fails with EIO. However, the glibc source code
+ // seems to indicate that it is not.
+ errno_ = errno;
+ return false;
+ }
+
+ return true;
+}
+
+int FileInputStream::CopyingFileInputStream::Read(void* buffer, int size) {
+ GOOGLE_CHECK(!is_closed_);
+
+ int result;
+ do {
+ result = read(file_, buffer, size);
+ } while (result < 0 && errno == EINTR);
+
+ if (result < 0) {
+ // Read error (not EOF).
+ errno_ = errno;
+ }
+
+ return result;
+}
+
+int FileInputStream::CopyingFileInputStream::Skip(int count) {
+ GOOGLE_CHECK(!is_closed_);
+
+ if (!previous_seek_failed_ &&
+ lseek(file_, count, SEEK_CUR) != (off_t)-1) {
+ // Seek succeeded.
+ return count;
+ } else {
+ // Failed to seek.
+
+ // Note to self: Don't seek again. This file descriptor doesn't
+ // support it.
+ previous_seek_failed_ = true;
+
+ // Use the default implementation.
+ return CopyingInputStream::Skip(count);
+ }
+}
+
+// ===================================================================
+
+FileOutputStream::FileOutputStream(int file_descriptor, int block_size)
+ : copying_output_(file_descriptor),
+ impl_(©ing_output_, block_size) {
+}
+
+FileOutputStream::~FileOutputStream() {
+ impl_.Flush();
+}
+
+bool FileOutputStream::Close() {
+ bool flush_succeeded = impl_.Flush();
+ return copying_output_.Close() && flush_succeeded;
+}
+
+bool FileOutputStream::Flush() {
+ return impl_.Flush();
+}
+
+bool FileOutputStream::Next(void** data, int* size) {
+ return impl_.Next(data, size);
+}
+
+void FileOutputStream::BackUp(int count) {
+ impl_.BackUp(count);
+}
+
+int64 FileOutputStream::ByteCount() const {
+ return impl_.ByteCount();
+}
+
+FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream(
+ int file_descriptor)
+ : file_(file_descriptor),
+ close_on_delete_(false),
+ is_closed_(false),
+ errno_(0) {
+}
+
+FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() {
+ if (close_on_delete_) {
+ if (!Close()) {
+ GOOGLE_LOG(ERROR) << "close() failed: " << strerror(errno_);
+ }
+ }
+}
+
+bool FileOutputStream::CopyingFileOutputStream::Close() {
+ GOOGLE_CHECK(!is_closed_);
+
+ is_closed_ = true;
+ if (close_no_eintr(file_) != 0) {
+ // The docs on close() do not specify whether a file descriptor is still
+ // open after close() fails with EIO. However, the glibc source code
+ // seems to indicate that it is not.
+ errno_ = errno;
+ return false;
+ }
+
+ return true;
+}
+
+bool FileOutputStream::CopyingFileOutputStream::Write(
+ const void* buffer, int size) {
+ GOOGLE_CHECK(!is_closed_);
+ int total_written = 0;
+
+ const uint8* buffer_base = reinterpret_cast<const uint8*>(buffer);
+
+ while (total_written < size) {
+ int bytes;
+ do {
+ bytes = write(file_, buffer_base + total_written, size - total_written);
+ } while (bytes < 0 && errno == EINTR);
+
+ if (bytes <= 0) {
+ // Write error.
+
+ // FIXME(kenton): According to the man page, if write() returns zero,
+ // there was no error; write() simply did not write anything. It's
+ // unclear under what circumstances this might happen, but presumably
+ // errno won't be set in this case. I am confused as to how such an
+ // event should be handled. For now I'm treating it as an error, since
+ // retrying seems like it could lead to an infinite loop. I suspect
+ // this never actually happens anyway.
+
+ if (bytes < 0) {
+ errno_ = errno;
+ }
+ return false;
+ }
+ total_written += bytes;
+ }
+
+ return true;
+}
+
+// ===================================================================
+
+IstreamInputStream::IstreamInputStream(istream* input, int block_size)
+ : copying_input_(input),
+ impl_(©ing_input_, block_size) {
+}
+
+IstreamInputStream::~IstreamInputStream() {}
+
+bool IstreamInputStream::Next(const void** data, int* size) {
+ return impl_.Next(data, size);
+}
+
+void IstreamInputStream::BackUp(int count) {
+ impl_.BackUp(count);
+}
+
+bool IstreamInputStream::Skip(int count) {
+ return impl_.Skip(count);
+}
+
+int64 IstreamInputStream::ByteCount() const {
+ return impl_.ByteCount();
+}
+
+IstreamInputStream::CopyingIstreamInputStream::CopyingIstreamInputStream(
+ istream* input)
+ : input_(input) {
+}
+
+IstreamInputStream::CopyingIstreamInputStream::~CopyingIstreamInputStream() {}
+
+int IstreamInputStream::CopyingIstreamInputStream::Read(
+ void* buffer, int size) {
+ input_->read(reinterpret_cast<char*>(buffer), size);
+ int result = input_->gcount();
+ if (result == 0 && input_->fail() && !input_->eof()) {
+ return -1;
+ }
+ return result;
+}
+
+// ===================================================================
+
+OstreamOutputStream::OstreamOutputStream(ostream* output, int block_size)
+ : copying_output_(output),
+ impl_(©ing_output_, block_size) {
+}
+
+OstreamOutputStream::~OstreamOutputStream() {
+ impl_.Flush();
+}
+
+bool OstreamOutputStream::Next(void** data, int* size) {
+ return impl_.Next(data, size);
+}
+
+void OstreamOutputStream::BackUp(int count) {
+ impl_.BackUp(count);
+}
+
+int64 OstreamOutputStream::ByteCount() const {
+ return impl_.ByteCount();
+}
+
+OstreamOutputStream::CopyingOstreamOutputStream::CopyingOstreamOutputStream(
+ ostream* output)
+ : output_(output) {
+}
+
+OstreamOutputStream::CopyingOstreamOutputStream::~CopyingOstreamOutputStream() {
+}
+
+bool OstreamOutputStream::CopyingOstreamOutputStream::Write(
+ const void* buffer, int size) {
+ output_->write(reinterpret_cast<const char*>(buffer), size);
+ return output_->good();
+}
+
+// ===================================================================
+
+ConcatenatingInputStream::ConcatenatingInputStream(
+ ZeroCopyInputStream* const streams[], int count)
+ : streams_(streams), stream_count_(count), bytes_retired_(0) {
+}
+
+ConcatenatingInputStream::~ConcatenatingInputStream() {
+}
+
+bool ConcatenatingInputStream::Next(const void** data, int* size) {
+ while (stream_count_ > 0) {
+ if (streams_[0]->Next(data, size)) return true;
+
+ // That stream is done. Advance to the next one.
+ bytes_retired_ += streams_[0]->ByteCount();
+ ++streams_;
+ --stream_count_;
+ }
+
+ // No more streams.
+ return false;
+}
+
+void ConcatenatingInputStream::BackUp(int count) {
+ if (stream_count_ > 0) {
+ streams_[0]->BackUp(count);
+ } else {
+ GOOGLE_LOG(DFATAL) << "Can't BackUp() after failed Next().";
+ }
+}
+
+bool ConcatenatingInputStream::Skip(int count) {
+ while (stream_count_ > 0) {
+ // Assume that ByteCount() can be used to find out how much we actually
+ // skipped when Skip() fails.
+ int64 target_byte_count = streams_[0]->ByteCount() + count;
+ if (streams_[0]->Skip(count)) return true;
+
+ // Hit the end of the stream. Figure out how many more bytes we still have
+ // to skip.
+ int64 final_byte_count = streams_[0]->ByteCount();
+ GOOGLE_DCHECK_LT(final_byte_count, target_byte_count);
+ count = target_byte_count - final_byte_count;
+
+ // That stream is done. Advance to the next one.
+ bytes_retired_ += final_byte_count;
+ ++streams_;
+ --stream_count_;
+ }
+
+ return false;
+}
+
+int64 ConcatenatingInputStream::ByteCount() const {
+ if (stream_count_ == 0) {
+ return bytes_retired_;
+ } else {
+ return bytes_retired_ + streams_[0]->ByteCount();
+ }
+}
+
+
+// ===================================================================
+
+LimitingInputStream::LimitingInputStream(ZeroCopyInputStream* input,
+ int64 limit)
+ : input_(input), limit_(limit) {}
+
+LimitingInputStream::~LimitingInputStream() {
+ // If we overshot the limit, back up.
+ if (limit_ < 0) input_->BackUp(-limit_);
+}
+
+bool LimitingInputStream::Next(const void** data, int* size) {
+ if (limit_ <= 0) return false;
+ if (!input_->Next(data, size)) return false;
+
+ limit_ -= *size;
+ if (limit_ < 0) {
+ // We overshot the limit. Reduce *size to hide the rest of the buffer.
+ *size += limit_;
+ }
+ return true;
+}
+
+void LimitingInputStream::BackUp(int count) {
+ if (limit_ < 0) {
+ input_->BackUp(count - limit_);
+ limit_ = count;
+ } else {
+ input_->BackUp(count);
+ limit_ += count;
+ }
+}
+
+bool LimitingInputStream::Skip(int count) {
+ if (count > limit_) {
+ if (limit_ < 0) return false;
+ input_->Skip(limit_);
+ limit_ = 0;
+ return false;
+ } else {
+ if (!input_->Skip(count)) return false;
+ limit_ -= count;
+ return true;
+ }
+}
+
+int64 LimitingInputStream::ByteCount() const {
+ if (limit_ < 0) {
+ return input_->ByteCount() + limit_;
+ } else {
+ return input_->ByteCount();
+ }
+}
+
+
+// ===================================================================
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
new file mode 100644
index 0000000..9fedb00
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -0,0 +1,357 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains common implementations of the interfaces defined in
+// zero_copy_stream.h which are only included in the full (non-lite)
+// protobuf library. These implementations include Unix file descriptors
+// and C++ iostreams. See also: zero_copy_stream_impl_lite.h
+
+#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
+
+#include <string>
+#include <iosfwd>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from a file descriptor.
+//
+// FileInputStream is preferred over using an ifstream with IstreamInputStream.
+// The latter will introduce an extra layer of buffering, harming performance.
+// Also, it's conceivable that FileInputStream could someday be enhanced
+// to use zero-copy file descriptors on OSs which support them.
+class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
+ public:
+ // Creates a stream that reads from the given Unix file descriptor.
+ // If a block_size is given, it specifies the number of bytes that
+ // should be read and returned with each call to Next(). Otherwise,
+ // a reasonable default is used.
+ explicit FileInputStream(int file_descriptor, int block_size = -1);
+ ~FileInputStream();
+
+ // Flushes any buffers and closes the underlying file. Returns false if
+ // an error occurs during the process; use GetErrno() to examine the error.
+ // Even if an error occurs, the file descriptor is closed when this returns.
+ bool Close();
+
+ // By default, the file descriptor is not closed when the stream is
+ // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
+ // This leaves no way for the caller to detect if close() fails. If
+ // detecting close() errors is important to you, you should arrange
+ // to close the descriptor yourself.
+ void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
+
+ // If an I/O error has occurred on this file descriptor, this is the
+ // errno from that error. Otherwise, this is zero. Once an error
+ // occurs, the stream is broken and all subsequent operations will
+ // fail.
+ int GetErrno() { return copying_input_.GetErrno(); }
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size);
+ void BackUp(int count);
+ bool Skip(int count);
+ int64 ByteCount() const;
+
+ private:
+ class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
+ public:
+ CopyingFileInputStream(int file_descriptor);
+ ~CopyingFileInputStream();
+
+ bool Close();
+ void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
+ int GetErrno() { return errno_; }
+
+ // implements CopyingInputStream ---------------------------------
+ int Read(void* buffer, int size);
+ int Skip(int count);
+
+ private:
+ // The file descriptor.
+ const int file_;
+ bool close_on_delete_;
+ bool is_closed_;
+
+ // The errno of the I/O error, if one has occurred. Otherwise, zero.
+ int errno_;
+
+ // Did we try to seek once and fail? If so, we assume this file descriptor
+ // doesn't support seeking and won't try again.
+ bool previous_seek_failed_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream);
+ };
+
+ CopyingFileInputStream copying_input_;
+ CopyingInputStreamAdaptor impl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which writes to a file descriptor.
+//
+// FileOutputStream is preferred over using an ofstream with
+// OstreamOutputStream. The latter will introduce an extra layer of buffering,
+// harming performance. Also, it's conceivable that FileOutputStream could
+// someday be enhanced to use zero-copy file descriptors on OSs which
+// support them.
+class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Creates a stream that writes to the given Unix file descriptor.
+ // If a block_size is given, it specifies the size of the buffers
+ // that should be returned by Next(). Otherwise, a reasonable default
+ // is used.
+ explicit FileOutputStream(int file_descriptor, int block_size = -1);
+ ~FileOutputStream();
+
+ // Flushes any buffers and closes the underlying file. Returns false if
+ // an error occurs during the process; use GetErrno() to examine the error.
+ // Even if an error occurs, the file descriptor is closed when this returns.
+ bool Close();
+
+ // Flushes FileOutputStream's buffers but does not close the
+ // underlying file. No special measures are taken to ensure that
+ // underlying operating system file object is synchronized to disk.
+ bool Flush();
+
+ // By default, the file descriptor is not closed when the stream is
+ // destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
+ // This leaves no way for the caller to detect if close() fails. If
+ // detecting close() errors is important to you, you should arrange
+ // to close the descriptor yourself.
+ void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
+
+ // If an I/O error has occurred on this file descriptor, this is the
+ // errno from that error. Otherwise, this is zero. Once an error
+ // occurs, the stream is broken and all subsequent operations will
+ // fail.
+ int GetErrno() { return copying_output_.GetErrno(); }
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size);
+ void BackUp(int count);
+ int64 ByteCount() const;
+
+ private:
+ class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
+ public:
+ CopyingFileOutputStream(int file_descriptor);
+ ~CopyingFileOutputStream();
+
+ bool Close();
+ void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
+ int GetErrno() { return errno_; }
+
+ // implements CopyingOutputStream --------------------------------
+ bool Write(const void* buffer, int size);
+
+ private:
+ // The file descriptor.
+ const int file_;
+ bool close_on_delete_;
+ bool is_closed_;
+
+ // The errno of the I/O error, if one has occurred. Otherwise, zero.
+ int errno_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
+ };
+
+ CopyingFileOutputStream copying_output_;
+ CopyingOutputStreamAdaptor impl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from a C++ istream.
+//
+// Note that for reading files (or anything represented by a file descriptor),
+// FileInputStream is more efficient.
+class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
+ public:
+ // Creates a stream that reads from the given C++ istream.
+ // If a block_size is given, it specifies the number of bytes that
+ // should be read and returned with each call to Next(). Otherwise,
+ // a reasonable default is used.
+ explicit IstreamInputStream(istream* stream, int block_size = -1);
+ ~IstreamInputStream();
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size);
+ void BackUp(int count);
+ bool Skip(int count);
+ int64 ByteCount() const;
+
+ private:
+ class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
+ public:
+ CopyingIstreamInputStream(istream* input);
+ ~CopyingIstreamInputStream();
+
+ // implements CopyingInputStream ---------------------------------
+ int Read(void* buffer, int size);
+ // (We use the default implementation of Skip().)
+
+ private:
+ // The stream.
+ istream* input_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
+ };
+
+ CopyingIstreamInputStream copying_input_;
+ CopyingInputStreamAdaptor impl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which writes to a C++ ostream.
+//
+// Note that for writing files (or anything represented by a file descriptor),
+// FileOutputStream is more efficient.
+class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Creates a stream that writes to the given C++ ostream.
+ // If a block_size is given, it specifies the size of the buffers
+ // that should be returned by Next(). Otherwise, a reasonable default
+ // is used.
+ explicit OstreamOutputStream(ostream* stream, int block_size = -1);
+ ~OstreamOutputStream();
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size);
+ void BackUp(int count);
+ int64 ByteCount() const;
+
+ private:
+ class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
+ public:
+ CopyingOstreamOutputStream(ostream* output);
+ ~CopyingOstreamOutputStream();
+
+ // implements CopyingOutputStream --------------------------------
+ bool Write(const void* buffer, int size);
+
+ private:
+ // The stream.
+ ostream* output_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
+ };
+
+ CopyingOstreamOutputStream copying_output_;
+ CopyingOutputStreamAdaptor impl_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which reads from several other streams in sequence.
+// ConcatenatingInputStream is unable to distinguish between end-of-stream
+// and read errors in the underlying streams, so it assumes any errors mean
+// end-of-stream. So, if the underlying streams fail for any other reason,
+// ConcatenatingInputStream may do odd things. It is suggested that you do
+// not use ConcatenatingInputStream on streams that might produce read errors
+// other than end-of-stream.
+class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
+ public:
+ // All streams passed in as well as the array itself must remain valid
+ // until the ConcatenatingInputStream is destroyed.
+ ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
+ ~ConcatenatingInputStream();
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size);
+ void BackUp(int count);
+ bool Skip(int count);
+ int64 ByteCount() const;
+
+
+ private:
+ // As streams are retired, streams_ is incremented and count_ is
+ // decremented.
+ ZeroCopyInputStream* const* streams_;
+ int stream_count_;
+ int64 bytes_retired_; // Bytes read from previous streams.
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyInputStream which wraps some other stream and limits it to
+// a particular byte count.
+class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
+ public:
+ LimitingInputStream(ZeroCopyInputStream* input, int64 limit);
+ ~LimitingInputStream();
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size);
+ void BackUp(int count);
+ bool Skip(int count);
+ int64 ByteCount() const;
+
+
+ private:
+ ZeroCopyInputStream* input_;
+ int64 limit_; // Decreases as we go, becomes negative if we overshoot.
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
+};
+
+// ===================================================================
+
+} // namespace io
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
new file mode 100644
index 0000000..e801251
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -0,0 +1,393 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+namespace {
+
+// Default block size for Copying{In,Out}putStreamAdaptor.
+static const int kDefaultBlockSize = 8192;
+
+} // namespace
+
+// ===================================================================
+
+ArrayInputStream::ArrayInputStream(const void* data, int size,
+ int block_size)
+ : data_(reinterpret_cast<const uint8*>(data)),
+ size_(size),
+ block_size_(block_size > 0 ? block_size : size),
+ position_(0),
+ last_returned_size_(0) {
+}
+
+ArrayInputStream::~ArrayInputStream() {
+}
+
+bool ArrayInputStream::Next(const void** data, int* size) {
+ if (position_ < size_) {
+ last_returned_size_ = min(block_size_, size_ - position_);
+ *data = data_ + position_;
+ *size = last_returned_size_;
+ position_ += last_returned_size_;
+ return true;
+ } else {
+ // We're at the end of the array.
+ last_returned_size_ = 0; // Don't let caller back up.
+ return false;
+ }
+}
+
+void ArrayInputStream::BackUp(int count) {
+ GOOGLE_CHECK_GT(last_returned_size_, 0)
+ << "BackUp() can only be called after a successful Next().";
+ GOOGLE_CHECK_LE(count, last_returned_size_);
+ GOOGLE_CHECK_GE(count, 0);
+ position_ -= count;
+ last_returned_size_ = 0; // Don't let caller back up further.
+}
+
+bool ArrayInputStream::Skip(int count) {
+ GOOGLE_CHECK_GE(count, 0);
+ last_returned_size_ = 0; // Don't let caller back up.
+ if (count > size_ - position_) {
+ position_ = size_;
+ return false;
+ } else {
+ position_ += count;
+ return true;
+ }
+}
+
+int64 ArrayInputStream::ByteCount() const {
+ return position_;
+}
+
+
+// ===================================================================
+
+ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
+ : data_(reinterpret_cast<uint8*>(data)),
+ size_(size),
+ block_size_(block_size > 0 ? block_size : size),
+ position_(0),
+ last_returned_size_(0) {
+}
+
+ArrayOutputStream::~ArrayOutputStream() {
+}
+
+bool ArrayOutputStream::Next(void** data, int* size) {
+ if (position_ < size_) {
+ last_returned_size_ = min(block_size_, size_ - position_);
+ *data = data_ + position_;
+ *size = last_returned_size_;
+ position_ += last_returned_size_;
+ return true;
+ } else {
+ // We're at the end of the array.
+ last_returned_size_ = 0; // Don't let caller back up.
+ return false;
+ }
+}
+
+void ArrayOutputStream::BackUp(int count) {
+ GOOGLE_CHECK_GT(last_returned_size_, 0)
+ << "BackUp() can only be called after a successful Next().";
+ GOOGLE_CHECK_LE(count, last_returned_size_);
+ GOOGLE_CHECK_GE(count, 0);
+ position_ -= count;
+ last_returned_size_ = 0; // Don't let caller back up further.
+}
+
+int64 ArrayOutputStream::ByteCount() const {
+ return position_;
+}
+
+// ===================================================================
+
+StringOutputStream::StringOutputStream(string* target)
+ : target_(target) {
+}
+
+StringOutputStream::~StringOutputStream() {
+}
+
+bool StringOutputStream::Next(void** data, int* size) {
+ int old_size = target_->size();
+
+ // Grow the string.
+ if (old_size < target_->capacity()) {
+ // Resize the string to match its capacity, since we can get away
+ // without a memory allocation this way.
+ STLStringResizeUninitialized(target_, target_->capacity());
+ } else {
+ // Size has reached capacity, so double the size. Also make sure
+ // that the new size is at least kMinimumSize.
+ STLStringResizeUninitialized(
+ target_,
+ max(old_size * 2,
+ kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
+ }
+
+ *data = string_as_array(target_) + old_size;
+ *size = target_->size() - old_size;
+ return true;
+}
+
+void StringOutputStream::BackUp(int count) {
+ GOOGLE_CHECK_GE(count, 0);
+ GOOGLE_CHECK_LE(count, target_->size());
+ target_->resize(target_->size() - count);
+}
+
+int64 StringOutputStream::ByteCount() const {
+ return target_->size();
+}
+
+// ===================================================================
+
+CopyingInputStream::~CopyingInputStream() {}
+
+int CopyingInputStream::Skip(int count) {
+ char junk[4096];
+ int skipped = 0;
+ while (skipped < count) {
+ int bytes = Read(junk, min(count - skipped,
+ implicit_cast<int>(sizeof(junk))));
+ if (bytes <= 0) {
+ // EOF or read error.
+ return skipped;
+ }
+ skipped += bytes;
+ }
+ return skipped;
+}
+
+CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
+ CopyingInputStream* copying_stream, int block_size)
+ : copying_stream_(copying_stream),
+ owns_copying_stream_(false),
+ failed_(false),
+ position_(0),
+ buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
+ buffer_used_(0),
+ backup_bytes_(0) {
+}
+
+CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() {
+ if (owns_copying_stream_) {
+ delete copying_stream_;
+ }
+}
+
+bool CopyingInputStreamAdaptor::Next(const void** data, int* size) {
+ if (failed_) {
+ // Already failed on a previous read.
+ return false;
+ }
+
+ AllocateBufferIfNeeded();
+
+ if (backup_bytes_ > 0) {
+ // We have data left over from a previous BackUp(), so just return that.
+ *data = buffer_.get() + buffer_used_ - backup_bytes_;
+ *size = backup_bytes_;
+ backup_bytes_ = 0;
+ return true;
+ }
+
+ // Read new data into the buffer.
+ buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_);
+ if (buffer_used_ <= 0) {
+ // EOF or read error. We don't need the buffer anymore.
+ if (buffer_used_ < 0) {
+ // Read error (not EOF).
+ failed_ = true;
+ }
+ FreeBuffer();
+ return false;
+ }
+ position_ += buffer_used_;
+
+ *size = buffer_used_;
+ *data = buffer_.get();
+ return true;
+}
+
+void CopyingInputStreamAdaptor::BackUp(int count) {
+ GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL)
+ << " BackUp() can only be called after Next().";
+ GOOGLE_CHECK_LE(count, buffer_used_)
+ << " Can't back up over more bytes than were returned by the last call"
+ " to Next().";
+ GOOGLE_CHECK_GE(count, 0)
+ << " Parameter to BackUp() can't be negative.";
+
+ backup_bytes_ = count;
+}
+
+bool CopyingInputStreamAdaptor::Skip(int count) {
+ GOOGLE_CHECK_GE(count, 0);
+
+ if (failed_) {
+ // Already failed on a previous read.
+ return false;
+ }
+
+ // First skip any bytes left over from a previous BackUp().
+ if (backup_bytes_ >= count) {
+ // We have more data left over than we're trying to skip. Just chop it.
+ backup_bytes_ -= count;
+ return true;
+ }
+
+ count -= backup_bytes_;
+ backup_bytes_ = 0;
+
+ int skipped = copying_stream_->Skip(count);
+ position_ += skipped;
+ return skipped == count;
+}
+
+int64 CopyingInputStreamAdaptor::ByteCount() const {
+ return position_ - backup_bytes_;
+}
+
+void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() {
+ if (buffer_.get() == NULL) {
+ buffer_.reset(new uint8[buffer_size_]);
+ }
+}
+
+void CopyingInputStreamAdaptor::FreeBuffer() {
+ GOOGLE_CHECK_EQ(backup_bytes_, 0);
+ buffer_used_ = 0;
+ buffer_.reset();
+}
+
+// ===================================================================
+
+CopyingOutputStream::~CopyingOutputStream() {}
+
+CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
+ CopyingOutputStream* copying_stream, int block_size)
+ : copying_stream_(copying_stream),
+ owns_copying_stream_(false),
+ failed_(false),
+ position_(0),
+ buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
+ buffer_used_(0) {
+}
+
+CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
+ WriteBuffer();
+ if (owns_copying_stream_) {
+ delete copying_stream_;
+ }
+}
+
+bool CopyingOutputStreamAdaptor::Flush() {
+ return WriteBuffer();
+}
+
+bool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
+ if (buffer_used_ == buffer_size_) {
+ if (!WriteBuffer()) return false;
+ }
+
+ AllocateBufferIfNeeded();
+
+ *data = buffer_.get() + buffer_used_;
+ *size = buffer_size_ - buffer_used_;
+ buffer_used_ = buffer_size_;
+ return true;
+}
+
+void CopyingOutputStreamAdaptor::BackUp(int count) {
+ GOOGLE_CHECK_GE(count, 0);
+ GOOGLE_CHECK_EQ(buffer_used_, buffer_size_)
+ << " BackUp() can only be called after Next().";
+ GOOGLE_CHECK_LE(count, buffer_used_)
+ << " Can't back up over more bytes than were returned by the last call"
+ " to Next().";
+
+ buffer_used_ -= count;
+}
+
+int64 CopyingOutputStreamAdaptor::ByteCount() const {
+ return position_ + buffer_used_;
+}
+
+bool CopyingOutputStreamAdaptor::WriteBuffer() {
+ if (failed_) {
+ // Already failed on a previous write.
+ return false;
+ }
+
+ if (buffer_used_ == 0) return true;
+
+ if (copying_stream_->Write(buffer_.get(), buffer_used_)) {
+ position_ += buffer_used_;
+ buffer_used_ = 0;
+ return true;
+ } else {
+ failed_ = true;
+ FreeBuffer();
+ return false;
+ }
+}
+
+void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() {
+ if (buffer_ == NULL) {
+ buffer_.reset(new uint8[buffer_size_]);
+ }
+}
+
+void CopyingOutputStreamAdaptor::FreeBuffer() {
+ buffer_used_ = 0;
+ buffer_.reset();
+}
+
+// ===================================================================
+
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
new file mode 100644
index 0000000..153f543
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -0,0 +1,340 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains common implementations of the interfaces defined in
+// zero_copy_stream.h which are included in the "lite" protobuf library.
+// These implementations cover I/O on raw arrays and strings, as well as
+// adaptors which make it easy to implement streams based on traditional
+// streams. Of course, many users will probably want to write their own
+// implementations of these interfaces specific to the particular I/O
+// abstractions they prefer to use, but these should cover the most common
+// cases.
+
+#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
+
+#include <string>
+#include <iosfwd>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// ===================================================================
+
+// A ZeroCopyInputStream backed by an in-memory array of bytes.
+class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
+ public:
+ // Create an InputStream that returns the bytes pointed to by "data".
+ // "data" remains the property of the caller but must remain valid until
+ // the stream is destroyed. If a block_size is given, calls to Next()
+ // will return data blocks no larger than the given size. Otherwise, the
+ // first call to Next() returns the entire array. block_size is mainly
+ // useful for testing; in production you would probably never want to set
+ // it.
+ ArrayInputStream(const void* data, int size, int block_size = -1);
+ ~ArrayInputStream();
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size);
+ void BackUp(int count);
+ bool Skip(int count);
+ int64 ByteCount() const;
+
+
+ private:
+ const uint8* const data_; // The byte array.
+ const int size_; // Total size of the array.
+ const int block_size_; // How many bytes to return at a time.
+
+ int position_;
+ int last_returned_size_; // How many bytes we returned last time Next()
+ // was called (used for error checking only).
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream backed by an in-memory array of bytes.
+class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Create an OutputStream that writes to the bytes pointed to by "data".
+ // "data" remains the property of the caller but must remain valid until
+ // the stream is destroyed. If a block_size is given, calls to Next()
+ // will return data blocks no larger than the given size. Otherwise, the
+ // first call to Next() returns the entire array. block_size is mainly
+ // useful for testing; in production you would probably never want to set
+ // it.
+ ArrayOutputStream(void* data, int size, int block_size = -1);
+ ~ArrayOutputStream();
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size);
+ void BackUp(int count);
+ int64 ByteCount() const;
+
+ private:
+ uint8* const data_; // The byte array.
+ const int size_; // Total size of the array.
+ const int block_size_; // How many bytes to return at a time.
+
+ int position_;
+ int last_returned_size_; // How many bytes we returned last time Next()
+ // was called (used for error checking only).
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream);
+};
+
+// ===================================================================
+
+// A ZeroCopyOutputStream which appends bytes to a string.
+class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
+ public:
+ // Create a StringOutputStream which appends bytes to the given string.
+ // The string remains property of the caller, but it MUST NOT be accessed
+ // in any way until the stream is destroyed.
+ //
+ // Hint: If you call target->reserve(n) before creating the stream,
+ // the first call to Next() will return at least n bytes of buffer
+ // space.
+ explicit StringOutputStream(string* target);
+ ~StringOutputStream();
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size);
+ void BackUp(int count);
+ int64 ByteCount() const;
+
+ private:
+ static const int kMinimumSize = 16;
+
+ string* target_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream);
+};
+
+// Note: There is no StringInputStream. Instead, just create an
+// ArrayInputStream as follows:
+// ArrayInputStream input(str.data(), str.size());
+
+// ===================================================================
+
+// A generic traditional input stream interface.
+//
+// Lots of traditional input streams (e.g. file descriptors, C stdio
+// streams, and C++ iostreams) expose an interface where every read
+// involves copying bytes into a buffer. If you want to take such an
+// interface and make a ZeroCopyInputStream based on it, simply implement
+// CopyingInputStream and then use CopyingInputStreamAdaptor.
+//
+// CopyingInputStream implementations should avoid buffering if possible.
+// CopyingInputStreamAdaptor does its own buffering and will read data
+// in large blocks.
+class LIBPROTOBUF_EXPORT CopyingInputStream {
+ public:
+ virtual ~CopyingInputStream();
+
+ // Reads up to "size" bytes into the given buffer. Returns the number of
+ // bytes read. Read() waits until at least one byte is available, or
+ // returns zero if no bytes will ever become available (EOF), or -1 if a
+ // permanent read error occurred.
+ virtual int Read(void* buffer, int size) = 0;
+
+ // Skips the next "count" bytes of input. Returns the number of bytes
+ // actually skipped. This will always be exactly equal to "count" unless
+ // EOF was reached or a permanent read error occurred.
+ //
+ // The default implementation just repeatedly calls Read() into a scratch
+ // buffer.
+ virtual int Skip(int count);
+};
+
+// A ZeroCopyInputStream which reads from a CopyingInputStream. This is
+// useful for implementing ZeroCopyInputStreams that read from traditional
+// streams. Note that this class is not really zero-copy.
+//
+// If you want to read from file descriptors or C++ istreams, this is
+// already implemented for you: use FileInputStream or IstreamInputStream
+// respectively.
+class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream {
+ public:
+ // Creates a stream that reads from the given CopyingInputStream.
+ // If a block_size is given, it specifies the number of bytes that
+ // should be read and returned with each call to Next(). Otherwise,
+ // a reasonable default is used. The caller retains ownership of
+ // copying_stream unless SetOwnsCopyingStream(true) is called.
+ explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream,
+ int block_size = -1);
+ ~CopyingInputStreamAdaptor();
+
+ // Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to
+ // delete the underlying CopyingInputStream when it is destroyed.
+ void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
+
+ // implements ZeroCopyInputStream ----------------------------------
+ bool Next(const void** data, int* size);
+ void BackUp(int count);
+ bool Skip(int count);
+ int64 ByteCount() const;
+
+ private:
+ // Insures that buffer_ is not NULL.
+ void AllocateBufferIfNeeded();
+ // Frees the buffer and resets buffer_used_.
+ void FreeBuffer();
+
+ // The underlying copying stream.
+ CopyingInputStream* copying_stream_;
+ bool owns_copying_stream_;
+
+ // True if we have seen a permenant error from the underlying stream.
+ bool failed_;
+
+ // The current position of copying_stream_, relative to the point where
+ // we started reading.
+ int64 position_;
+
+ // Data is read into this buffer. It may be NULL if no buffer is currently
+ // in use. Otherwise, it points to an array of size buffer_size_.
+ scoped_array<uint8> buffer_;
+ const int buffer_size_;
+
+ // Number of valid bytes currently in the buffer (i.e. the size last
+ // returned by Next()). 0 <= buffer_used_ <= buffer_size_.
+ int buffer_used_;
+
+ // Number of bytes in the buffer which were backed up over by a call to
+ // BackUp(). These need to be returned again.
+ // 0 <= backup_bytes_ <= buffer_used_
+ int backup_bytes_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor);
+};
+
+// ===================================================================
+
+// A generic traditional output stream interface.
+//
+// Lots of traditional output streams (e.g. file descriptors, C stdio
+// streams, and C++ iostreams) expose an interface where every write
+// involves copying bytes from a buffer. If you want to take such an
+// interface and make a ZeroCopyOutputStream based on it, simply implement
+// CopyingOutputStream and then use CopyingOutputStreamAdaptor.
+//
+// CopyingOutputStream implementations should avoid buffering if possible.
+// CopyingOutputStreamAdaptor does its own buffering and will write data
+// in large blocks.
+class LIBPROTOBUF_EXPORT CopyingOutputStream {
+ public:
+ virtual ~CopyingOutputStream();
+
+ // Writes "size" bytes from the given buffer to the output. Returns true
+ // if successful, false on a write error.
+ virtual bool Write(const void* buffer, int size) = 0;
+};
+
+// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is
+// useful for implementing ZeroCopyOutputStreams that write to traditional
+// streams. Note that this class is not really zero-copy.
+//
+// If you want to write to file descriptors or C++ ostreams, this is
+// already implemented for you: use FileOutputStream or OstreamOutputStream
+// respectively.
+class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream {
+ public:
+ // Creates a stream that writes to the given Unix file descriptor.
+ // If a block_size is given, it specifies the size of the buffers
+ // that should be returned by Next(). Otherwise, a reasonable default
+ // is used.
+ explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream,
+ int block_size = -1);
+ ~CopyingOutputStreamAdaptor();
+
+ // Writes all pending data to the underlying stream. Returns false if a
+ // write error occurred on the underlying stream. (The underlying
+ // stream itself is not necessarily flushed.)
+ bool Flush();
+
+ // Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to
+ // delete the underlying CopyingOutputStream when it is destroyed.
+ void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
+
+ // implements ZeroCopyOutputStream ---------------------------------
+ bool Next(void** data, int* size);
+ void BackUp(int count);
+ int64 ByteCount() const;
+
+ private:
+ // Write the current buffer, if it is present.
+ bool WriteBuffer();
+ // Insures that buffer_ is not NULL.
+ void AllocateBufferIfNeeded();
+ // Frees the buffer.
+ void FreeBuffer();
+
+ // The underlying copying stream.
+ CopyingOutputStream* copying_stream_;
+ bool owns_copying_stream_;
+
+ // True if we have seen a permenant error from the underlying stream.
+ bool failed_;
+
+ // The current position of copying_stream_, relative to the point where
+ // we started writing.
+ int64 position_;
+
+ // Data is written from this buffer. It may be NULL if no buffer is
+ // currently in use. Otherwise, it points to an array of size buffer_size_.
+ scoped_array<uint8> buffer_;
+ const int buffer_size_;
+
+ // Number of valid bytes currently in the buffer (i.e. the size last
+ // returned by Next()). When BackUp() is called, we just reduce this.
+ // 0 <= buffer_used_ <= buffer_size_.
+ int buffer_used_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor);
+};
+
+// ===================================================================
+
+} // namespace io
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc
new file mode 100644
index 0000000..5196d90
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -0,0 +1,850 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Testing strategy: For each type of I/O (array, string, file, etc.) we
+// create an output stream and write some data to it, then create a
+// corresponding input stream to read the same data back and expect it to
+// match. When the data is written, it is written in several small chunks
+// of varying sizes, with a BackUp() after each chunk. It is read back
+// similarly, but with chunks separated at different points. The whole
+// process is run with a variety of block sizes for both the input and
+// the output.
+//
+// TODO(kenton): Rewrite this test to bring it up to the standards of all
+// the other proto2 tests. May want to wait for gTest to implement
+// "parametized tests" so that one set of tests can be used on all the
+// implementations.
+
+#include "config.h"
+
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sstream>
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
+
+#if HAVE_ZLIB
+#include <google/protobuf/io/gzip_stream.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <google/protobuf/testing/file.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+namespace {
+
+#ifdef _WIN32
+#define pipe(fds) _pipe(fds, 4096, O_BINARY)
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+class IoTest : public testing::Test {
+ protected:
+ // Test helpers.
+
+ // Helper to write an array of data to an output stream.
+ bool WriteToOutput(ZeroCopyOutputStream* output, const void* data, int size);
+ // Helper to read a fixed-length array of data from an input stream.
+ int ReadFromInput(ZeroCopyInputStream* input, void* data, int size);
+ // Write a string to the output stream.
+ void WriteString(ZeroCopyOutputStream* output, const string& str);
+ // Read a number of bytes equal to the size of the given string and checks
+ // that it matches the string.
+ void ReadString(ZeroCopyInputStream* input, const string& str);
+ // Writes some text to the output stream in a particular order. Returns
+ // the number of bytes written, incase the caller needs that to set up an
+ // input stream.
+ int WriteStuff(ZeroCopyOutputStream* output);
+ // Reads text from an input stream and expects it to match what
+ // WriteStuff() writes.
+ void ReadStuff(ZeroCopyInputStream* input);
+
+ // Similar to WriteStuff, but performs more sophisticated testing.
+ int WriteStuffLarge(ZeroCopyOutputStream* output);
+ // Reads and tests a stream that should have been written to
+ // via WriteStuffLarge().
+ void ReadStuffLarge(ZeroCopyInputStream* input);
+
+#if HAVE_ZLIB
+ string Compress(const string& data, const GzipOutputStream::Options& options);
+ string Uncompress(const string& data);
+#endif
+
+ static const int kBlockSizes[];
+ static const int kBlockSizeCount;
+};
+
+const int IoTest::kBlockSizes[] = {-1, 1, 2, 5, 7, 10, 23, 64};
+const int IoTest::kBlockSizeCount = GOOGLE_ARRAYSIZE(IoTest::kBlockSizes);
+
+bool IoTest::WriteToOutput(ZeroCopyOutputStream* output,
+ const void* data, int size) {
+ const uint8* in = reinterpret_cast<const uint8*>(data);
+ int in_size = size;
+
+ void* out;
+ int out_size;
+
+ while (true) {
+ if (!output->Next(&out, &out_size)) {
+ return false;
+ }
+ EXPECT_GT(out_size, 0);
+
+ if (in_size <= out_size) {
+ memcpy(out, in, in_size);
+ output->BackUp(out_size - in_size);
+ return true;
+ }
+
+ memcpy(out, in, out_size);
+ in += out_size;
+ in_size -= out_size;
+ }
+}
+
+#define MAX_REPEATED_ZEROS 100
+
+int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) {
+ uint8* out = reinterpret_cast<uint8*>(data);
+ int out_size = size;
+
+ const void* in;
+ int in_size = 0;
+
+ int repeated_zeros = 0;
+
+ while (true) {
+ if (!input->Next(&in, &in_size)) {
+ return size - out_size;
+ }
+ EXPECT_GT(in_size, -1);
+ if (in_size == 0) {
+ repeated_zeros++;
+ } else {
+ repeated_zeros = 0;
+ }
+ EXPECT_LT(repeated_zeros, MAX_REPEATED_ZEROS);
+
+ if (out_size <= in_size) {
+ memcpy(out, in, out_size);
+ if (in_size > out_size) {
+ input->BackUp(in_size - out_size);
+ }
+ return size; // Copied all of it.
+ }
+
+ memcpy(out, in, in_size);
+ out += in_size;
+ out_size -= in_size;
+ }
+}
+
+void IoTest::WriteString(ZeroCopyOutputStream* output, const string& str) {
+ EXPECT_TRUE(WriteToOutput(output, str.c_str(), str.size()));
+}
+
+void IoTest::ReadString(ZeroCopyInputStream* input, const string& str) {
+ scoped_array<char> buffer(new char[str.size() + 1]);
+ buffer[str.size()] = '\0';
+ EXPECT_EQ(ReadFromInput(input, buffer.get(), str.size()), str.size());
+ EXPECT_STREQ(str.c_str(), buffer.get());
+}
+
+int IoTest::WriteStuff(ZeroCopyOutputStream* output) {
+ WriteString(output, "Hello world!\n");
+ WriteString(output, "Some te");
+ WriteString(output, "xt. Blah blah.");
+ WriteString(output, "abcdefg");
+ WriteString(output, "01234567890123456789");
+ WriteString(output, "foobar");
+
+ EXPECT_EQ(output->ByteCount(), 68);
+
+ int result = output->ByteCount();
+ return result;
+}
+
+// Reads text from an input stream and expects it to match what WriteStuff()
+// writes.
+void IoTest::ReadStuff(ZeroCopyInputStream* input) {
+ ReadString(input, "Hello world!\n");
+ ReadString(input, "Some text. ");
+ ReadString(input, "Blah ");
+ ReadString(input, "blah.");
+ ReadString(input, "abcdefg");
+ EXPECT_TRUE(input->Skip(20));
+ ReadString(input, "foo");
+ ReadString(input, "bar");
+
+ EXPECT_EQ(input->ByteCount(), 68);
+
+ uint8 byte;
+ EXPECT_EQ(ReadFromInput(input, &byte, 1), 0);
+}
+
+int IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) {
+ WriteString(output, "Hello world!\n");
+ WriteString(output, "Some te");
+ WriteString(output, "xt. Blah blah.");
+ WriteString(output, string(100000, 'x')); // A very long string
+ WriteString(output, string(100000, 'y')); // A very long string
+ WriteString(output, "01234567890123456789");
+
+ EXPECT_EQ(output->ByteCount(), 200055);
+
+ int result = output->ByteCount();
+ return result;
+}
+
+// Reads text from an input stream and expects it to match what WriteStuff()
+// writes.
+void IoTest::ReadStuffLarge(ZeroCopyInputStream* input) {
+ ReadString(input, "Hello world!\nSome text. ");
+ EXPECT_TRUE(input->Skip(5));
+ ReadString(input, "blah.");
+ EXPECT_TRUE(input->Skip(100000 - 10));
+ ReadString(input, string(10, 'x') + string(100000 - 20000, 'y'));
+ EXPECT_TRUE(input->Skip(20000 - 10));
+ ReadString(input, "yyyyyyyyyy01234567890123456789");
+
+ EXPECT_EQ(input->ByteCount(), 200055);
+
+ uint8 byte;
+ EXPECT_EQ(ReadFromInput(input, &byte, 1), 0);
+}
+
+// ===================================================================
+
+TEST_F(IoTest, ArrayIo) {
+ const int kBufferSize = 256;
+ uint8 buffer[kBufferSize];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+ size = WriteStuff(&output);
+ }
+ {
+ ArrayInputStream input(buffer, size, kBlockSizes[j]);
+ ReadStuff(&input);
+ }
+ }
+ }
+}
+
+TEST_F(IoTest, TwoSessionWrite) {
+ // Test that two concatenated write sessions read correctly
+
+ static const char* strA = "0123456789";
+ static const char* strB = "WhirledPeas";
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ char* temp_buffer = new char[40];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ ArrayOutputStream* output =
+ new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+ CodedOutputStream* coded_output = new CodedOutputStream(output);
+ coded_output->WriteVarint32(strlen(strA));
+ coded_output->WriteRaw(strA, strlen(strA));
+ delete coded_output; // flush
+ int64 pos = output->ByteCount();
+ delete output;
+ output = new ArrayOutputStream(
+ buffer + pos, kBufferSize - pos, kBlockSizes[i]);
+ coded_output = new CodedOutputStream(output);
+ coded_output->WriteVarint32(strlen(strB));
+ coded_output->WriteRaw(strB, strlen(strB));
+ delete coded_output; // flush
+ int64 size = pos + output->ByteCount();
+ delete output;
+
+ ArrayInputStream* input =
+ new ArrayInputStream(buffer, size, kBlockSizes[j]);
+ CodedInputStream* coded_input = new CodedInputStream(input);
+ uint32 insize;
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strA), insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strA, insize));
+
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strB), insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strB, insize));
+
+ delete coded_input;
+ delete input;
+ }
+ }
+
+ delete [] temp_buffer;
+ delete [] buffer;
+}
+
+#if HAVE_ZLIB
+TEST_F(IoTest, GzipIo) {
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ for (int z = 0; z < kBlockSizeCount; z++) {
+ int gzip_buffer_size = kBlockSizes[z];
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size, kBlockSizes[j]);
+ GzipInputStream gzin(
+ &input, GzipInputStream::GZIP, gzip_buffer_size);
+ ReadStuff(&gzin);
+ }
+ }
+ }
+ }
+ delete [] buffer;
+}
+
+TEST_F(IoTest, ZlibIo) {
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ for (int z = 0; z < kBlockSizeCount; z++) {
+ int gzip_buffer_size = kBlockSizes[z];
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::ZLIB;
+ if (gzip_buffer_size != -1) {
+ options.buffer_size = gzip_buffer_size;
+ }
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size, kBlockSizes[j]);
+ GzipInputStream gzin(
+ &input, GzipInputStream::ZLIB, gzip_buffer_size);
+ ReadStuff(&gzin);
+ }
+ }
+ }
+ }
+ delete [] buffer;
+}
+
+TEST_F(IoTest, ZlibIoInputAutodetect) {
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ int size;
+ {
+ ArrayOutputStream output(buffer, kBufferSize);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::ZLIB;
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size);
+ GzipInputStream gzin(&input, GzipInputStream::AUTO);
+ ReadStuff(&gzin);
+ }
+ {
+ ArrayOutputStream output(buffer, kBufferSize);
+ GzipOutputStream::Options options;
+ options.format = GzipOutputStream::GZIP;
+ GzipOutputStream gzout(&output, options);
+ WriteStuff(&gzout);
+ gzout.Close();
+ size = output.ByteCount();
+ }
+ {
+ ArrayInputStream input(buffer, size);
+ GzipInputStream gzin(&input, GzipInputStream::AUTO);
+ ReadStuff(&gzin);
+ }
+ delete [] buffer;
+}
+
+string IoTest::Compress(const string& data,
+ const GzipOutputStream::Options& options) {
+ string result;
+ {
+ StringOutputStream output(&result);
+ GzipOutputStream gzout(&output, options);
+ WriteToOutput(&gzout, data.data(), data.size());
+ }
+ return result;
+}
+
+string IoTest::Uncompress(const string& data) {
+ string result;
+ {
+ ArrayInputStream input(data.data(), data.size());
+ GzipInputStream gzin(&input);
+ const void* buffer;
+ int size;
+ while (gzin.Next(&buffer, &size)) {
+ result.append(reinterpret_cast<const char*>(buffer), size);
+ }
+ }
+ return result;
+}
+
+TEST_F(IoTest, CompressionOptions) {
+ // Some ad-hoc testing of compression options.
+
+ string golden;
+ File::ReadFileToStringOrDie(
+ TestSourceDir() + "/google/protobuf/testdata/golden_message",
+ &golden);
+
+ GzipOutputStream::Options options;
+ string gzip_compressed = Compress(golden, options);
+
+ options.compression_level = 0;
+ string not_compressed = Compress(golden, options);
+
+ // Try zlib compression for fun.
+ options = GzipOutputStream::Options();
+ options.format = GzipOutputStream::ZLIB;
+ string zlib_compressed = Compress(golden, options);
+
+ // Uncompressed should be bigger than the original since it should have some
+ // sort of header.
+ EXPECT_GT(not_compressed.size(), golden.size());
+
+ // Higher compression levels should result in smaller sizes.
+ EXPECT_LT(zlib_compressed.size(), not_compressed.size());
+
+ // ZLIB format should differ from GZIP format.
+ EXPECT_TRUE(zlib_compressed != gzip_compressed);
+
+ // Everything should decompress correctly.
+ EXPECT_TRUE(Uncompress(not_compressed) == golden);
+ EXPECT_TRUE(Uncompress(gzip_compressed) == golden);
+ EXPECT_TRUE(Uncompress(zlib_compressed) == golden);
+}
+
+TEST_F(IoTest, TwoSessionWriteGzip) {
+ // Test that two concatenated gzip streams can be read correctly
+
+ static const char* strA = "0123456789";
+ static const char* strB = "QuickBrownFox";
+ const int kBufferSize = 2*1024;
+ uint8* buffer = new uint8[kBufferSize];
+ char* temp_buffer = new char[40];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ ArrayOutputStream* output =
+ new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+ GzipOutputStream* gzout = new GzipOutputStream(output);
+ CodedOutputStream* coded_output = new CodedOutputStream(gzout);
+ int32 outlen = strlen(strA) + 1;
+ coded_output->WriteVarint32(outlen);
+ coded_output->WriteRaw(strA, outlen);
+ delete coded_output; // flush
+ delete gzout; // flush
+ int64 pos = output->ByteCount();
+ delete output;
+ output = new ArrayOutputStream(
+ buffer + pos, kBufferSize - pos, kBlockSizes[i]);
+ gzout = new GzipOutputStream(output);
+ coded_output = new CodedOutputStream(gzout);
+ outlen = strlen(strB) + 1;
+ coded_output->WriteVarint32(outlen);
+ coded_output->WriteRaw(strB, outlen);
+ delete coded_output; // flush
+ delete gzout; // flush
+ int64 size = pos + output->ByteCount();
+ delete output;
+
+ ArrayInputStream* input =
+ new ArrayInputStream(buffer, size, kBlockSizes[j]);
+ GzipInputStream* gzin = new GzipInputStream(input);
+ CodedInputStream* coded_input = new CodedInputStream(gzin);
+ uint32 insize;
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strA) + 1, insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strA, insize))
+ << "strA=" << strA << " in=" << temp_buffer;
+
+ EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+ EXPECT_EQ(strlen(strB) + 1, insize);
+ EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+ EXPECT_EQ(0, memcmp(temp_buffer, strB, insize))
+ << " out_block_size=" << kBlockSizes[i]
+ << " in_block_size=" << kBlockSizes[j]
+ << " pos=" << pos
+ << " size=" << size
+ << " strB=" << strB << " in=" << temp_buffer;
+
+ delete coded_input;
+ delete gzin;
+ delete input;
+ }
+ }
+
+ delete [] temp_buffer;
+ delete [] buffer;
+}
+#endif
+
+// There is no string input, only string output. Also, it doesn't support
+// explicit block sizes. So, we'll only run one test and we'll use
+// ArrayInput to read back the results.
+TEST_F(IoTest, StringIo) {
+ string str;
+ {
+ StringOutputStream output(&str);
+ WriteStuff(&output);
+ }
+ {
+ ArrayInputStream input(str.data(), str.size());
+ ReadStuff(&input);
+ }
+}
+
+
+// To test files, we create a temporary file, write, read, truncate, repeat.
+TEST_F(IoTest, FileIo) {
+ string filename = TestTempDir() + "/zero_copy_stream_test_file";
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ // Make a temporary file.
+ int file =
+ open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777);
+ ASSERT_GE(file, 0);
+
+ {
+ FileOutputStream output(file, kBlockSizes[i]);
+ WriteStuff(&output);
+ EXPECT_EQ(0, output.GetErrno());
+ }
+
+ // Rewind.
+ ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1);
+
+ {
+ FileInputStream input(file, kBlockSizes[j]);
+ ReadStuff(&input);
+ EXPECT_EQ(0, input.GetErrno());
+ }
+
+ close(file);
+ }
+ }
+}
+
+#if HAVE_ZLIB
+TEST_F(IoTest, GzipFileIo) {
+ string filename = TestTempDir() + "/zero_copy_stream_test_file";
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ // Make a temporary file.
+ int file =
+ open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777);
+ ASSERT_GE(file, 0);
+ {
+ FileOutputStream output(file, kBlockSizes[i]);
+ GzipOutputStream gzout(&output);
+ WriteStuffLarge(&gzout);
+ gzout.Close();
+ output.Flush();
+ EXPECT_EQ(0, output.GetErrno());
+ }
+
+ // Rewind.
+ ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1);
+
+ {
+ FileInputStream input(file, kBlockSizes[j]);
+ GzipInputStream gzin(&input);
+ ReadStuffLarge(&gzin);
+ EXPECT_EQ(0, input.GetErrno());
+ }
+
+ close(file);
+ }
+ }
+}
+#endif
+
+// MSVC raises various debugging exceptions if we try to use a file
+// descriptor of -1, defeating our tests below. This class will disable
+// these debug assertions while in scope.
+class MsvcDebugDisabler {
+ public:
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ MsvcDebugDisabler() {
+ old_handler_ = _set_invalid_parameter_handler(MyHandler);
+ old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0);
+ }
+ ~MsvcDebugDisabler() {
+ old_handler_ = _set_invalid_parameter_handler(old_handler_);
+ old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_);
+ }
+
+ static void MyHandler(const wchar_t *expr,
+ const wchar_t *func,
+ const wchar_t *file,
+ unsigned int line,
+ uintptr_t pReserved) {
+ // do nothing
+ }
+
+ _invalid_parameter_handler old_handler_;
+ int old_mode_;
+#else
+ // Dummy constructor and destructor to ensure that GCC doesn't complain
+ // that debug_disabler is an unused variable.
+ MsvcDebugDisabler() {}
+ ~MsvcDebugDisabler() {}
+#endif
+};
+
+// Test that FileInputStreams report errors correctly.
+TEST_F(IoTest, FileReadError) {
+ MsvcDebugDisabler debug_disabler;
+
+ // -1 = invalid file descriptor.
+ FileInputStream input(-1);
+
+ const void* buffer;
+ int size;
+ EXPECT_FALSE(input.Next(&buffer, &size));
+ EXPECT_EQ(EBADF, input.GetErrno());
+}
+
+// Test that FileOutputStreams report errors correctly.
+TEST_F(IoTest, FileWriteError) {
+ MsvcDebugDisabler debug_disabler;
+
+ // -1 = invalid file descriptor.
+ FileOutputStream input(-1);
+
+ void* buffer;
+ int size;
+
+ // The first call to Next() succeeds because it doesn't have anything to
+ // write yet.
+ EXPECT_TRUE(input.Next(&buffer, &size));
+
+ // Second call fails.
+ EXPECT_FALSE(input.Next(&buffer, &size));
+
+ EXPECT_EQ(EBADF, input.GetErrno());
+}
+
+// Pipes are not seekable, so File{Input,Output}Stream ends up doing some
+// different things to handle them. We'll test by writing to a pipe and
+// reading back from it.
+TEST_F(IoTest, PipeIo) {
+ int files[2];
+
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ // Need to create a new pipe each time because ReadStuff() expects
+ // to see EOF at the end.
+ ASSERT_EQ(pipe(files), 0);
+
+ {
+ FileOutputStream output(files[1], kBlockSizes[i]);
+ WriteStuff(&output);
+ EXPECT_EQ(0, output.GetErrno());
+ }
+ close(files[1]); // Send EOF.
+
+ {
+ FileInputStream input(files[0], kBlockSizes[j]);
+ ReadStuff(&input);
+ EXPECT_EQ(0, input.GetErrno());
+ }
+ close(files[0]);
+ }
+ }
+}
+
+// Test using C++ iostreams.
+TEST_F(IoTest, IostreamIo) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ for (int j = 0; j < kBlockSizeCount; j++) {
+ {
+ stringstream stream;
+
+ {
+ OstreamOutputStream output(&stream, kBlockSizes[i]);
+ WriteStuff(&output);
+ EXPECT_FALSE(stream.fail());
+ }
+
+ {
+ IstreamInputStream input(&stream, kBlockSizes[j]);
+ ReadStuff(&input);
+ EXPECT_TRUE(stream.eof());
+ }
+ }
+
+ {
+ stringstream stream;
+
+ {
+ OstreamOutputStream output(&stream, kBlockSizes[i]);
+ WriteStuffLarge(&output);
+ EXPECT_FALSE(stream.fail());
+ }
+
+ {
+ IstreamInputStream input(&stream, kBlockSizes[j]);
+ ReadStuffLarge(&input);
+ EXPECT_TRUE(stream.eof());
+ }
+ }
+ }
+ }
+}
+
+// To test ConcatenatingInputStream, we create several ArrayInputStreams
+// covering a buffer and then concatenate them.
+TEST_F(IoTest, ConcatenatingInputStream) {
+ const int kBufferSize = 256;
+ uint8 buffer[kBufferSize];
+
+ // Fill the buffer.
+ ArrayOutputStream output(buffer, kBufferSize);
+ WriteStuff(&output);
+
+ // Now split it up into multiple streams of varying sizes.
+ ASSERT_EQ(68, output.ByteCount()); // Test depends on this.
+ ArrayInputStream input1(buffer , 12);
+ ArrayInputStream input2(buffer + 12, 7);
+ ArrayInputStream input3(buffer + 19, 6);
+ ArrayInputStream input4(buffer + 25, 15);
+ ArrayInputStream input5(buffer + 40, 0);
+ // Note: We want to make sure we have a stream boundary somewhere between
+ // bytes 42 and 62, which is the range that it Skip()ed by ReadStuff(). This
+ // tests that a bug that existed in the original code for Skip() is fixed.
+ ArrayInputStream input6(buffer + 40, 10);
+ ArrayInputStream input7(buffer + 50, 18); // Total = 68 bytes.
+
+ ZeroCopyInputStream* streams[] =
+ {&input1, &input2, &input3, &input4, &input5, &input6, &input7};
+
+ // Create the concatenating stream and read.
+ ConcatenatingInputStream input(streams, GOOGLE_ARRAYSIZE(streams));
+ ReadStuff(&input);
+}
+
+// To test LimitingInputStream, we write our golden text to a buffer, then
+// create an ArrayInputStream that contains the whole buffer (not just the
+// bytes written), then use a LimitingInputStream to limit it just to the
+// bytes written.
+TEST_F(IoTest, LimitingInputStream) {
+ const int kBufferSize = 256;
+ uint8 buffer[kBufferSize];
+
+ // Fill the buffer.
+ ArrayOutputStream output(buffer, kBufferSize);
+ WriteStuff(&output);
+
+ // Set up input.
+ ArrayInputStream array_input(buffer, kBufferSize);
+ LimitingInputStream input(&array_input, output.ByteCount());
+
+ ReadStuff(&input);
+}
+
+// Check that a zero-size array doesn't confuse the code.
+TEST(ZeroSizeArray, Input) {
+ ArrayInputStream input(NULL, 0);
+ const void* data;
+ int size;
+ EXPECT_FALSE(input.Next(&data, &size));
+}
+
+TEST(ZeroSizeArray, Output) {
+ ArrayOutputStream output(NULL, 0);
+ void* data;
+ int size;
+ EXPECT_FALSE(output.Next(&data, &size));
+}
+
+} // namespace
+} // namespace io
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/lite_unittest.cc b/src/third_party/protobuf/src/google/protobuf/lite_unittest.cc
new file mode 100644
index 0000000..ffeec3c
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/lite_unittest.cc
@@ -0,0 +1,112 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <string>
+#include <iostream>
+
+#include <google/protobuf/test_util_lite.h>
+#include <google/protobuf/stubs/common.h>
+
+using namespace std;
+
+int main(int argc, char* argv[]) {
+ string data, packed_data;
+
+ {
+ protobuf_unittest::TestAllTypesLite message, message2, message3;
+ google::protobuf::TestUtilLite::ExpectClear(message);
+ google::protobuf::TestUtilLite::SetAllFields(&message);
+ message2.CopyFrom(message);
+ data = message.SerializeAsString();
+ message3.ParseFromString(data);
+ google::protobuf::TestUtilLite::ExpectAllFieldsSet(message);
+ google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2);
+ google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3);
+ google::protobuf::TestUtilLite::ModifyRepeatedFields(&message);
+ google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message);
+ message.Clear();
+ google::protobuf::TestUtilLite::ExpectClear(message);
+ }
+
+ {
+ protobuf_unittest::TestAllExtensionsLite message, message2, message3;
+ google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+ google::protobuf::TestUtilLite::SetAllExtensions(&message);
+ message2.CopyFrom(message);
+ string extensions_data = message.SerializeAsString();
+ GOOGLE_CHECK(extensions_data == data);
+ message3.ParseFromString(extensions_data);
+ google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message);
+ google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
+ google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3);
+ google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message);
+ google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message);
+ message.Clear();
+ google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+ }
+
+ {
+ protobuf_unittest::TestPackedTypesLite message, message2, message3;
+ google::protobuf::TestUtilLite::ExpectPackedClear(message);
+ google::protobuf::TestUtilLite::SetPackedFields(&message);
+ message2.CopyFrom(message);
+ packed_data = message.SerializeAsString();
+ message3.ParseFromString(packed_data);
+ google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message);
+ google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2);
+ google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3);
+ google::protobuf::TestUtilLite::ModifyPackedFields(&message);
+ google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message);
+ message.Clear();
+ google::protobuf::TestUtilLite::ExpectPackedClear(message);
+ }
+
+ {
+ protobuf_unittest::TestPackedExtensionsLite message, message2, message3;
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+ google::protobuf::TestUtilLite::SetPackedExtensions(&message);
+ message2.CopyFrom(message);
+ string packed_extensions_data = message.SerializeAsString();
+ GOOGLE_CHECK(packed_extensions_data == packed_data);
+ message3.ParseFromString(packed_extensions_data);
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message);
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3);
+ google::protobuf::TestUtilLite::ModifyPackedExtensions(&message);
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message);
+ message.Clear();
+ google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+ }
+
+ cout << "PASS" << endl;
+ return 0;
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/message.cc b/src/third_party/protobuf/src/google/protobuf/message.cc
new file mode 100644
index 0000000..91e6878
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/message.cc
@@ -0,0 +1,318 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <stack>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/message.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map-util.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+using internal::ReflectionOps;
+
+Message::~Message() {}
+
+void Message::MergeFrom(const Message& from) {
+ const Descriptor* descriptor = GetDescriptor();
+ GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
+ << ": Tried to merge from a message with a different type. "
+ "to: " << descriptor->full_name() << ", "
+ "from:" << from.GetDescriptor()->full_name();
+ ReflectionOps::Merge(from, this);
+}
+
+void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
+ MergeFrom(*down_cast<const Message*>(&other));
+}
+
+void Message::CopyFrom(const Message& from) {
+ const Descriptor* descriptor = GetDescriptor();
+ GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
+ << ": Tried to copy from a message with a different type."
+ "to: " << descriptor->full_name() << ", "
+ "from:" << from.GetDescriptor()->full_name();
+ ReflectionOps::Copy(from, this);
+}
+
+string Message::GetTypeName() const {
+ return GetDescriptor()->full_name();
+}
+
+void Message::Clear() {
+ ReflectionOps::Clear(this);
+}
+
+bool Message::IsInitialized() const {
+ return ReflectionOps::IsInitialized(*this);
+}
+
+void Message::FindInitializationErrors(vector<string>* errors) const {
+ return ReflectionOps::FindInitializationErrors(*this, "", errors);
+}
+
+string Message::InitializationErrorString() const {
+ vector<string> errors;
+ FindInitializationErrors(&errors);
+ return JoinStrings(errors, ", ");
+}
+
+void Message::CheckInitialized() const {
+ GOOGLE_CHECK(IsInitialized())
+ << "Message of type \"" << GetDescriptor()->full_name()
+ << "\" is missing required fields: " << InitializationErrorString();
+}
+
+void Message::DiscardUnknownFields() {
+ return ReflectionOps::DiscardUnknownFields(this);
+}
+
+bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
+ return WireFormat::ParseAndMergePartial(input, this);
+}
+
+bool Message::ParseFromFileDescriptor(int file_descriptor) {
+ io::FileInputStream input(file_descriptor);
+ return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0;
+}
+
+bool Message::ParsePartialFromFileDescriptor(int file_descriptor) {
+ io::FileInputStream input(file_descriptor);
+ return ParsePartialFromZeroCopyStream(&input) && input.GetErrno() == 0;
+}
+
+bool Message::ParseFromIstream(istream* input) {
+ io::IstreamInputStream zero_copy_input(input);
+ return ParseFromZeroCopyStream(&zero_copy_input) && input->eof();
+}
+
+bool Message::ParsePartialFromIstream(istream* input) {
+ io::IstreamInputStream zero_copy_input(input);
+ return ParsePartialFromZeroCopyStream(&zero_copy_input) && input->eof();
+}
+
+
+void Message::SerializeWithCachedSizes(
+ io::CodedOutputStream* output) const {
+ WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output);
+}
+
+int Message::ByteSize() const {
+ int size = WireFormat::ByteSize(*this);
+ SetCachedSize(size);
+ return size;
+}
+
+void Message::SetCachedSize(int size) const {
+ GOOGLE_LOG(FATAL) << "Message class \"" << GetDescriptor()->full_name()
+ << "\" implements neither SetCachedSize() nor ByteSize(). "
+ "Must implement one or the other.";
+}
+
+int Message::SpaceUsed() const {
+ return GetReflection()->SpaceUsed(*this);
+}
+
+bool Message::SerializeToFileDescriptor(int file_descriptor) const {
+ io::FileOutputStream output(file_descriptor);
+ return SerializeToZeroCopyStream(&output);
+}
+
+bool Message::SerializePartialToFileDescriptor(int file_descriptor) const {
+ io::FileOutputStream output(file_descriptor);
+ return SerializePartialToZeroCopyStream(&output);
+}
+
+bool Message::SerializeToOstream(ostream* output) const {
+ {
+ io::OstreamOutputStream zero_copy_output(output);
+ if (!SerializeToZeroCopyStream(&zero_copy_output)) return false;
+ }
+ return output->good();
+}
+
+bool Message::SerializePartialToOstream(ostream* output) const {
+ io::OstreamOutputStream zero_copy_output(output);
+ return SerializePartialToZeroCopyStream(&zero_copy_output);
+}
+
+
+Reflection::~Reflection() {}
+
+// ===================================================================
+// MessageFactory
+
+MessageFactory::~MessageFactory() {}
+
+namespace {
+
+class GeneratedMessageFactory : public MessageFactory {
+ public:
+ GeneratedMessageFactory();
+ ~GeneratedMessageFactory();
+
+ static GeneratedMessageFactory* singleton();
+
+ typedef void RegistrationFunc(const string&);
+ void RegisterFile(const char* file, RegistrationFunc* registration_func);
+ void RegisterType(const Descriptor* descriptor, const Message* prototype);
+
+ // implements MessageFactory ---------------------------------------
+ const Message* GetPrototype(const Descriptor* type);
+
+ private:
+ // Only written at static init time, so does not require locking.
+ hash_map<const char*, RegistrationFunc*,
+ hash<const char*>, streq> file_map_;
+
+ // Initialized lazily, so requires locking.
+ Mutex mutex_;
+ hash_map<const Descriptor*, const Message*> type_map_;
+};
+
+GeneratedMessageFactory* generated_message_factory_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_);
+
+void ShutdownGeneratedMessageFactory() {
+ delete generated_message_factory_;
+}
+
+void InitGeneratedMessageFactory() {
+ generated_message_factory_ = new GeneratedMessageFactory;
+ internal::OnShutdown(&ShutdownGeneratedMessageFactory);
+}
+
+GeneratedMessageFactory::GeneratedMessageFactory() {}
+GeneratedMessageFactory::~GeneratedMessageFactory() {}
+
+GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
+ ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_,
+ &InitGeneratedMessageFactory);
+ return generated_message_factory_;
+}
+
+void GeneratedMessageFactory::RegisterFile(
+ const char* file, RegistrationFunc* registration_func) {
+ if (!InsertIfNotPresent(&file_map_, file, registration_func)) {
+ GOOGLE_LOG(FATAL) << "File is already registered: " << file;
+ }
+}
+
+void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor,
+ const Message* prototype) {
+ GOOGLE_DCHECK_EQ(descriptor->file()->pool(), DescriptorPool::generated_pool())
+ << "Tried to register a non-generated type with the generated "
+ "type registry.";
+
+ // This should only be called as a result of calling a file registration
+ // function during GetPrototype(), in which case we already have locked
+ // the mutex.
+ mutex_.AssertHeld();
+ if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) {
+ GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name();
+ }
+}
+
+const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
+ {
+ ReaderMutexLock lock(&mutex_);
+ const Message* result = FindPtrOrNull(type_map_, type);
+ if (result != NULL) return result;
+ }
+
+ // If the type is not in the generated pool, then we can't possibly handle
+ // it.
+ if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL;
+
+ // Apparently the file hasn't been registered yet. Let's do that now.
+ RegistrationFunc* registration_func =
+ FindPtrOrNull(file_map_, type->file()->name().c_str());
+ if (registration_func == NULL) {
+ GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't "
+ "registered: " << type->file()->name();
+ return NULL;
+ }
+
+ WriterMutexLock lock(&mutex_);
+
+ // Check if another thread preempted us.
+ const Message* result = FindPtrOrNull(type_map_, type);
+ if (result == NULL) {
+ // Nope. OK, register everything.
+ registration_func(type->file()->name());
+ // Should be here now.
+ result = FindPtrOrNull(type_map_, type);
+ }
+
+ if (result == NULL) {
+ GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't "
+ << "registered: " << type->full_name();
+ }
+
+ return result;
+}
+
+} // namespace
+
+MessageFactory* MessageFactory::generated_factory() {
+ return GeneratedMessageFactory::singleton();
+}
+
+void MessageFactory::InternalRegisterGeneratedFile(
+ const char* filename, void (*register_messages)(const string&)) {
+ GeneratedMessageFactory::singleton()->RegisterFile(filename,
+ register_messages);
+}
+
+void MessageFactory::InternalRegisterGeneratedMessage(
+ const Descriptor* descriptor, const Message* prototype) {
+ GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
+}
+
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/message.h b/src/third_party/protobuf/src/google/protobuf/message.h
new file mode 100644
index 0000000..4bbc641
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/message.h
@@ -0,0 +1,692 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines Message, the abstract interface implemented by non-lite
+// protocol message objects. Although it's possible to implement this
+// interface manually, most users will use the protocol compiler to
+// generate implementations.
+//
+// Example usage:
+//
+// Say you have a message defined as:
+//
+// message Foo {
+// optional string text = 1;
+// repeated int32 numbers = 2;
+// }
+//
+// Then, if you used the protocol compiler to generate a class from the above
+// definition, you could use it like so:
+//
+// string data; // Will store a serialized version of the message.
+//
+// {
+// // Create a message and serialize it.
+// Foo foo;
+// foo.set_text("Hello World!");
+// foo.add_numbers(1);
+// foo.add_numbers(5);
+// foo.add_numbers(42);
+//
+// foo.SerializeToString(&data);
+// }
+//
+// {
+// // Parse the serialized message and check that it contains the
+// // correct data.
+// Foo foo;
+// foo.ParseFromString(data);
+//
+// assert(foo.text() == "Hello World!");
+// assert(foo.numbers_size() == 3);
+// assert(foo.numbers(0) == 1);
+// assert(foo.numbers(1) == 5);
+// assert(foo.numbers(2) == 42);
+// }
+//
+// {
+// // Same as the last block, but do it dynamically via the Message
+// // reflection interface.
+// Message* foo = new Foo;
+// Descriptor* descriptor = foo->GetDescriptor();
+//
+// // Get the descriptors for the fields we're interested in and verify
+// // their types.
+// FieldDescriptor* text_field = descriptor->FindFieldByName("text");
+// assert(text_field != NULL);
+// assert(text_field->type() == FieldDescriptor::TYPE_STRING);
+// assert(text_field->label() == FieldDescriptor::TYPE_OPTIONAL);
+// FieldDescriptor* numbers_field = descriptor->FindFieldByName("numbers");
+// assert(numbers_field != NULL);
+// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
+// assert(numbers_field->label() == FieldDescriptor::TYPE_REPEATED);
+//
+// // Parse the message.
+// foo->ParseFromString(data);
+//
+// // Use the reflection interface to examine the contents.
+// const Reflection* reflection = foo->GetReflection();
+// assert(reflection->GetString(foo, text_field) == "Hello World!");
+// assert(reflection->FieldSize(foo, numbers_field) == 3);
+// assert(reflection->GetRepeatedInt32(foo, numbers_field, 0) == 1);
+// assert(reflection->GetRepeatedInt32(foo, numbers_field, 1) == 5);
+// assert(reflection->GetRepeatedInt32(foo, numbers_field, 2) == 42);
+//
+// delete foo;
+// }
+
+#ifndef GOOGLE_PROTOBUF_MESSAGE_H__
+#define GOOGLE_PROTOBUF_MESSAGE_H__
+
+#include <vector>
+#include <string>
+
+#ifdef __DECCXX
+// HP C++'s iosfwd doesn't work.
+#include <iostream>
+#else
+#include <iosfwd>
+#endif
+
+#include <google/protobuf/message_lite.h>
+
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class Message;
+class Reflection;
+class MessageFactory;
+
+// Defined in other files.
+class Descriptor; // descriptor.h
+class FieldDescriptor; // descriptor.h
+class EnumDescriptor; // descriptor.h
+class EnumValueDescriptor; // descriptor.h
+namespace io {
+ class ZeroCopyInputStream; // zero_copy_stream.h
+ class ZeroCopyOutputStream; // zero_copy_stream.h
+ class CodedInputStream; // coded_stream.h
+ class CodedOutputStream; // coded_stream.h
+}
+class UnknownFieldSet; // unknown_field_set.h
+
+// A container to hold message metadata.
+struct Metadata {
+ const Descriptor* descriptor;
+ const Reflection* reflection;
+};
+
+// Returns the EnumDescriptor for enum type E, which must be a
+// proto-declared enum type. Code generated by the protocol compiler
+// will include specializations of this template for each enum type declared.
+template <typename E>
+const EnumDescriptor* GetEnumDescriptor();
+
+// Abstract interface for protocol messages.
+//
+// See also MessageLite, which contains most every-day operations. Message
+// adds descriptors and reflection on top of that.
+//
+// The methods of this class that are virtual but not pure-virtual have
+// default implementations based on reflection. Message classes which are
+// optimized for speed will want to override these with faster implementations,
+// but classes optimized for code size may be happy with keeping them. See
+// the optimize_for option in descriptor.proto.
+class LIBPROTOBUF_EXPORT Message : public MessageLite {
+ public:
+ inline Message() {}
+ virtual ~Message();
+
+ // Basic Operations ------------------------------------------------
+
+ // Construct a new instance of the same type. Ownership is passed to the
+ // caller. (This is also defined in MessageLite, but is defined again here
+ // for return-type covariance.)
+ virtual Message* New() const = 0;
+
+ // Make this message into a copy of the given message. The given message
+ // must have the same descriptor, but need not necessarily be the same class.
+ // By default this is just implemented as "Clear(); MergeFrom(from);".
+ virtual void CopyFrom(const Message& from);
+
+ // Merge the fields from the given message into this message. Singular
+ // fields will be overwritten, except for embedded messages which will
+ // be merged. Repeated fields will be concatenated. The given message
+ // must be of the same type as this message (i.e. the exact same class).
+ virtual void MergeFrom(const Message& from);
+
+ // Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with
+ // a nice error message.
+ void CheckInitialized() const;
+
+ // Slowly build a list of all required fields that are not set.
+ // This is much, much slower than IsInitialized() as it is implemented
+ // purely via reflection. Generally, you should not call this unless you
+ // have already determined that an error exists by calling IsInitialized().
+ void FindInitializationErrors(vector<string>* errors) const;
+
+ // Like FindInitializationErrors, but joins all the strings, delimited by
+ // commas, and returns them.
+ string InitializationErrorString() const;
+
+ // Clears all unknown fields from this message and all embedded messages.
+ // Normally, if unknown tag numbers are encountered when parsing a message,
+ // the tag and value are stored in the message's UnknownFieldSet and
+ // then written back out when the message is serialized. This allows servers
+ // which simply route messages to other servers to pass through messages
+ // that have new field definitions which they don't yet know about. However,
+ // this behavior can have security implications. To avoid it, call this
+ // method after parsing.
+ //
+ // See Reflection::GetUnknownFields() for more on unknown fields.
+ virtual void DiscardUnknownFields();
+
+ // Computes (an estimate of) the total number of bytes currently used for
+ // storing the message in memory. The default implementation calls the
+ // Reflection object's SpaceUsed() method.
+ virtual int SpaceUsed() const;
+
+ // Debugging & Testing----------------------------------------------
+
+ // Generates a human readable form of this message, useful for debugging
+ // and other purposes.
+ string DebugString() const;
+ // Like DebugString(), but with less whitespace.
+ string ShortDebugString() const;
+ // Like DebugString(), but do not escape UTF-8 byte sequences.
+ string Utf8DebugString() const;
+ // Convenience function useful in GDB. Prints DebugString() to stdout.
+ void PrintDebugString() const;
+
+ // Heavy I/O -------------------------------------------------------
+ // Additional parsing and serialization methods not implemented by
+ // MessageLite because they are not supported by the lite library.
+
+ // Parse a protocol buffer from a file descriptor. If successful, the entire
+ // input will be consumed.
+ bool ParseFromFileDescriptor(int file_descriptor);
+ // Like ParseFromFileDescriptor(), but accepts messages that are missing
+ // required fields.
+ bool ParsePartialFromFileDescriptor(int file_descriptor);
+ // Parse a protocol buffer from a C++ istream. If successful, the entire
+ // input will be consumed.
+ bool ParseFromIstream(istream* input);
+ // Like ParseFromIstream(), but accepts messages that are missing
+ // required fields.
+ bool ParsePartialFromIstream(istream* input);
+
+ // Serialize the message and write it to the given file descriptor. All
+ // required fields must be set.
+ bool SerializeToFileDescriptor(int file_descriptor) const;
+ // Like SerializeToFileDescriptor(), but allows missing required fields.
+ bool SerializePartialToFileDescriptor(int file_descriptor) const;
+ // Serialize the message and write it to the given C++ ostream. All
+ // required fields must be set.
+ bool SerializeToOstream(ostream* output) const;
+ // Like SerializeToOstream(), but allows missing required fields.
+ bool SerializePartialToOstream(ostream* output) const;
+
+
+ // Reflection-based methods ----------------------------------------
+ // These methods are pure-virtual in MessageLite, but Message provides
+ // reflection-based default implementations.
+
+ virtual string GetTypeName() const;
+ virtual void Clear();
+ virtual bool IsInitialized() const;
+ virtual void CheckTypeAndMergeFrom(const MessageLite& other);
+ virtual bool MergePartialFromCodedStream(io::CodedInputStream* input);
+ virtual int ByteSize() const;
+ virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const;
+
+ private:
+ // This is called only by the default implementation of ByteSize(), to
+ // update the cached size. If you override ByteSize(), you do not need
+ // to override this. If you do not override ByteSize(), you MUST override
+ // this; the default implementation will crash.
+ //
+ // The method is private because subclasses should never call it; only
+ // override it. Yes, C++ lets you do that. Crazy, huh?
+ virtual void SetCachedSize(int size) const;
+
+ public:
+
+ // Introspection ---------------------------------------------------
+
+ // Typedef for backwards-compatibility.
+ typedef google::protobuf::Reflection Reflection;
+
+ // Get a Descriptor for this message's type. This describes what
+ // fields the message contains, the types of those fields, etc.
+ const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; }
+
+ // Get the Reflection interface for this Message, which can be used to
+ // read and modify the fields of the Message dynamically (in other words,
+ // without knowing the message type at compile time). This object remains
+ // property of the Message.
+ //
+ // This method remains virtual in case a subclass does not implement
+ // reflection and wants to override the default behavior.
+ virtual const Reflection* GetReflection() const {
+ return GetMetadata().reflection;
+ }
+
+ protected:
+ // Get a struct containing the metadata for the Message. Most subclasses only
+ // need to implement this method, rather than the GetDescriptor() and
+ // GetReflection() wrappers.
+ virtual Metadata GetMetadata() const = 0;
+
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message);
+};
+
+// This interface contains methods that can be used to dynamically access
+// and modify the fields of a protocol message. Their semantics are
+// similar to the accessors the protocol compiler generates.
+//
+// To get the Reflection for a given Message, call Message::GetReflection().
+//
+// This interface is separate from Message only for efficiency reasons;
+// the vast majority of implementations of Message will share the same
+// implementation of Reflection (GeneratedMessageReflection,
+// defined in generated_message.h), and all Messages of a particular class
+// should share the same Reflection object (though you should not rely on
+// the latter fact).
+//
+// There are several ways that these methods can be used incorrectly. For
+// example, any of the following conditions will lead to undefined
+// results (probably assertion failures):
+// - The FieldDescriptor is not a field of this message type.
+// - The method called is not appropriate for the field's type. For
+// each field type in FieldDescriptor::TYPE_*, there is only one
+// Get*() method, one Set*() method, and one Add*() method that is
+// valid for that type. It should be obvious which (except maybe
+// for TYPE_BYTES, which are represented using strings in C++).
+// - A Get*() or Set*() method for singular fields is called on a repeated
+// field.
+// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated
+// field.
+// - The Message object passed to any method is not of the right type for
+// this Reflection object (i.e. message.GetReflection() != reflection).
+//
+// You might wonder why there is not any abstract representation for a field
+// of arbitrary type. E.g., why isn't there just a "GetField()" method that
+// returns "const Field&", where "Field" is some class with accessors like
+// "GetInt32Value()". The problem is that someone would have to deal with
+// allocating these Field objects. For generated message classes, having to
+// allocate space for an additional object to wrap every field would at least
+// double the message's memory footprint, probably worse. Allocating the
+// objects on-demand, on the other hand, would be expensive and prone to
+// memory leaks. So, instead we ended up with this flat interface.
+//
+// TODO(kenton): Create a utility class which callers can use to read and
+// write fields from a Reflection without paying attention to the type.
+class LIBPROTOBUF_EXPORT Reflection {
+ public:
+ // TODO(kenton): Remove parameter.
+ inline Reflection() {}
+ virtual ~Reflection();
+
+ // Get the UnknownFieldSet for the message. This contains fields which
+ // were seen when the Message was parsed but were not recognized according
+ // to the Message's definition.
+ virtual const UnknownFieldSet& GetUnknownFields(
+ const Message& message) const = 0;
+ // Get a mutable pointer to the UnknownFieldSet for the message. This
+ // contains fields which were seen when the Message was parsed but were not
+ // recognized according to the Message's definition.
+ virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0;
+
+ // Estimate the amount of memory used by the message object.
+ virtual int SpaceUsed(const Message& message) const = 0;
+
+ // Check if the given non-repeated field is set.
+ virtual bool HasField(const Message& message,
+ const FieldDescriptor* field) const = 0;
+
+ // Get the number of elements of a repeated field.
+ virtual int FieldSize(const Message& message,
+ const FieldDescriptor* field) const = 0;
+
+ // Clear the value of a field, so that HasField() returns false or
+ // FieldSize() returns zero.
+ virtual void ClearField(Message* message,
+ const FieldDescriptor* field) const = 0;
+
+ // Remove the last element of a repeated field.
+ // We don't provide a way to remove any element other than the last
+ // because it invites inefficient use, such as O(n^2) filtering loops
+ // that should have been O(n). If you want to remove an element other
+ // than the last, the best way to do it is to re-arrange the elements
+ // (using Swap()) so that the one you want removed is at the end, then
+ // call RemoveLast().
+ virtual void RemoveLast(Message* message,
+ const FieldDescriptor* field) const = 0;
+
+ // Swap the complete contents of two messages.
+ virtual void Swap(Message* message1, Message* message2) const = 0;
+
+ // Swap two elements of a repeated field.
+ virtual void SwapElements(Message* message,
+ const FieldDescriptor* field,
+ int index1,
+ int index2) const = 0;
+
+ // List all fields of the message which are currently set. This includes
+ // extensions. Singular fields will only be listed if HasField(field) would
+ // return true and repeated fields will only be listed if FieldSize(field)
+ // would return non-zero. Fields (both normal fields and extension fields)
+ // will be listed ordered by field number.
+ virtual void ListFields(const Message& message,
+ vector<const FieldDescriptor*>* output) const = 0;
+
+ // Singular field getters ------------------------------------------
+ // These get the value of a non-repeated field. They return the default
+ // value for fields that aren't set.
+
+ virtual int32 GetInt32 (const Message& message,
+ const FieldDescriptor* field) const = 0;
+ virtual int64 GetInt64 (const Message& message,
+ const FieldDescriptor* field) const = 0;
+ virtual uint32 GetUInt32(const Message& message,
+ const FieldDescriptor* field) const = 0;
+ virtual uint64 GetUInt64(const Message& message,
+ const FieldDescriptor* field) const = 0;
+ virtual float GetFloat (const Message& message,
+ const FieldDescriptor* field) const = 0;
+ virtual double GetDouble(const Message& message,
+ const FieldDescriptor* field) const = 0;
+ virtual bool GetBool (const Message& message,
+ const FieldDescriptor* field) const = 0;
+ virtual string GetString(const Message& message,
+ const FieldDescriptor* field) const = 0;
+ virtual const EnumValueDescriptor* GetEnum(
+ const Message& message, const FieldDescriptor* field) const = 0;
+ // See MutableMessage() for the meaning of the "factory" parameter.
+ virtual const Message& GetMessage(const Message& message,
+ const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const = 0;
+
+ // Get a string value without copying, if possible.
+ //
+ // GetString() necessarily returns a copy of the string. This can be
+ // inefficient when the string is already stored in a string object in the
+ // underlying message. GetStringReference() will return a reference to the
+ // underlying string in this case. Otherwise, it will copy the string into
+ // *scratch and return that.
+ //
+ // Note: It is perfectly reasonable and useful to write code like:
+ // str = reflection->GetStringReference(field, &str);
+ // This line would ensure that only one copy of the string is made
+ // regardless of the field's underlying representation. When initializing
+ // a newly-constructed string, though, it's just as fast and more readable
+ // to use code like:
+ // string str = reflection->GetString(field);
+ virtual const string& GetStringReference(const Message& message,
+ const FieldDescriptor* field,
+ string* scratch) const = 0;
+
+
+ // Singular field mutators -----------------------------------------
+ // These mutate the value of a non-repeated field.
+
+ virtual void SetInt32 (Message* message,
+ const FieldDescriptor* field, int32 value) const = 0;
+ virtual void SetInt64 (Message* message,
+ const FieldDescriptor* field, int64 value) const = 0;
+ virtual void SetUInt32(Message* message,
+ const FieldDescriptor* field, uint32 value) const = 0;
+ virtual void SetUInt64(Message* message,
+ const FieldDescriptor* field, uint64 value) const = 0;
+ virtual void SetFloat (Message* message,
+ const FieldDescriptor* field, float value) const = 0;
+ virtual void SetDouble(Message* message,
+ const FieldDescriptor* field, double value) const = 0;
+ virtual void SetBool (Message* message,
+ const FieldDescriptor* field, bool value) const = 0;
+ virtual void SetString(Message* message,
+ const FieldDescriptor* field,
+ const string& value) const = 0;
+ virtual void SetEnum (Message* message,
+ const FieldDescriptor* field,
+ const EnumValueDescriptor* value) const = 0;
+ // Get a mutable pointer to a field with a message type. If a MessageFactory
+ // is provided, it will be used to construct instances of the sub-message;
+ // otherwise, the default factory is used. If the field is an extension that
+ // does not live in the same pool as the containing message's descriptor (e.g.
+ // it lives in an overlay pool), then a MessageFactory must be provided.
+ // If you have no idea what that meant, then you probably don't need to worry
+ // about it (don't provide a MessageFactory). WARNING: If the
+ // FieldDescriptor is for a compiled-in extension, then
+ // factory->GetPrototype(field->message_type() MUST return an instance of the
+ // compiled-in class for this type, NOT DynamicMessage.
+ virtual Message* MutableMessage(Message* message,
+ const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const = 0;
+
+
+ // Repeated field getters ------------------------------------------
+ // These get the value of one element of a repeated field.
+
+ virtual int32 GetRepeatedInt32 (const Message& message,
+ const FieldDescriptor* field,
+ int index) const = 0;
+ virtual int64 GetRepeatedInt64 (const Message& message,
+ const FieldDescriptor* field,
+ int index) const = 0;
+ virtual uint32 GetRepeatedUInt32(const Message& message,
+ const FieldDescriptor* field,
+ int index) const = 0;
+ virtual uint64 GetRepeatedUInt64(const Message& message,
+ const FieldDescriptor* field,
+ int index) const = 0;
+ virtual float GetRepeatedFloat (const Message& message,
+ const FieldDescriptor* field,
+ int index) const = 0;
+ virtual double GetRepeatedDouble(const Message& message,
+ const FieldDescriptor* field,
+ int index) const = 0;
+ virtual bool GetRepeatedBool (const Message& message,
+ const FieldDescriptor* field,
+ int index) const = 0;
+ virtual string GetRepeatedString(const Message& message,
+ const FieldDescriptor* field,
+ int index) const = 0;
+ virtual const EnumValueDescriptor* GetRepeatedEnum(
+ const Message& message,
+ const FieldDescriptor* field, int index) const = 0;
+ virtual const Message& GetRepeatedMessage(
+ const Message& message,
+ const FieldDescriptor* field, int index) const = 0;
+
+ // See GetStringReference(), above.
+ virtual const string& GetRepeatedStringReference(
+ const Message& message, const FieldDescriptor* field,
+ int index, string* scratch) const = 0;
+
+
+ // Repeated field mutators -----------------------------------------
+ // These mutate the value of one element of a repeated field.
+
+ virtual void SetRepeatedInt32 (Message* message,
+ const FieldDescriptor* field,
+ int index, int32 value) const = 0;
+ virtual void SetRepeatedInt64 (Message* message,
+ const FieldDescriptor* field,
+ int index, int64 value) const = 0;
+ virtual void SetRepeatedUInt32(Message* message,
+ const FieldDescriptor* field,
+ int index, uint32 value) const = 0;
+ virtual void SetRepeatedUInt64(Message* message,
+ const FieldDescriptor* field,
+ int index, uint64 value) const = 0;
+ virtual void SetRepeatedFloat (Message* message,
+ const FieldDescriptor* field,
+ int index, float value) const = 0;
+ virtual void SetRepeatedDouble(Message* message,
+ const FieldDescriptor* field,
+ int index, double value) const = 0;
+ virtual void SetRepeatedBool (Message* message,
+ const FieldDescriptor* field,
+ int index, bool value) const = 0;
+ virtual void SetRepeatedString(Message* message,
+ const FieldDescriptor* field,
+ int index, const string& value) const = 0;
+ virtual void SetRepeatedEnum(Message* message,
+ const FieldDescriptor* field, int index,
+ const EnumValueDescriptor* value) const = 0;
+ // Get a mutable pointer to an element of a repeated field with a message
+ // type.
+ virtual Message* MutableRepeatedMessage(
+ Message* message, const FieldDescriptor* field, int index) const = 0;
+
+
+ // Repeated field adders -------------------------------------------
+ // These add an element to a repeated field.
+
+ virtual void AddInt32 (Message* message,
+ const FieldDescriptor* field, int32 value) const = 0;
+ virtual void AddInt64 (Message* message,
+ const FieldDescriptor* field, int64 value) const = 0;
+ virtual void AddUInt32(Message* message,
+ const FieldDescriptor* field, uint32 value) const = 0;
+ virtual void AddUInt64(Message* message,
+ const FieldDescriptor* field, uint64 value) const = 0;
+ virtual void AddFloat (Message* message,
+ const FieldDescriptor* field, float value) const = 0;
+ virtual void AddDouble(Message* message,
+ const FieldDescriptor* field, double value) const = 0;
+ virtual void AddBool (Message* message,
+ const FieldDescriptor* field, bool value) const = 0;
+ virtual void AddString(Message* message,
+ const FieldDescriptor* field,
+ const string& value) const = 0;
+ virtual void AddEnum (Message* message,
+ const FieldDescriptor* field,
+ const EnumValueDescriptor* value) const = 0;
+ // See MutableMessage() for comments on the "factory" parameter.
+ virtual Message* AddMessage(Message* message,
+ const FieldDescriptor* field,
+ MessageFactory* factory = NULL) const = 0;
+
+
+ // Extensions ------------------------------------------------------
+
+ // Try to find an extension of this message type by fully-qualified field
+ // name. Returns NULL if no extension is known for this name or number.
+ virtual const FieldDescriptor* FindKnownExtensionByName(
+ const string& name) const = 0;
+
+ // Try to find an extension of this message type by field number.
+ // Returns NULL if no extension is known for this name or number.
+ virtual const FieldDescriptor* FindKnownExtensionByNumber(
+ int number) const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
+};
+
+// Abstract interface for a factory for message objects.
+class LIBPROTOBUF_EXPORT MessageFactory {
+ public:
+ inline MessageFactory() {}
+ virtual ~MessageFactory();
+
+ // Given a Descriptor, gets or constructs the default (prototype) Message
+ // of that type. You can then call that message's New() method to construct
+ // a mutable message of that type.
+ //
+ // Calling this method twice with the same Descriptor returns the same
+ // object. The returned object remains property of the factory. Also, any
+ // objects created by calling the prototype's New() method share some data
+ // with the prototype, so these must be destoyed before the MessageFactory
+ // is destroyed.
+ //
+ // The given descriptor must outlive the returned message, and hence must
+ // outlive the MessageFactory.
+ //
+ // Some implementations do not support all types. GetPrototype() will
+ // return NULL if the descriptor passed in is not supported.
+ //
+ // This method may or may not be thread-safe depending on the implementation.
+ // Each implementation should document its own degree thread-safety.
+ virtual const Message* GetPrototype(const Descriptor* type) = 0;
+
+ // Gets a MessageFactory which supports all generated, compiled-in messages.
+ // In other words, for any compiled-in type FooMessage, the following is true:
+ // MessageFactory::generated_factory()->GetPrototype(
+ // FooMessage::descriptor()) == FooMessage::default_instance()
+ // This factory supports all types which are found in
+ // DescriptorPool::generated_pool(). If given a descriptor from any other
+ // pool, GetPrototype() will return NULL. (You can also check if a
+ // descriptor is for a generated message by checking if
+ // descriptor->file()->pool() == DescriptorPool::generated_pool().)
+ //
+ // This factory is 100% thread-safe; calling GetPrototype() does not modify
+ // any shared data.
+ //
+ // This factory is a singleton. The caller must not delete the object.
+ static MessageFactory* generated_factory();
+
+ // For internal use only: Registers a .proto file at static initialization
+ // time, to be placed in generated_factory. The first time GetPrototype()
+ // is called with a descriptor from this file, |register_messages| will be
+ // called, with the file name as the parameter. It must call
+ // InternalRegisterGeneratedMessage() (below) to register each message type
+ // in the file. This strange mechanism is necessary because descriptors are
+ // built lazily, so we can't register types by their descriptor until we
+ // know that the descriptor exists. |filename| must be a permanent string.
+ static void InternalRegisterGeneratedFile(
+ const char* filename, void (*register_messages)(const string&));
+
+ // For internal use only: Registers a message type. Called only by the
+ // functions which are registered with InternalRegisterGeneratedFile(),
+ // above.
+ static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
+ const Message* prototype);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
+};
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_MESSAGE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/message_lite.cc b/src/third_party/protobuf/src/google/protobuf/message_lite.cc
new file mode 100644
index 0000000..7c8f37d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/message_lite.cc
@@ -0,0 +1,334 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Authors: wink@google.com (Wink Saville),
+// kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/message_lite.h>
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+
+MessageLite::~MessageLite() {}
+
+string MessageLite::InitializationErrorString() const {
+ return "(cannot determine missing fields for lite message)";
+}
+
+namespace {
+
+// When serializing, we first compute the byte size, then serialize the message.
+// If serialization produces a different number of bytes than expected, we
+// call this function, which crashes. The problem could be due to a bug in the
+// protobuf implementation but is more likely caused by concurrent modification
+// of the message. This function attempts to distinguish between the two and
+// provide a useful error message.
+void ByteSizeConsistencyError(int byte_size_before_serialization,
+ int byte_size_after_serialization,
+ int bytes_produced_by_serialization) {
+ GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization)
+ << "Protocol message was modified concurrently during serialization.";
+ GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization)
+ << "Byte size calculation and serialization were inconsistent. This "
+ "may indicate a bug in protocol buffers or it may be caused by "
+ "concurrent modification of the message.";
+ GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal.";
+}
+
+string InitializationErrorMessage(const char* action,
+ const MessageLite& message) {
+ // Note: We want to avoid depending on strutil in the lite library, otherwise
+ // we'd use:
+ //
+ // return strings::Substitute(
+ // "Can't $0 message of type \"$1\" because it is missing required "
+ // "fields: $2",
+ // action, message.GetTypeName(),
+ // message.InitializationErrorString());
+
+ string result;
+ result += "Can't ";
+ result += action;
+ result += " message of type \"";
+ result += message.GetTypeName();
+ result += "\" because it is missing required fields: ";
+ result += message.InitializationErrorString();
+ return result;
+}
+
+// Several of the Parse methods below just do one thing and then call another
+// method. In a naive implementation, we might have ParseFromString() call
+// ParseFromArray() which would call ParseFromZeroCopyStream() which would call
+// ParseFromCodedStream() which would call MergeFromCodedStream() which would
+// call MergePartialFromCodedStream(). However, when parsing very small
+// messages, every function call introduces significant overhead. To avoid
+// this without reproducing code, we use these forced-inline helpers.
+//
+// Note: GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not
+// definitions.
+inline bool InlineMergeFromCodedStream(io::CodedInputStream* input,
+ MessageLite* message)
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
+ MessageLite* message)
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
+ MessageLite* message)
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline bool InlineParseFromArray(const void* data, int size,
+ MessageLite* message)
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline bool InlineParsePartialFromArray(const void* data, int size,
+ MessageLite* message)
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+bool InlineMergeFromCodedStream(io::CodedInputStream* input,
+ MessageLite* message) {
+ if (!message->MergePartialFromCodedStream(input)) return false;
+ if (!message->IsInitialized()) {
+ GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
+ return false;
+ }
+ return true;
+}
+
+bool InlineParseFromCodedStream(io::CodedInputStream* input,
+ MessageLite* message) {
+ message->Clear();
+ return InlineMergeFromCodedStream(input, message);
+}
+
+bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
+ MessageLite* message) {
+ message->Clear();
+ return message->MergePartialFromCodedStream(input);
+}
+
+bool InlineParseFromArray(const void* data, int size, MessageLite* message) {
+ io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
+ return InlineParseFromCodedStream(&input, message) &&
+ input.ConsumedEntireMessage();
+}
+
+bool InlineParsePartialFromArray(const void* data, int size,
+ MessageLite* message) {
+ io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
+ return InlineParsePartialFromCodedStream(&input, message) &&
+ input.ConsumedEntireMessage();
+}
+
+} // namespace
+
+bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
+ return InlineMergeFromCodedStream(input, this);
+}
+
+bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) {
+ return InlineParseFromCodedStream(input, this);
+}
+
+bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) {
+ return InlineParsePartialFromCodedStream(input, this);
+}
+
+bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
+ io::CodedInputStream decoder(input);
+ return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage();
+}
+
+bool MessageLite::ParsePartialFromZeroCopyStream(
+ io::ZeroCopyInputStream* input) {
+ io::CodedInputStream decoder(input);
+ return ParsePartialFromCodedStream(&decoder) &&
+ decoder.ConsumedEntireMessage();
+}
+
+bool MessageLite::ParseFromBoundedZeroCopyStream(
+ io::ZeroCopyInputStream* input, int size) {
+ io::CodedInputStream decoder(input);
+ decoder.PushLimit(size);
+ return ParseFromCodedStream(&decoder) &&
+ decoder.ConsumedEntireMessage() &&
+ decoder.BytesUntilLimit() == 0;
+}
+
+bool MessageLite::ParsePartialFromBoundedZeroCopyStream(
+ io::ZeroCopyInputStream* input, int size) {
+ io::CodedInputStream decoder(input);
+ decoder.PushLimit(size);
+ return ParsePartialFromCodedStream(&decoder) &&
+ decoder.ConsumedEntireMessage() &&
+ decoder.BytesUntilLimit() == 0;
+}
+
+bool MessageLite::ParseFromString(const string& data) {
+ return InlineParseFromArray(data.data(), data.size(), this);
+}
+
+bool MessageLite::ParsePartialFromString(const string& data) {
+ return InlineParsePartialFromArray(data.data(), data.size(), this);
+}
+
+bool MessageLite::ParseFromArray(const void* data, int size) {
+ return InlineParseFromArray(data, size, this);
+}
+
+bool MessageLite::ParsePartialFromArray(const void* data, int size) {
+ return InlineParsePartialFromArray(data, size, this);
+}
+
+
+// ===================================================================
+
+uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
+ // We only optimize this when using optimize_for = SPEED. In other cases
+ // we just use the CodedOutputStream path.
+ int size = GetCachedSize();
+ io::ArrayOutputStream out(target, size);
+ io::CodedOutputStream coded_out(&out);
+ SerializeWithCachedSizes(&coded_out);
+ GOOGLE_CHECK(!coded_out.HadError());
+ return target + size;
+}
+
+bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const {
+ GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+ return SerializePartialToCodedStream(output);
+}
+
+bool MessageLite::SerializePartialToCodedStream(
+ io::CodedOutputStream* output) const {
+ const int size = ByteSize(); // Force size to be cached.
+ uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size);
+ if (buffer != NULL) {
+ uint8* end = SerializeWithCachedSizesToArray(buffer);
+ if (end - buffer != size) {
+ ByteSizeConsistencyError(size, ByteSize(), end - buffer);
+ }
+ return true;
+ } else {
+ int original_byte_count = output->ByteCount();
+ SerializeWithCachedSizes(output);
+ if (output->HadError()) {
+ return false;
+ }
+ int final_byte_count = output->ByteCount();
+
+ if (final_byte_count - original_byte_count != size) {
+ ByteSizeConsistencyError(size, ByteSize(),
+ final_byte_count - original_byte_count);
+ }
+
+ return true;
+ }
+}
+
+bool MessageLite::SerializeToZeroCopyStream(
+ io::ZeroCopyOutputStream* output) const {
+ io::CodedOutputStream encoder(output);
+ return SerializeToCodedStream(&encoder);
+}
+
+bool MessageLite::SerializePartialToZeroCopyStream(
+ io::ZeroCopyOutputStream* output) const {
+ io::CodedOutputStream encoder(output);
+ return SerializePartialToCodedStream(&encoder);
+}
+
+bool MessageLite::AppendToString(string* output) const {
+ GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+ return AppendPartialToString(output);
+}
+
+bool MessageLite::AppendPartialToString(string* output) const {
+ int old_size = output->size();
+ int byte_size = ByteSize();
+ STLStringResizeUninitialized(output, old_size + byte_size);
+ uint8* start = reinterpret_cast<uint8*>(string_as_array(output) + old_size);
+ uint8* end = SerializeWithCachedSizesToArray(start);
+ if (end - start != byte_size) {
+ ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
+ }
+ return true;
+}
+
+bool MessageLite::SerializeToString(string* output) const {
+ output->clear();
+ return AppendToString(output);
+}
+
+bool MessageLite::SerializePartialToString(string* output) const {
+ output->clear();
+ return AppendPartialToString(output);
+}
+
+bool MessageLite::SerializeToArray(void* data, int size) const {
+ GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+ return SerializePartialToArray(data, size);
+}
+
+bool MessageLite::SerializePartialToArray(void* data, int size) const {
+ int byte_size = ByteSize();
+ if (size < byte_size) return false;
+ uint8* start = reinterpret_cast<uint8*>(data);
+ uint8* end = SerializeWithCachedSizesToArray(start);
+ if (end - start != byte_size) {
+ ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
+ }
+ return true;
+}
+
+string MessageLite::SerializeAsString() const {
+ // If the compiler implements the (Named) Return Value Optimization,
+ // the local variable 'result' will not actually reside on the stack
+ // of this function, but will be overlaid with the object that the
+ // caller supplied for the return value to be constructed in.
+ string output;
+ if (!AppendToString(&output))
+ output.clear();
+ return output;
+}
+
+string MessageLite::SerializePartialAsString() const {
+ string output;
+ if (!AppendPartialToString(&output))
+ output.clear();
+ return output;
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/message_lite.h b/src/third_party/protobuf/src/google/protobuf/message_lite.h
new file mode 100644
index 0000000..ebf4ba3
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/message_lite.h
@@ -0,0 +1,239 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Authors: wink@google.com (Wink Saville),
+// kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines MessageLite, the abstract interface implemented by all (lite
+// and non-lite) protocol message objects.
+
+#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__
+#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+
+namespace google {
+namespace protobuf {
+
+// Interface to light weight protocol messages.
+//
+// This interface is implemented by all protocol message objects. Non-lite
+// messages additionally implement the Message interface, which is a
+// subclass of MessageLite. Use MessageLite instead when you only need
+// the subset of features which it supports -- namely, nothing that uses
+// descriptors or reflection. You can instruct the protocol compiler
+// to generate classes which implement only MessageLite, not the full
+// Message interface, by adding the following line to the .proto file:
+//
+// option optimize_for = LITE_RUNTIME;
+//
+// This is particularly useful on resource-constrained systems where
+// the full protocol buffers runtime library is too big.
+//
+// Note that on non-constrained systems (e.g. servers) when you need
+// to link in lots of protocol definitions, a better way to reduce
+// total code footprint is to use optimize_for = CODE_SIZE. This
+// will make the generated code smaller while still supporting all the
+// same features (at the expense of speed). optimize_for = LITE_RUNTIME
+// is best when you only have a small number of message types linked
+// into your binary, in which case the size of the protocol buffers
+// runtime itself is the biggest problem.
+class LIBPROTOBUF_EXPORT MessageLite {
+ public:
+ inline MessageLite() {}
+ virtual ~MessageLite();
+
+ // Basic Operations ------------------------------------------------
+
+ // Get the name of this message type, e.g. "foo.bar.BazProto".
+ virtual string GetTypeName() const = 0;
+
+ // Construct a new instance of the same type. Ownership is passed to the
+ // caller.
+ virtual MessageLite* New() const = 0;
+
+ // Clear all fields of the message and set them to their default values.
+ // Clear() avoids freeing memory, assuming that any memory allocated
+ // to hold parts of the message will be needed again to hold the next
+ // message. If you actually want to free the memory used by a Message,
+ // you must delete it.
+ virtual void Clear() = 0;
+
+ // Quickly check if all required fields have values set.
+ virtual bool IsInitialized() const = 0;
+
+ // This is not implemented for Lite messages -- it just returns "(cannot
+ // determine missing fields for lite message)". However, it is implemented
+ // for full messages. See message.h.
+ virtual string InitializationErrorString() const;
+
+ // If |other| is the exact same class as this, calls MergeFrom(). Otherwise,
+ // results are undefined (probably crash).
+ virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0;
+
+ // Parsing ---------------------------------------------------------
+ // Methods for parsing in protocol buffer format. Most of these are
+ // just simple wrappers around MergeFromCodedStream().
+
+ // Fill the message with a protocol buffer parsed from the given input
+ // stream. Returns false on a read error or if the input is in the
+ // wrong format.
+ bool ParseFromCodedStream(io::CodedInputStream* input);
+ // Like ParseFromCodedStream(), but accepts messages that are missing
+ // required fields.
+ bool ParsePartialFromCodedStream(io::CodedInputStream* input);
+ // Read a protocol buffer from the given zero-copy input stream. If
+ // successful, the entire input will be consumed.
+ bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
+ // Like ParseFromZeroCopyStream(), but accepts messages that are missing
+ // required fields.
+ bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input);
+ // Read a protocol buffer from the given zero-copy input stream, expecting
+ // the message to be exactly "size" bytes long. If successful, exactly
+ // this many bytes will have been consumed from the input.
+ bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size);
+ // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are
+ // missing required fields.
+ bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
+ int size);
+ // Parse a protocol buffer contained in a string.
+ bool ParseFromString(const string& data);
+ // Like ParseFromString(), but accepts messages that are missing
+ // required fields.
+ bool ParsePartialFromString(const string& data);
+ // Parse a protocol buffer contained in an array of bytes.
+ bool ParseFromArray(const void* data, int size);
+ // Like ParseFromArray(), but accepts messages that are missing
+ // required fields.
+ bool ParsePartialFromArray(const void* data, int size);
+
+
+ // Reads a protocol buffer from the stream and merges it into this
+ // Message. Singular fields read from the input overwrite what is
+ // already in the Message and repeated fields are appended to those
+ // already present.
+ //
+ // It is the responsibility of the caller to call input->LastTagWas()
+ // (for groups) or input->ConsumedEntireMessage() (for non-groups) after
+ // this returns to verify that the message's end was delimited correctly.
+ //
+ // ParsefromCodedStream() is implemented as Clear() followed by
+ // MergeFromCodedStream().
+ bool MergeFromCodedStream(io::CodedInputStream* input);
+
+ // Like MergeFromCodedStream(), but succeeds even if required fields are
+ // missing in the input.
+ //
+ // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream()
+ // followed by IsInitialized().
+ virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0;
+
+ // Serialization ---------------------------------------------------
+ // Methods for serializing in protocol buffer format. Most of these
+ // are just simple wrappers around ByteSize() and SerializeWithCachedSizes().
+
+ // Write a protocol buffer of this message to the given output. Returns
+ // false on a write error. If the message is missing required fields,
+ // this may GOOGLE_CHECK-fail.
+ bool SerializeToCodedStream(io::CodedOutputStream* output) const;
+ // Like SerializeToCodedStream(), but allows missing required fields.
+ bool SerializePartialToCodedStream(io::CodedOutputStream* output) const;
+ // Write the message to the given zero-copy output stream. All required
+ // fields must be set.
+ bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
+ // Like SerializeToZeroCopyStream(), but allows missing required fields.
+ bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
+ // Serialize the message and store it in the given string. All required
+ // fields must be set.
+ bool SerializeToString(string* output) const;
+ // Like SerializeToString(), but allows missing required fields.
+ bool SerializePartialToString(string* output) const;
+ // Serialize the message and store it in the given byte array. All required
+ // fields must be set.
+ bool SerializeToArray(void* data, int size) const;
+ // Like SerializeToArray(), but allows missing required fields.
+ bool SerializePartialToArray(void* data, int size) const;
+
+ // Make a string encoding the message. Is equivalent to calling
+ // SerializeToString() on a string and using that. Returns the empty
+ // string if SerializeToString() would have returned an error.
+ // Note: If you intend to generate many such strings, you may
+ // reduce heap fragmentation by instead re-using the same string
+ // object with calls to SerializeToString().
+ string SerializeAsString() const;
+ // Like SerializeAsString(), but allows missing required fields.
+ string SerializePartialAsString() const;
+
+ // Like SerializeToString(), but appends to the data to the string's existing
+ // contents. All required fields must be set.
+ bool AppendToString(string* output) const;
+ // Like AppendToString(), but allows missing required fields.
+ bool AppendPartialToString(string* output) const;
+
+ // Computes the serialized size of the message. This recursively calls
+ // ByteSize() on all embedded messages. If a subclass does not override
+ // this, it MUST override SetCachedSize().
+ virtual int ByteSize() const = 0;
+
+ // Serializes the message without recomputing the size. The message must
+ // not have changed since the last call to ByteSize(); if it has, the results
+ // are undefined.
+ virtual void SerializeWithCachedSizes(
+ io::CodedOutputStream* output) const = 0;
+
+ // Like SerializeWithCachedSizes, but writes directly to *target, returning
+ // a pointer to the byte immediately after the last byte written. "target"
+ // must point at a byte array of at least ByteSize() bytes.
+ virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const;
+
+ // Returns the result of the last call to ByteSize(). An embedded message's
+ // size is needed both to serialize it (because embedded messages are
+ // length-delimited) and to compute the outer message's size. Caching
+ // the size avoids computing it multiple times.
+ //
+ // ByteSize() does not automatically use the cached size when available
+ // because this would require invalidating it every time the message was
+ // modified, which would be too hard and expensive. (E.g. if a deeply-nested
+ // sub-message is changed, all of its parents' cached sizes would need to be
+ // invalidated, which is too much work for an otherwise inlined setter
+ // method.)
+ virtual int GetCachedSize() const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite);
+};
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/message_unittest.cc b/src/third_party/protobuf/src/google/protobuf/message_unittest.cc
new file mode 100644
index 0000000..33b9e77
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/message_unittest.cc
@@ -0,0 +1,281 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/message.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <sstream>
+#include <fstream>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+TEST(MessageTest, SerializeHelpers) {
+ // TODO(kenton): Test more helpers? They're all two-liners so it seems
+ // like a waste of time.
+
+ protobuf_unittest::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+ stringstream stream;
+
+ string str1("foo");
+ string str2("bar");
+
+ EXPECT_TRUE(message.SerializeToString(&str1));
+ EXPECT_TRUE(message.AppendToString(&str2));
+ EXPECT_TRUE(message.SerializeToOstream(&stream));
+
+ EXPECT_EQ(str1.size() + 3, str2.size());
+ EXPECT_EQ("bar", str2.substr(0, 3));
+ // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+ // stdout.
+ EXPECT_TRUE(str2.substr(3) == str1);
+
+ // GCC gives some sort of error if we try to just do stream.str() == str1.
+ string temp = stream.str();
+ EXPECT_TRUE(temp == str1);
+
+ EXPECT_TRUE(message.SerializeAsString() == str1);
+
+}
+
+TEST(MessageTest, SerializeToBrokenOstream) {
+ ofstream out;
+ protobuf_unittest::TestAllTypes message;
+ message.set_optional_int32(123);
+
+ EXPECT_FALSE(message.SerializeToOstream(&out));
+}
+
+TEST(MessageTest, ParseFromFileDescriptor) {
+ string filename = TestSourceDir() +
+ "/google/protobuf/testdata/golden_message";
+ int file = open(filename.c_str(), O_RDONLY | O_BINARY);
+
+ unittest::TestAllTypes message;
+ EXPECT_TRUE(message.ParseFromFileDescriptor(file));
+ TestUtil::ExpectAllFieldsSet(message);
+
+ EXPECT_GE(close(file), 0);
+}
+
+TEST(MessageTest, ParsePackedFromFileDescriptor) {
+ string filename =
+ TestSourceDir() +
+ "/google/protobuf/testdata/golden_packed_fields_message";
+ int file = open(filename.c_str(), O_RDONLY | O_BINARY);
+
+ unittest::TestPackedTypes message;
+ EXPECT_TRUE(message.ParseFromFileDescriptor(file));
+ TestUtil::ExpectPackedFieldsSet(message);
+
+ EXPECT_GE(close(file), 0);
+}
+
+TEST(MessageTest, ParseHelpers) {
+ // TODO(kenton): Test more helpers? They're all two-liners so it seems
+ // like a waste of time.
+ string data;
+
+ {
+ // Set up.
+ protobuf_unittest::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+ message.SerializeToString(&data);
+ }
+
+ {
+ // Test ParseFromString.
+ protobuf_unittest::TestAllTypes message;
+ EXPECT_TRUE(message.ParseFromString(data));
+ TestUtil::ExpectAllFieldsSet(message);
+ }
+
+ {
+ // Test ParseFromIstream.
+ protobuf_unittest::TestAllTypes message;
+ stringstream stream(data);
+ EXPECT_TRUE(message.ParseFromIstream(&stream));
+ EXPECT_TRUE(stream.eof());
+ TestUtil::ExpectAllFieldsSet(message);
+ }
+
+ {
+ // Test ParseFromBoundedZeroCopyStream.
+ string data_with_junk(data);
+ data_with_junk.append("some junk on the end");
+ io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
+ protobuf_unittest::TestAllTypes message;
+ EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
+ TestUtil::ExpectAllFieldsSet(message);
+ }
+
+ {
+ // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
+ // EOF is reached before the expected number of bytes.
+ io::ArrayInputStream stream(data.data(), data.size());
+ protobuf_unittest::TestAllTypes message;
+ EXPECT_FALSE(
+ message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
+ }
+}
+
+TEST(MessageTest, ParseFailsIfNotInitialized) {
+ unittest::TestRequired message;
+ vector<string> errors;
+
+ {
+ ScopedMemoryLog log;
+ EXPECT_FALSE(message.ParseFromString(""));
+ errors = log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(1, errors.size());
+ EXPECT_EQ("Can't parse message of type \"protobuf_unittest.TestRequired\" "
+ "because it is missing required fields: a, b, c",
+ errors[0]);
+}
+
+TEST(MessageTest, BypassInitializationCheckOnParse) {
+ unittest::TestRequired message;
+ io::ArrayInputStream raw_input(NULL, 0);
+ io::CodedInputStream input(&raw_input);
+ EXPECT_TRUE(message.MergePartialFromCodedStream(&input));
+}
+
+TEST(MessageTest, InitializationErrorString) {
+ unittest::TestRequired message;
+ EXPECT_EQ("a, b, c", message.InitializationErrorString());
+}
+
+#ifdef GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet.
+
+TEST(MessageTest, SerializeFailsIfNotInitialized) {
+ unittest::TestRequired message;
+ string data;
+ EXPECT_DEBUG_DEATH(EXPECT_TRUE(message.SerializeToString(&data)),
+ "Can't serialize message of type \"protobuf_unittest.TestRequired\" because "
+ "it is missing required fields: a, b, c");
+}
+
+TEST(MessageTest, CheckInitialized) {
+ unittest::TestRequired message;
+ EXPECT_DEATH(message.CheckInitialized(),
+ "Message of type \"protobuf_unittest.TestRequired\" is missing required "
+ "fields: a, b, c");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+TEST(MessageTest, BypassInitializationCheckOnSerialize) {
+ unittest::TestRequired message;
+ io::ArrayOutputStream raw_output(NULL, 0);
+ io::CodedOutputStream output(&raw_output);
+ EXPECT_TRUE(message.SerializePartialToCodedStream(&output));
+}
+
+TEST(MessageTest, FindInitializationErrors) {
+ unittest::TestRequired message;
+ vector<string> errors;
+ message.FindInitializationErrors(&errors);
+ ASSERT_EQ(3, errors.size());
+ EXPECT_EQ("a", errors[0]);
+ EXPECT_EQ("b", errors[1]);
+ EXPECT_EQ("c", errors[2]);
+}
+
+TEST(MessageTest, ParseFailsOnInvalidMessageEnd) {
+ unittest::TestAllTypes message;
+
+ // Control case.
+ EXPECT_TRUE(message.ParseFromArray("", 0));
+
+ // The byte is a valid varint, but not a valid tag (zero).
+ EXPECT_FALSE(message.ParseFromArray("\0", 1));
+
+ // The byte is a malformed varint.
+ EXPECT_FALSE(message.ParseFromArray("\200", 1));
+
+ // The byte is an endgroup tag, but we aren't parsing a group.
+ EXPECT_FALSE(message.ParseFromArray("\014", 1));
+}
+
+TEST(MessageFactoryTest, GeneratedFactoryLookup) {
+ EXPECT_EQ(
+ MessageFactory::generated_factory()->GetPrototype(
+ protobuf_unittest::TestAllTypes::descriptor()),
+ &protobuf_unittest::TestAllTypes::default_instance());
+}
+
+TEST(MessageFactoryTest, GeneratedFactoryUnknownType) {
+ // Construct a new descriptor.
+ DescriptorPool pool;
+ FileDescriptorProto file;
+ file.set_name("foo.proto");
+ file.add_message_type()->set_name("Foo");
+ const Descriptor* descriptor = pool.BuildFile(file)->message_type(0);
+
+ // Trying to construct it should return NULL.
+ EXPECT_TRUE(
+ MessageFactory::generated_factory()->GetPrototype(descriptor) == NULL);
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/package_info.h b/src/third_party/protobuf/src/google/protobuf/package_info.h
new file mode 100644
index 0000000..60cd399
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/package_info.h
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file exists solely to document the google::protobuf namespace.
+// It is not compiled into anything, but it may be read by an automated
+// documentation generator.
+
+namespace google {
+
+// Core components of the Protocol Buffers runtime library.
+//
+// The files in this package represent the core of the Protocol Buffer
+// system. All of them are part of the libprotobuf library.
+//
+// A note on thread-safety:
+//
+// Thread-safety in the Protocol Buffer library follows a simple rule:
+// unless explicitly noted otherwise, it is always safe to use an object
+// from multiple threads simultaneously as long as the object is declared
+// const in all threads (or, it is only used in ways that would be allowed
+// if it were declared const). However, if an object is accessed in one
+// thread in a way that would not be allowed if it were const, then it is
+// not safe to access that object in any other thread simultaneously.
+//
+// Put simply, read-only access to an object can happen in multiple threads
+// simultaneously, but write access can only happen in a single thread at
+// a time.
+//
+// The implementation does contain some "const" methods which actually modify
+// the object behind the scenes -- e.g., to cache results -- but in these cases
+// mutex locking is used to make the access thread-safe.
+namespace protobuf {}
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/reflection_ops.cc b/src/third_party/protobuf/src/google/protobuf/reflection_ops.cc
new file mode 100644
index 0000000..897c0d7
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/reflection_ops.cc
@@ -0,0 +1,262 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+void ReflectionOps::Copy(const Message& from, Message* to) {
+ if (&from == to) return;
+ Clear(to);
+ Merge(from, to);
+}
+
+void ReflectionOps::Merge(const Message& from, Message* to) {
+ GOOGLE_CHECK_NE(&from, to);
+
+ const Descriptor* descriptor = from.GetDescriptor();
+ GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
+ << "Tried to merge messages of different types.";
+
+ const Reflection* from_reflection = from.GetReflection();
+ const Reflection* to_reflection = to->GetReflection();
+
+ vector<const FieldDescriptor*> fields;
+ from_reflection->ListFields(from, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+
+ if (field->is_repeated()) {
+ int count = from_reflection->FieldSize(from, field);
+ for (int j = 0; j < count; j++) {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, METHOD) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ to_reflection->Add##METHOD(to, field, \
+ from_reflection->GetRepeated##METHOD(from, field, j)); \
+ break;
+
+ HANDLE_TYPE(INT32 , Int32 );
+ HANDLE_TYPE(INT64 , Int64 );
+ HANDLE_TYPE(UINT32, UInt32);
+ HANDLE_TYPE(UINT64, UInt64);
+ HANDLE_TYPE(FLOAT , Float );
+ HANDLE_TYPE(DOUBLE, Double);
+ HANDLE_TYPE(BOOL , Bool );
+ HANDLE_TYPE(STRING, String);
+ HANDLE_TYPE(ENUM , Enum );
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ to_reflection->AddMessage(to, field)->MergeFrom(
+ from_reflection->GetRepeatedMessage(from, field, j));
+ break;
+ }
+ }
+ } else {
+ switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, METHOD) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ to_reflection->Set##METHOD(to, field, \
+ from_reflection->Get##METHOD(from, field)); \
+ break;
+
+ HANDLE_TYPE(INT32 , Int32 );
+ HANDLE_TYPE(INT64 , Int64 );
+ HANDLE_TYPE(UINT32, UInt32);
+ HANDLE_TYPE(UINT64, UInt64);
+ HANDLE_TYPE(FLOAT , Float );
+ HANDLE_TYPE(DOUBLE, Double);
+ HANDLE_TYPE(BOOL , Bool );
+ HANDLE_TYPE(STRING, String);
+ HANDLE_TYPE(ENUM , Enum );
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ to_reflection->MutableMessage(to, field)->MergeFrom(
+ from_reflection->GetMessage(from, field));
+ break;
+ }
+ }
+ }
+
+ to_reflection->MutableUnknownFields(to)->MergeFrom(
+ from_reflection->GetUnknownFields(from));
+}
+
+void ReflectionOps::Clear(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(*message, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ reflection->ClearField(message, fields[i]);
+ }
+
+ reflection->MutableUnknownFields(message)->Clear();
+}
+
+bool ReflectionOps::IsInitialized(const Message& message) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* reflection = message.GetReflection();
+
+ // Check required fields of this message.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ if (descriptor->field(i)->is_required()) {
+ if (!reflection->HasField(message, descriptor->field(i))) {
+ return false;
+ }
+ }
+ }
+
+ // Check that sub-messages are initialized.
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (field->is_repeated()) {
+ int size = reflection->FieldSize(message, field);
+
+ for (int i = 0; i < size; i++) {
+ if (!reflection->GetRepeatedMessage(message, field, i)
+ .IsInitialized()) {
+ return false;
+ }
+ }
+ } else {
+ if (!reflection->GetMessage(message, field).IsInitialized()) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void ReflectionOps::DiscardUnknownFields(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ reflection->MutableUnknownFields(message)->Clear();
+
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(*message, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (field->is_repeated()) {
+ int size = reflection->FieldSize(*message, field);
+ for (int i = 0; i < size; i++) {
+ reflection->MutableRepeatedMessage(message, field, i)
+ ->DiscardUnknownFields();
+ }
+ } else {
+ reflection->MutableMessage(message, field)->DiscardUnknownFields();
+ }
+ }
+ }
+}
+
+static string SubMessagePrefix(const string& prefix,
+ const FieldDescriptor* field,
+ int index) {
+ string result(prefix);
+ if (field->is_extension()) {
+ result.append("(");
+ result.append(field->full_name());
+ result.append(")");
+ } else {
+ result.append(field->name());
+ }
+ if (index != -1) {
+ result.append("[");
+ result.append(SimpleItoa(index));
+ result.append("]");
+ }
+ result.append(".");
+ return result;
+}
+
+void ReflectionOps::FindInitializationErrors(
+ const Message& message,
+ const string& prefix,
+ vector<string>* errors) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* reflection = message.GetReflection();
+
+ // Check required fields of this message.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ if (descriptor->field(i)->is_required()) {
+ if (!reflection->HasField(message, descriptor->field(i))) {
+ errors->push_back(prefix + descriptor->field(i)->name());
+ }
+ }
+ }
+
+ // Check sub-messages.
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ const FieldDescriptor* field = fields[i];
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+
+ if (field->is_repeated()) {
+ int size = reflection->FieldSize(message, field);
+
+ for (int i = 0; i < size; i++) {
+ const Message& sub_message =
+ reflection->GetRepeatedMessage(message, field, i);
+ FindInitializationErrors(sub_message,
+ SubMessagePrefix(prefix, field, i),
+ errors);
+ }
+ } else {
+ const Message& sub_message = reflection->GetMessage(message, field);
+ FindInitializationErrors(sub_message,
+ SubMessagePrefix(prefix, field, -1),
+ errors);
+ }
+ }
+ }
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/reflection_ops.h b/src/third_party/protobuf/src/google/protobuf/reflection_ops.h
new file mode 100644
index 0000000..355a0a5
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/reflection_ops.h
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_REFLECTION_OPS_H__
+#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__
+
+#include <google/protobuf/message.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Basic operations that can be performed using reflection.
+// These can be used as a cheap way to implement the corresponding
+// methods of the Message interface, though they are likely to be
+// slower than implementations tailored for the specific message type.
+//
+// This class should stay limited to operations needed to implement
+// the Message interface.
+//
+// This class is really a namespace that contains only static methods.
+class LIBPROTOBUF_EXPORT ReflectionOps {
+ public:
+ static void Copy(const Message& from, Message* to);
+ static void Merge(const Message& from, Message* to);
+ static void Clear(Message* message);
+ static bool IsInitialized(const Message& message);
+ static void DiscardUnknownFields(Message* message);
+
+ // Finds all unset required fields in the message and adds their full
+ // paths (e.g. "foo.bar[5].baz") to *names. "prefix" will be attached to
+ // the front of each name.
+ static void FindInitializationErrors(const Message& message,
+ const string& prefix,
+ vector<string>* errors);
+
+ private:
+ // All methods are static. No need to construct.
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps);
+};
+
+} // namespace internal
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/reflection_ops_unittest.cc b/src/third_party/protobuf/src/google/protobuf/reflection_ops_unittest.cc
new file mode 100644
index 0000000..1cd56f1
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/reflection_ops_unittest.cc
@@ -0,0 +1,405 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(ReflectionOpsTest, SanityCheck) {
+ unittest::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(ReflectionOpsTest, Copy) {
+ unittest::TestAllTypes message, message2;
+
+ TestUtil::SetAllFields(&message);
+
+ ReflectionOps::Copy(message, &message2);
+
+ TestUtil::ExpectAllFieldsSet(message2);
+
+ // Copying from self should be a no-op.
+ ReflectionOps::Copy(message2, &message2);
+ TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(ReflectionOpsTest, CopyExtensions) {
+ unittest::TestAllExtensions message, message2;
+
+ TestUtil::SetAllExtensions(&message);
+
+ ReflectionOps::Copy(message, &message2);
+
+ TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ReflectionOpsTest, Merge) {
+ // Note: Copy is implemented in terms of Merge() so technically the Copy
+ // test already tested most of this.
+
+ unittest::TestAllTypes message, message2;
+
+ TestUtil::SetAllFields(&message);
+
+ // This field will test merging into an empty spot.
+ message2.set_optional_int32(message.optional_int32());
+ message.clear_optional_int32();
+
+ // This tests overwriting.
+ message2.set_optional_string(message.optional_string());
+ message.set_optional_string("something else");
+
+ // This tests concatenating.
+ message2.add_repeated_int32(message.repeated_int32(1));
+ int32 i = message.repeated_int32(0);
+ message.clear_repeated_int32();
+ message.add_repeated_int32(i);
+
+ ReflectionOps::Merge(message2, &message);
+
+ TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(ReflectionOpsTest, MergeExtensions) {
+ // Note: Copy is implemented in terms of Merge() so technically the Copy
+ // test already tested most of this.
+
+ unittest::TestAllExtensions message, message2;
+
+ TestUtil::SetAllExtensions(&message);
+
+ // This field will test merging into an empty spot.
+ message2.SetExtension(unittest::optional_int32_extension,
+ message.GetExtension(unittest::optional_int32_extension));
+ message.ClearExtension(unittest::optional_int32_extension);
+
+ // This tests overwriting.
+ message2.SetExtension(unittest::optional_string_extension,
+ message.GetExtension(unittest::optional_string_extension));
+ message.SetExtension(unittest::optional_string_extension, "something else");
+
+ // This tests concatenating.
+ message2.AddExtension(unittest::repeated_int32_extension,
+ message.GetExtension(unittest::repeated_int32_extension, 1));
+ int32 i = message.GetExtension(unittest::repeated_int32_extension, 0);
+ message.ClearExtension(unittest::repeated_int32_extension);
+ message.AddExtension(unittest::repeated_int32_extension, i);
+
+ ReflectionOps::Merge(message2, &message);
+
+ TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ReflectionOpsTest, MergeUnknown) {
+ // Test that the messages' UnknownFieldSets are correctly merged.
+ unittest::TestEmptyMessage message1, message2;
+ message1.mutable_unknown_fields()->AddVarint(1234, 1);
+ message2.mutable_unknown_fields()->AddVarint(1234, 2);
+
+ ReflectionOps::Merge(message2, &message1);
+
+ ASSERT_EQ(2, message1.unknown_fields().field_count());
+ ASSERT_EQ(UnknownField::TYPE_VARINT,
+ message1.unknown_fields().field(0).type());
+ EXPECT_EQ(1, message1.unknown_fields().field(0).varint());
+ ASSERT_EQ(UnknownField::TYPE_VARINT,
+ message1.unknown_fields().field(1).type());
+ EXPECT_EQ(2, message1.unknown_fields().field(1).varint());
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST(ReflectionOpsTest, MergeFromSelf) {
+ // Note: Copy is implemented in terms of Merge() so technically the Copy
+ // test already tested most of this.
+
+ unittest::TestAllTypes message;
+
+ EXPECT_DEATH(
+ ReflectionOps::Merge(message, &message),
+ "&from");
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+TEST(ReflectionOpsTest, Clear) {
+ unittest::TestAllTypes message;
+
+ TestUtil::SetAllFields(&message);
+
+ ReflectionOps::Clear(&message);
+
+ TestUtil::ExpectClear(message);
+
+ // Check that getting embedded messages returns the objects created during
+ // SetAllFields() rather than default instances.
+ EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+ &message.optionalgroup());
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.optional_nested_message());
+ EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+ &message.optional_foreign_message());
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &message.optional_import_message());
+}
+
+TEST(ReflectionOpsTest, ClearExtensions) {
+ unittest::TestAllExtensions message;
+
+ TestUtil::SetAllExtensions(&message);
+
+ ReflectionOps::Clear(&message);
+
+ TestUtil::ExpectExtensionsClear(message);
+
+ // Check that getting embedded messages returns the objects created during
+ // SetAllExtensions() rather than default instances.
+ EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
+ &message.GetExtension(unittest::optionalgroup_extension));
+ EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+ &message.GetExtension(unittest::optional_nested_message_extension));
+ EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+ &message.GetExtension(
+ unittest::optional_foreign_message_extension));
+ EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+ &message.GetExtension(unittest::optional_import_message_extension));
+}
+
+TEST(ReflectionOpsTest, ClearUnknown) {
+ // Test that the message's UnknownFieldSet is correctly cleared.
+ unittest::TestEmptyMessage message;
+ message.mutable_unknown_fields()->AddVarint(1234, 1);
+
+ ReflectionOps::Clear(&message);
+
+ EXPECT_EQ(0, message.unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, DiscardUnknownFields) {
+ unittest::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+
+ // Set some unknown fields in message.
+ message.mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+ message.mutable_optional_nested_message()
+ ->mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+ message.mutable_repeated_nested_message(0)
+ ->mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+
+ EXPECT_EQ(1, message.unknown_fields().field_count());
+ EXPECT_EQ(1, message.optional_nested_message()
+ .unknown_fields().field_count());
+ EXPECT_EQ(1, message.repeated_nested_message(0)
+ .unknown_fields().field_count());
+
+ // Discard them.
+ ReflectionOps::DiscardUnknownFields(&message);
+ TestUtil::ExpectAllFieldsSet(message);
+
+ EXPECT_EQ(0, message.unknown_fields().field_count());
+ EXPECT_EQ(0, message.optional_nested_message()
+ .unknown_fields().field_count());
+ EXPECT_EQ(0, message.repeated_nested_message(0)
+ .unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, DiscardUnknownExtensions) {
+ unittest::TestAllExtensions message;
+ TestUtil::SetAllExtensions(&message);
+
+ // Set some unknown fields.
+ message.mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+ message.MutableExtension(unittest::optional_nested_message_extension)
+ ->mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+ message.MutableExtension(unittest::repeated_nested_message_extension, 0)
+ ->mutable_unknown_fields()
+ ->AddVarint(123456, 654321);
+
+ EXPECT_EQ(1, message.unknown_fields().field_count());
+ EXPECT_EQ(1,
+ message.GetExtension(unittest::optional_nested_message_extension)
+ .unknown_fields().field_count());
+ EXPECT_EQ(1,
+ message.GetExtension(unittest::repeated_nested_message_extension, 0)
+ .unknown_fields().field_count());
+
+ // Discard them.
+ ReflectionOps::DiscardUnknownFields(&message);
+ TestUtil::ExpectAllExtensionsSet(message);
+
+ EXPECT_EQ(0, message.unknown_fields().field_count());
+ EXPECT_EQ(0,
+ message.GetExtension(unittest::optional_nested_message_extension)
+ .unknown_fields().field_count());
+ EXPECT_EQ(0,
+ message.GetExtension(unittest::repeated_nested_message_extension, 0)
+ .unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, IsInitialized) {
+ unittest::TestRequired message;
+
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ message.set_a(1);
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ message.set_b(2);
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+ message.set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+}
+
+TEST(ReflectionOpsTest, ForeignIsInitialized) {
+ unittest::TestRequiredForeign message;
+
+ // Starts out initialized because the foreign message is itself an optional
+ // field.
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+ // Once we create that field, the message is no longer initialized.
+ message.mutable_optional_message();
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+ // Initialize it. Now we're initialized.
+ message.mutable_optional_message()->set_a(1);
+ message.mutable_optional_message()->set_b(2);
+ message.mutable_optional_message()->set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+ // Add a repeated version of the message. No longer initialized.
+ unittest::TestRequired* sub_message = message.add_repeated_message();
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+ // Initialize that repeated version.
+ sub_message->set_a(1);
+ sub_message->set_b(2);
+ sub_message->set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+}
+
+TEST(ReflectionOpsTest, ExtensionIsInitialized) {
+ unittest::TestAllExtensions message;
+
+ // Starts out initialized because the foreign message is itself an optional
+ // field.
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+ // Once we create that field, the message is no longer initialized.
+ message.MutableExtension(unittest::TestRequired::single);
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+ // Initialize it. Now we're initialized.
+ message.MutableExtension(unittest::TestRequired::single)->set_a(1);
+ message.MutableExtension(unittest::TestRequired::single)->set_b(2);
+ message.MutableExtension(unittest::TestRequired::single)->set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+ // Add a repeated version of the message. No longer initialized.
+ message.AddExtension(unittest::TestRequired::multi);
+ EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+ // Initialize that repeated version.
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
+ message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
+ EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+}
+
+static string FindInitializationErrors(const Message& message) {
+ vector<string> errors;
+ ReflectionOps::FindInitializationErrors(message, "", &errors);
+ return JoinStrings(errors, ",");
+}
+
+TEST(ReflectionOpsTest, FindInitializationErrors) {
+ unittest::TestRequired message;
+ EXPECT_EQ("a,b,c", FindInitializationErrors(message));
+}
+
+TEST(ReflectionOpsTest, FindForeignInitializationErrors) {
+ unittest::TestRequiredForeign message;
+ message.mutable_optional_message();
+ message.add_repeated_message();
+ message.add_repeated_message();
+ EXPECT_EQ("optional_message.a,"
+ "optional_message.b,"
+ "optional_message.c,"
+ "repeated_message[0].a,"
+ "repeated_message[0].b,"
+ "repeated_message[0].c,"
+ "repeated_message[1].a,"
+ "repeated_message[1].b,"
+ "repeated_message[1].c",
+ FindInitializationErrors(message));
+}
+
+TEST(ReflectionOpsTest, FindExtensionInitializationErrors) {
+ unittest::TestAllExtensions message;
+ message.MutableExtension(unittest::TestRequired::single);
+ message.AddExtension(unittest::TestRequired::multi);
+ message.AddExtension(unittest::TestRequired::multi);
+ EXPECT_EQ("(protobuf_unittest.TestRequired.single).a,"
+ "(protobuf_unittest.TestRequired.single).b,"
+ "(protobuf_unittest.TestRequired.single).c,"
+ "(protobuf_unittest.TestRequired.multi)[0].a,"
+ "(protobuf_unittest.TestRequired.multi)[0].b,"
+ "(protobuf_unittest.TestRequired.multi)[0].c,"
+ "(protobuf_unittest.TestRequired.multi)[1].a,"
+ "(protobuf_unittest.TestRequired.multi)[1].b,"
+ "(protobuf_unittest.TestRequired.multi)[1].c",
+ FindInitializationErrors(message));
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/repeated_field.cc b/src/third_party/protobuf/src/google/protobuf/repeated_field.cc
new file mode 100644
index 0000000..0937774
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/repeated_field.cc
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+void RepeatedPtrFieldBase::Reserve(int new_size) {
+ if (total_size_ >= new_size) return;
+
+ void** old_elements = elements_;
+ total_size_ = max(total_size_ * 2, new_size);
+ elements_ = new void*[total_size_];
+ memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
+ if (old_elements != initial_space_) {
+ delete [] old_elements;
+ }
+}
+
+void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
+ void** swap_elements = elements_;
+ int swap_current_size = current_size_;
+ int swap_allocated_size = allocated_size_;
+ int swap_total_size = total_size_;
+ // We may not be using initial_space_ but it's not worth checking. Just
+ // copy it anyway.
+ void* swap_initial_space[kInitialSize];
+ memcpy(swap_initial_space, initial_space_, sizeof(initial_space_));
+
+ elements_ = other->elements_;
+ current_size_ = other->current_size_;
+ allocated_size_ = other->allocated_size_;
+ total_size_ = other->total_size_;
+ memcpy(initial_space_, other->initial_space_, sizeof(initial_space_));
+
+ other->elements_ = swap_elements;
+ other->current_size_ = swap_current_size;
+ other->allocated_size_ = swap_allocated_size;
+ other->total_size_ = swap_total_size;
+ memcpy(other->initial_space_, swap_initial_space, sizeof(swap_initial_space));
+
+ if (elements_ == other->initial_space_) {
+ elements_ = initial_space_;
+ }
+ if (other->elements_ == initial_space_) {
+ other->elements_ = other->initial_space_;
+ }
+}
+
+string* StringTypeHandlerBase::New() {
+ return new string;
+}
+void StringTypeHandlerBase::Delete(string* value) {
+ delete value;
+}
+
+} // namespace internal
+
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/repeated_field.h b/src/third_party/protobuf/src/google/protobuf/repeated_field.h
new file mode 100644
index 0000000..6a6ae63
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/repeated_field.h
@@ -0,0 +1,1299 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// RepeatedField and RepeatedPtrField are used by generated protocol message
+// classes to manipulate repeated fields. These classes are very similar to
+// STL's vector, but include a number of optimizations found to be useful
+// specifically in the case of Protocol Buffers. RepeatedPtrField is
+// particularly different from STL vector as it manages ownership of the
+// pointers that it contains.
+//
+// Typically, clients should not need to access RepeatedField objects directly,
+// but should instead use the accessor functions generated automatically by the
+// protocol compiler.
+
+#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+#define GOOGLE_PROTOBUF_REPEATED_FIELD_H__
+
+#include <string>
+#ifndef STARBOARD
+#include <iterator>
+#endif // STARBOARD
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/message_lite.h>
+
+namespace google {
+
+namespace protobuf {
+
+class Message;
+
+namespace internal {
+
+// We need this (from generated_message_reflection.cc).
+LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
+
+} // namespace internal
+
+// RepeatedField is used to represent repeated fields of a primitive type (in
+// other words, everything except strings and nested Messages). Most users will
+// not ever use a RepeatedField directly; they will use the get-by-index,
+// set-by-index, and add accessors that are generated for all repeated fields.
+template <typename Element>
+class RepeatedField {
+ public:
+ RepeatedField();
+ RepeatedField(const RepeatedField& other);
+ ~RepeatedField();
+
+ RepeatedField& operator=(const RepeatedField& other);
+
+ int size() const;
+
+ const Element& Get(int index) const;
+ Element* Mutable(int index);
+ void Set(int index, const Element& value);
+ void Add(const Element& value);
+ Element* Add();
+ // Remove the last element in the array.
+ // We don't provide a way to remove any element other than the last
+ // because it invites inefficient use, such as O(n^2) filtering loops
+ // that should have been O(n). If you want to remove an element other
+ // than the last, the best way to do it is to re-arrange the elements
+ // so that the one you want removed is at the end, then call RemoveLast().
+ void RemoveLast();
+ void Clear();
+ void MergeFrom(const RepeatedField& other);
+ void CopyFrom(const RepeatedField& other);
+
+ // Reserve space to expand the field to at least the given size. If the
+ // array is grown, it will always be at least doubled in size.
+ void Reserve(int new_size);
+
+ // Resize the RepeatedField to a new, smaller size. This is O(1).
+ void Truncate(int new_size);
+
+ void AddAlreadyReserved(const Element& value);
+ Element* AddAlreadyReserved();
+ int Capacity() const;
+
+ // Gets the underlying array. This pointer is possibly invalidated by
+ // any add or remove operation.
+ Element* mutable_data();
+ const Element* data() const;
+
+ // Swap entire contents with "other".
+ void Swap(RepeatedField* other);
+
+ // Swap two elements.
+ void SwapElements(int index1, int index2);
+
+ // STL-like iterator support
+ typedef Element* iterator;
+ typedef const Element* const_iterator;
+ typedef Element value_type;
+
+ iterator begin();
+ const_iterator begin() const;
+ iterator end();
+ const_iterator end() const;
+
+ // Returns the number of bytes used by the repeated field, excluding
+ // sizeof(*this)
+ int SpaceUsedExcludingSelf() const;
+
+ private:
+ static const int kInitialSize = 4;
+
+ Element* elements_;
+ int current_size_;
+ int total_size_;
+
+ Element initial_space_[kInitialSize];
+
+ // Move the contents of |from| into |to|, possibly clobbering |from| in the
+ // process. For primitive types this is just a memcpy(), but it could be
+ // specialized for non-primitive types to, say, swap each element instead.
+ void MoveArray(Element to[], Element from[], int size);
+
+ // Copy the elements of |from| into |to|.
+ void CopyArray(Element to[], const Element from[], int size);
+};
+
+namespace internal {
+template <typename It> class RepeatedPtrIterator;
+template <typename It> class RepeatedPtrOverPtrsIterator;
+} // namespace internal
+
+namespace internal {
+
+// This is the common base class for RepeatedPtrFields. It deals only in void*
+// pointers. Users should not use this interface directly.
+//
+// The methods of this interface correspond to the methods of RepeatedPtrField,
+// but may have a template argument called TypeHandler. Its signature is:
+// class TypeHandler {
+// public:
+// typedef MyType Type;
+// static Type* New();
+// static void Delete(Type*);
+// static void Clear(Type*);
+// static void Merge(const Type& from, Type* to);
+//
+// // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
+// static int SpaceUsed(const Type&);
+// };
+class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
+ protected:
+ // The reflection implementation needs to call protected methods directly,
+ // reinterpreting pointers as being to Message instead of a specific Message
+ // subclass.
+ friend class GeneratedMessageReflection;
+
+ // ExtensionSet stores repeated message extensions as
+ // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
+ // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
+ // reinterpreting MessageLite as Message. ExtensionSet also needs to make
+ // use of AddFromCleared(), which is not part of the public interface.
+ friend class ExtensionSet;
+
+ RepeatedPtrFieldBase();
+
+ // Must be called from destructor.
+ template <typename TypeHandler>
+ void Destroy();
+
+ int size() const;
+
+ template <typename TypeHandler>
+ const typename TypeHandler::Type& Get(int index) const;
+ template <typename TypeHandler>
+ typename TypeHandler::Type* Mutable(int index);
+ template <typename TypeHandler>
+ typename TypeHandler::Type* Add();
+ template <typename TypeHandler>
+ void RemoveLast();
+ template <typename TypeHandler>
+ void Clear();
+ template <typename TypeHandler>
+ void MergeFrom(const RepeatedPtrFieldBase& other);
+ template <typename TypeHandler>
+ void CopyFrom(const RepeatedPtrFieldBase& other);
+
+ void Reserve(int new_size);
+
+ int Capacity() const;
+
+ // Used for constructing iterators.
+ void* const* raw_data() const;
+ void** raw_mutable_data() const;
+
+ template <typename TypeHandler>
+ typename TypeHandler::Type** mutable_data();
+ template <typename TypeHandler>
+ const typename TypeHandler::Type* const* data() const;
+
+ void Swap(RepeatedPtrFieldBase* other);
+
+ void SwapElements(int index1, int index2);
+
+ template <typename TypeHandler>
+ int SpaceUsedExcludingSelf() const;
+
+
+ // Advanced memory management --------------------------------------
+
+ // Like Add(), but if there are no cleared objects to use, returns NULL.
+ template <typename TypeHandler>
+ typename TypeHandler::Type* AddFromCleared();
+
+ template <typename TypeHandler>
+ void AddAllocated(typename TypeHandler::Type* value);
+ template <typename TypeHandler>
+ typename TypeHandler::Type* ReleaseLast();
+
+ int ClearedCount() const;
+ template <typename TypeHandler>
+ void AddCleared(typename TypeHandler::Type* value);
+ template <typename TypeHandler>
+ typename TypeHandler::Type* ReleaseCleared();
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
+
+ static const int kInitialSize = 4;
+
+ void** elements_;
+ int current_size_;
+ int allocated_size_;
+ int total_size_;
+
+ void* initial_space_[kInitialSize];
+
+ template <typename TypeHandler>
+ static inline typename TypeHandler::Type* cast(void* element) {
+ return reinterpret_cast<typename TypeHandler::Type*>(element);
+ }
+ template <typename TypeHandler>
+ static inline const typename TypeHandler::Type* cast(const void* element) {
+ return reinterpret_cast<const typename TypeHandler::Type*>(element);
+ }
+};
+
+template <typename GenericType>
+class GenericTypeHandler {
+ public:
+ typedef GenericType Type;
+ static GenericType* New() { return new GenericType; }
+ static void Delete(GenericType* value) { delete value; }
+ static void Clear(GenericType* value) { value->Clear(); }
+ static void Merge(const GenericType& from, GenericType* to) {
+ to->MergeFrom(from);
+ }
+ static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
+};
+
+template <>
+inline void GenericTypeHandler<MessageLite>::Merge(
+ const MessageLite& from, MessageLite* to) {
+ to->CheckTypeAndMergeFrom(from);
+}
+
+// HACK: If a class is declared as DLL-exported in MSVC, it insists on
+// generating copies of all its methods -- even inline ones -- to include
+// in the DLL. But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
+// isn't in the lite library, therefore the lite library cannot link if
+// StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
+// export that, then make StringTypeHandler be a subclass which is NOT
+// exported.
+// TODO(kenton): There has to be a better way.
+class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
+ public:
+ typedef string Type;
+ static string* New();
+ static void Delete(string* value);
+ static void Clear(string* value) { value->clear(); }
+ static void Merge(const string& from, string* to) { *to = from; }
+};
+
+class StringTypeHandler : public StringTypeHandlerBase {
+ public:
+ static int SpaceUsed(const string& value) {
+ return static_cast<int>(
+ sizeof(value) + StringSpaceUsedExcludingSelf(value));
+ }
+};
+
+
+} // namespace internal
+
+// RepeatedPtrField is like RepeatedField, but used for repeated strings or
+// Messages.
+template <typename Element>
+class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
+ public:
+ RepeatedPtrField();
+ RepeatedPtrField(const RepeatedPtrField& other);
+ ~RepeatedPtrField();
+
+ RepeatedPtrField& operator=(const RepeatedPtrField& other);
+
+ int size() const;
+
+ const Element& Get(int index) const;
+ Element* Mutable(int index);
+ Element* Add();
+ void RemoveLast(); // Remove the last element in the array.
+ void Clear();
+ void MergeFrom(const RepeatedPtrField& other);
+ void CopyFrom(const RepeatedPtrField& other);
+
+ // Reserve space to expand the field to at least the given size. This only
+ // resizes the pointer array; it doesn't allocate any objects. If the
+ // array is grown, it will always be at least doubled in size.
+ void Reserve(int new_size);
+
+ int Capacity() const;
+
+ // Gets the underlying array. This pointer is possibly invalidated by
+ // any add or remove operation.
+ Element** mutable_data();
+ const Element* const* data() const;
+
+ // Swap entire contents with "other".
+ void Swap(RepeatedPtrField* other);
+
+ // Swap two elements.
+ void SwapElements(int index1, int index2);
+
+ // STL-like iterator support
+ typedef internal::RepeatedPtrIterator<Element> iterator;
+ typedef internal::RepeatedPtrIterator<const Element> const_iterator;
+ typedef Element value_type;
+
+ iterator begin();
+ const_iterator begin() const;
+ iterator end();
+ const_iterator end() const;
+
+ // Custom STL-like iterator that iterates over and returns the underlying
+ // pointers to Element rather than Element itself.
+ typedef internal::RepeatedPtrOverPtrsIterator<Element> pointer_iterator;
+ pointer_iterator pointer_begin();
+ pointer_iterator pointer_end();
+
+ // Returns (an estimate of) the number of bytes used by the repeated field,
+ // excluding sizeof(*this).
+ int SpaceUsedExcludingSelf() const;
+
+ // Advanced memory management --------------------------------------
+ // When hardcore memory management becomes necessary -- as it often
+ // does here at Google -- the following methods may be useful.
+
+ // Add an already-allocated object, passing ownership to the
+ // RepeatedPtrField.
+ void AddAllocated(Element* value);
+ // Remove the last element and return it, passing ownership to the
+ // caller.
+ // Requires: size() > 0
+ Element* ReleaseLast();
+
+ // When elements are removed by calls to RemoveLast() or Clear(), they
+ // are not actually freed. Instead, they are cleared and kept so that
+ // they can be reused later. This can save lots of CPU time when
+ // repeatedly reusing a protocol message for similar purposes.
+ //
+ // Really, extremely hardcore programs may actually want to manipulate
+ // these objects to better-optimize memory management. These methods
+ // allow that.
+
+ // Get the number of cleared objects that are currently being kept
+ // around for reuse.
+ int ClearedCount() const;
+ // Add an element to the pool of cleared objects, passing ownership to
+ // the RepeatedPtrField. The element must be cleared prior to calling
+ // this method.
+ void AddCleared(Element* value);
+ // Remove a single element from the cleared pool and return it, passing
+ // ownership to the caller. The element is guaranteed to be cleared.
+ // Requires: ClearedCount() > 0
+ Element* ReleaseCleared();
+
+ protected:
+ // Note: RepeatedPtrField SHOULD NOT be subclassed by users. We only
+ // subclass it in one place as a hack for compatibility with proto1. The
+ // subclass needs to know about TypeHandler in order to call protected
+ // methods on RepeatedPtrFieldBase.
+ class TypeHandler;
+
+};
+
+// implementation ====================================================
+
+template <typename Element>
+inline RepeatedField<Element>::RepeatedField()
+ : elements_(initial_space_),
+ current_size_(0),
+ total_size_(kInitialSize) {
+}
+
+template <typename Element>
+inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
+ : elements_(initial_space_),
+ current_size_(0),
+ total_size_(kInitialSize) {
+ CopyFrom(other);
+}
+
+template <typename Element>
+RepeatedField<Element>::~RepeatedField() {
+ if (elements_ != initial_space_) {
+ delete [] elements_;
+ }
+}
+
+template <typename Element>
+inline RepeatedField<Element>&
+RepeatedField<Element>::operator=(const RepeatedField& other) {
+ CopyFrom(other);
+ return *this;
+}
+
+template <typename Element>
+inline int RepeatedField<Element>::size() const {
+ return current_size_;
+}
+
+template <typename Element>
+inline int RepeatedField<Element>::Capacity() const {
+ return total_size_;
+}
+
+template<typename Element>
+inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
+ GOOGLE_DCHECK_LT(size(), Capacity());
+ elements_[current_size_++] = value;
+}
+
+template<typename Element>
+inline Element* RepeatedField<Element>::AddAlreadyReserved() {
+ GOOGLE_DCHECK_LT(size(), Capacity());
+ return &elements_[current_size_++];
+}
+
+template <typename Element>
+inline const Element& RepeatedField<Element>::Get(int index) const {
+ GOOGLE_DCHECK_LT(index, size());
+ return elements_[index];
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::Mutable(int index) {
+ GOOGLE_DCHECK_LT(index, size());
+ return elements_ + index;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Set(int index, const Element& value) {
+ GOOGLE_DCHECK_LT(index, size());
+ elements_[index] = value;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Add(const Element& value) {
+ if (current_size_ == total_size_) Reserve(total_size_ + 1);
+ elements_[current_size_++] = value;
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::Add() {
+ if (current_size_ == total_size_) Reserve(total_size_ + 1);
+ return &elements_[current_size_++];
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::RemoveLast() {
+ GOOGLE_DCHECK_GT(current_size_, 0);
+ --current_size_;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Clear() {
+ current_size_ = 0;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
+ Reserve(current_size_ + other.current_size_);
+ CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
+ current_size_ += other.current_size_;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
+ Clear();
+ MergeFrom(other);
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::mutable_data() {
+ return elements_;
+}
+
+template <typename Element>
+inline const Element* RepeatedField<Element>::data() const {
+ return elements_;
+}
+
+
+template <typename Element>
+void RepeatedField<Element>::Swap(RepeatedField* other) {
+ Element* swap_elements = elements_;
+ int swap_current_size = current_size_;
+ int swap_total_size = total_size_;
+ // We may not be using initial_space_ but it's not worth checking. Just
+ // copy it anyway.
+ Element swap_initial_space[kInitialSize];
+ MoveArray(swap_initial_space, initial_space_, kInitialSize);
+
+ elements_ = other->elements_;
+ current_size_ = other->current_size_;
+ total_size_ = other->total_size_;
+ MoveArray(initial_space_, other->initial_space_, kInitialSize);
+
+ other->elements_ = swap_elements;
+ other->current_size_ = swap_current_size;
+ other->total_size_ = swap_total_size;
+ MoveArray(other->initial_space_, swap_initial_space, kInitialSize);
+
+ if (elements_ == other->initial_space_) {
+ elements_ = initial_space_;
+ }
+ if (other->elements_ == initial_space_) {
+ other->elements_ = other->initial_space_;
+ }
+}
+
+template <typename Element>
+void RepeatedField<Element>::SwapElements(int index1, int index2) {
+ std::swap(elements_[index1], elements_[index2]);
+}
+
+template <typename Element>
+inline typename RepeatedField<Element>::iterator
+RepeatedField<Element>::begin() {
+ return elements_;
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::begin() const {
+ return elements_;
+}
+template <typename Element>
+inline typename RepeatedField<Element>::iterator
+RepeatedField<Element>::end() {
+ return elements_ + current_size_;
+}
+template <typename Element>
+inline typename RepeatedField<Element>::const_iterator
+RepeatedField<Element>::end() const {
+ return elements_ + current_size_;
+}
+
+template <typename Element>
+inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
+ return (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
+}
+
+// Avoid inlining of Reserve(): new, memcpy, and delete[] lead to a significant
+// amount of code bloat.
+template <typename Element>
+void RepeatedField<Element>::Reserve(int new_size) {
+ if (total_size_ >= new_size) return;
+
+ Element* old_elements = elements_;
+ total_size_ = max(total_size_ * 2, new_size);
+ elements_ = new Element[static_cast<size_t>(total_size_)];
+ MoveArray(elements_, old_elements, current_size_);
+ if (old_elements != initial_space_) {
+ delete [] old_elements;
+ }
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Truncate(int new_size) {
+ GOOGLE_DCHECK_LE(new_size, current_size_);
+ current_size_ = new_size;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::MoveArray(
+ Element to[], Element from[], int array_size) {
+ memcpy(to, from, array_size * sizeof(Element));
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::CopyArray(
+ Element to[], const Element from[], int array_size) {
+ memcpy(to, from, array_size * sizeof(Element));
+}
+
+
+// -------------------------------------------------------------------
+
+namespace internal {
+
+inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
+ : elements_(initial_space_),
+ current_size_(0),
+ allocated_size_(0),
+ total_size_(kInitialSize) {
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::Destroy() {
+ for (int i = 0; i < allocated_size_; i++) {
+ TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
+ }
+ if (elements_ != initial_space_) {
+ delete [] elements_;
+ }
+}
+
+inline int RepeatedPtrFieldBase::size() const {
+ return current_size_;
+}
+
+
+template <typename TypeHandler>
+inline const typename TypeHandler::Type&
+RepeatedPtrFieldBase::Get(int index) const {
+ GOOGLE_DCHECK_LT(index, size());
+ return *cast<TypeHandler>(elements_[index]);
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type*
+RepeatedPtrFieldBase::Mutable(int index) {
+ GOOGLE_DCHECK_LT(index, size());
+ return cast<TypeHandler>(elements_[index]);
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
+ if (current_size_ < allocated_size_) {
+ return cast<TypeHandler>(elements_[current_size_++]);
+ }
+ if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
+ ++allocated_size_;
+ typename TypeHandler::Type* result = TypeHandler::New();
+ elements_[current_size_++] = result;
+ return result;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::RemoveLast() {
+ GOOGLE_DCHECK_GT(current_size_, 0);
+ TypeHandler::Clear(cast<TypeHandler>(elements_[--current_size_]));
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::Clear() {
+ for (int i = 0; i < current_size_; i++) {
+ TypeHandler::Clear(cast<TypeHandler>(elements_[i]));
+ }
+ current_size_ = 0;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
+ Reserve(current_size_ + other.current_size_);
+ for (int i = 0; i < other.current_size_; i++) {
+ TypeHandler::Merge(other.template Get<TypeHandler>(i), Add<TypeHandler>());
+ }
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+}
+
+inline int RepeatedPtrFieldBase::Capacity() const {
+ return total_size_;
+}
+
+inline void* const* RepeatedPtrFieldBase::raw_data() const {
+ return elements_;
+}
+
+inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
+ return elements_;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
+ // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
+ // method entirely.
+ return reinterpret_cast<typename TypeHandler::Type**>(elements_);
+}
+
+template <typename TypeHandler>
+inline const typename TypeHandler::Type* const*
+RepeatedPtrFieldBase::data() const {
+ // TODO(kenton): Breaks C++ aliasing rules. We should probably remove this
+ // method entirely.
+ return reinterpret_cast<const typename TypeHandler::Type* const*>(elements_);
+}
+
+inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
+ std::swap(elements_[index1], elements_[index2]);
+}
+
+template <typename TypeHandler>
+inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
+ int allocated_bytes =
+ (elements_ != initial_space_) ? total_size_ * sizeof(elements_[0]) : 0;
+ for (int i = 0; i < allocated_size_; ++i) {
+ allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
+ }
+ return allocated_bytes;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
+ if (current_size_ < allocated_size_) {
+ return cast<TypeHandler>(elements_[current_size_++]);
+ } else {
+ return NULL;
+ }
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::AddAllocated(
+ typename TypeHandler::Type* value) {
+ // Make room for the new pointer.
+ if (current_size_ == total_size_) {
+ // The array is completely full with no cleared objects, so grow it.
+ Reserve(total_size_ + 1);
+ ++allocated_size_;
+ } else if (allocated_size_ == total_size_) {
+ // There is no more space in the pointer array because it contains some
+ // cleared objects awaiting reuse. We don't want to grow the array in this
+ // case because otherwise a loop calling AddAllocated() followed by Clear()
+ // would leak memory.
+ TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_]));
+ } else if (current_size_ < allocated_size_) {
+ // We have some cleared objects. We don't care about their order, so we
+ // can just move the first one to the end to make space.
+ elements_[allocated_size_] = elements_[current_size_];
+ ++allocated_size_;
+ } else {
+ // There are no cleared objects.
+ ++allocated_size_;
+ }
+
+ elements_[current_size_++] = value;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
+ GOOGLE_DCHECK_GT(current_size_, 0);
+ typename TypeHandler::Type* result =
+ cast<TypeHandler>(elements_[--current_size_]);
+ --allocated_size_;
+ if (current_size_ < allocated_size_) {
+ // There are cleared elements on the end; replace the removed element
+ // with the last allocated element.
+ elements_[current_size_] = elements_[allocated_size_];
+ }
+ return result;
+}
+
+
+inline int RepeatedPtrFieldBase::ClearedCount() const {
+ return allocated_size_ - current_size_;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::AddCleared(
+ typename TypeHandler::Type* value) {
+ if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
+ elements_[allocated_size_++] = value;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
+ GOOGLE_DCHECK_GT(allocated_size_, current_size_);
+ return cast<TypeHandler>(elements_[--allocated_size_]);
+}
+
+} // namespace internal
+
+// -------------------------------------------------------------------
+
+template <typename Element>
+class RepeatedPtrField<Element>::TypeHandler
+ : public internal::GenericTypeHandler<Element> {};
+
+template <>
+class RepeatedPtrField<string>::TypeHandler
+ : public internal::StringTypeHandler {};
+
+
+template <typename Element>
+inline RepeatedPtrField<Element>::RepeatedPtrField() {}
+
+template <typename Element>
+inline RepeatedPtrField<Element>::RepeatedPtrField(
+ const RepeatedPtrField& other) {
+ CopyFrom(other);
+}
+
+template <typename Element>
+RepeatedPtrField<Element>::~RepeatedPtrField() {
+ Destroy<TypeHandler>();
+}
+
+template <typename Element>
+inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
+ const RepeatedPtrField& other) {
+ CopyFrom(other);
+ return *this;
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::size() const {
+ return RepeatedPtrFieldBase::size();
+}
+
+template <typename Element>
+inline const Element& RepeatedPtrField<Element>::Get(int index) const {
+ return RepeatedPtrFieldBase::Get<TypeHandler>(index);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::Mutable(int index) {
+ return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::Add() {
+ return RepeatedPtrFieldBase::Add<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::RemoveLast() {
+ RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Clear() {
+ RepeatedPtrFieldBase::Clear<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::MergeFrom(
+ const RepeatedPtrField& other) {
+ RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::CopyFrom(
+ const RepeatedPtrField& other) {
+ RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
+}
+
+template <typename Element>
+inline Element** RepeatedPtrField<Element>::mutable_data() {
+ return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
+}
+
+template <typename Element>
+inline const Element* const* RepeatedPtrField<Element>::data() const {
+ return RepeatedPtrFieldBase::data<TypeHandler>();
+}
+
+template <typename Element>
+void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
+ RepeatedPtrFieldBase::Swap(other);
+}
+
+template <typename Element>
+void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
+ RepeatedPtrFieldBase::SwapElements(index1, index2);
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
+ return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
+ RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::ReleaseLast() {
+ return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
+}
+
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::ClearedCount() const {
+ return RepeatedPtrFieldBase::ClearedCount();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
+ return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
+ return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Reserve(int new_size) {
+ return RepeatedPtrFieldBase::Reserve(new_size);
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::Capacity() const {
+ return RepeatedPtrFieldBase::Capacity();
+}
+
+// -------------------------------------------------------------------
+
+namespace internal {
+
+// STL-like iterator implementation for RepeatedPtrField. You should not
+// refer to this class directly; use RepeatedPtrField<T>::iterator instead.
+//
+// The iterator for RepeatedPtrField<T>, RepeatedPtrIterator<T>, is
+// very similar to iterator_ptr<T**> in util/gtl/iterator_adaptors-inl.h,
+// but adds random-access operators and is modified to wrap a void** base
+// iterator (since RepeatedPtrField stores its array as a void* array and
+// casting void** to T** would violate C++ aliasing rules).
+//
+// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
+// (jyasskin@google.com).
+template<typename Element>
+class RepeatedPtrIterator
+ : public std::iterator<
+ std::random_access_iterator_tag, Element> {
+ public:
+ typedef RepeatedPtrIterator<Element> iterator;
+ typedef std::iterator<
+ std::random_access_iterator_tag, Element> superclass;
+
+ // Let the compiler know that these are type names, so we don't have to
+ // write "typename" in front of them everywhere.
+ typedef typename superclass::reference reference;
+ typedef typename superclass::pointer pointer;
+ typedef typename superclass::difference_type difference_type;
+
+ RepeatedPtrIterator() : it_(NULL) {}
+ explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
+
+ // Allow "upcasting" from RepeatedPtrIterator<T**> to
+ // RepeatedPtrIterator<const T*const*>.
+ template<typename OtherElement>
+ RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
+ : it_(other.it_) {
+ // Force a compiler error if the other type is not convertible to ours.
+ if (false) {
+ implicit_cast<Element*, OtherElement*>(0);
+ }
+ }
+
+ // dereferenceable
+ reference operator*() const { return *reinterpret_cast<Element*>(*it_); }
+ pointer operator->() const { return &(operator*()); }
+
+ // {inc,dec}rementable
+ iterator& operator++() { ++it_; return *this; }
+ iterator operator++(int) { return iterator(it_++); }
+ iterator& operator--() { --it_; return *this; }
+ iterator operator--(int) { return iterator(it_--); }
+
+ // equality_comparable
+ bool operator==(const iterator& x) const { return it_ == x.it_; }
+ bool operator!=(const iterator& x) const { return it_ != x.it_; }
+
+ // less_than_comparable
+ bool operator<(const iterator& x) const { return it_ < x.it_; }
+ bool operator<=(const iterator& x) const { return it_ <= x.it_; }
+ bool operator>(const iterator& x) const { return it_ > x.it_; }
+ bool operator>=(const iterator& x) const { return it_ >= x.it_; }
+
+ // addable, subtractable
+ iterator& operator+=(difference_type d) {
+ it_ += d;
+ return *this;
+ }
+ friend iterator operator+(iterator it, difference_type d) {
+ it += d;
+ return it;
+ }
+ friend iterator operator+(difference_type d, iterator it) {
+ it += d;
+ return it;
+ }
+ iterator& operator-=(difference_type d) {
+ it_ -= d;
+ return *this;
+ }
+ friend iterator operator-(iterator it, difference_type d) {
+ it -= d;
+ return it;
+ }
+
+ // indexable
+ reference operator[](difference_type d) const { return *(*this + d); }
+
+ // random access iterator
+ difference_type operator-(const iterator& x) const { return it_ - x.it_; }
+
+ private:
+ template<typename OtherElement>
+ friend class RepeatedPtrIterator;
+
+ // The internal iterator.
+ void* const* it_;
+};
+
+// Provide an iterator that operates on pointers to the underlying objects
+// rather than the objects themselves as RepeatedPtrIterator does.
+// Consider using this when working with stl algorithms that change
+// the array.
+template<typename Element>
+class RepeatedPtrOverPtrsIterator
+ : public std::iterator<std::random_access_iterator_tag, Element*> {
+ public:
+ typedef RepeatedPtrOverPtrsIterator<Element> iterator;
+ typedef std::iterator<
+ std::random_access_iterator_tag, Element*> superclass;
+
+ // Let the compiler know that these are type names, so we don't have to
+ // write "typename" in front of them everywhere.
+ typedef typename superclass::reference reference;
+ typedef typename superclass::pointer pointer;
+ typedef typename superclass::difference_type difference_type;
+
+ RepeatedPtrOverPtrsIterator() : it_(NULL) {}
+ explicit RepeatedPtrOverPtrsIterator(void** it) : it_(it) {}
+
+ // dereferenceable
+ reference operator*() const { return *reinterpret_cast<Element**>(it_); }
+ pointer operator->() const { return &(operator*()); }
+
+ // {inc,dec}rementable
+ iterator& operator++() { ++it_; return *this; }
+ iterator operator++(int) { return iterator(it_++); }
+ iterator& operator--() { --it_; return *this; }
+ iterator operator--(int) { return iterator(it_--); }
+
+ // equality_comparable
+ bool operator==(const iterator& x) const { return it_ == x.it_; }
+ bool operator!=(const iterator& x) const { return it_ != x.it_; }
+
+ // less_than_comparable
+ bool operator<(const iterator& x) const { return it_ < x.it_; }
+ bool operator<=(const iterator& x) const { return it_ <= x.it_; }
+ bool operator>(const iterator& x) const { return it_ > x.it_; }
+ bool operator>=(const iterator& x) const { return it_ >= x.it_; }
+
+ // addable, subtractable
+ iterator& operator+=(difference_type d) {
+ it_ += d;
+ return *this;
+ }
+ friend iterator operator+(iterator it, difference_type d) {
+ it += d;
+ return it;
+ }
+ friend iterator operator+(difference_type d, iterator it) {
+ it += d;
+ return it;
+ }
+ iterator& operator-=(difference_type d) {
+ it_ -= d;
+ return *this;
+ }
+ friend iterator operator-(iterator it, difference_type d) {
+ it -= d;
+ return it;
+ }
+
+ // indexable
+ reference operator[](difference_type d) const { return *(*this + d); }
+
+ // random access iterator
+ difference_type operator-(const iterator& x) const { return it_ - x.it_; }
+
+ private:
+ template<typename OtherElement>
+ friend class RepeatedPtrIterator;
+
+ // The internal iterator.
+ void** it_;
+};
+
+
+} // namespace internal
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::begin() {
+ return iterator(raw_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::begin() const {
+ return iterator(raw_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::end() {
+ return iterator(raw_data() + size());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::end() const {
+ return iterator(raw_data() + size());
+}
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::pointer_iterator
+RepeatedPtrField<Element>::pointer_begin() {
+ return pointer_iterator(raw_mutable_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::pointer_iterator
+RepeatedPtrField<Element>::pointer_end() {
+ return pointer_iterator(raw_mutable_data() + size());
+}
+
+
+// Iterators and helper functions that follow the spirit of the STL
+// std::back_insert_iterator and std::back_inserter but are tailor-made
+// for RepeatedField and RepatedPtrField. Typical usage would be:
+//
+// std::copy(some_sequence.begin(), some_sequence.end(),
+// google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
+//
+// Ported by johannes from util/gtl/proto-array-iterators-inl.h
+
+namespace internal {
+// A back inserter for RepeatedField objects.
+template<typename T> class RepeatedFieldBackInsertIterator
+ : public std::iterator<std::output_iterator_tag, T> {
+ public:
+ explicit RepeatedFieldBackInsertIterator(
+ RepeatedField<T>* const mutable_field)
+ : field_(mutable_field) {
+ }
+ RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
+ field_->Add(value);
+ return *this;
+ }
+ RepeatedFieldBackInsertIterator<T>& operator*() {
+ return *this;
+ }
+ RepeatedFieldBackInsertIterator<T>& operator++() {
+ return *this;
+ }
+ RepeatedFieldBackInsertIterator<T>& operator++(int /*ignores_parameter*/) {
+ return *this;
+ }
+
+ private:
+ RepeatedField<T>* field_;
+};
+
+// A back inserter for RepeatedPtrField objects.
+template<typename T> class RepeatedPtrFieldBackInsertIterator
+ : public std::iterator<std::output_iterator_tag, T> {
+ public:
+ RepeatedPtrFieldBackInsertIterator(
+ RepeatedPtrField<T>* const mutable_field)
+ : field_(mutable_field) {
+ }
+ RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
+ *field_->Add() = value;
+ return *this;
+ }
+ RepeatedPtrFieldBackInsertIterator<T>& operator=(
+ const T* const ptr_to_value) {
+ *field_->Add() = *ptr_to_value;
+ return *this;
+ }
+ RepeatedPtrFieldBackInsertIterator<T>& operator*() {
+ return *this;
+ }
+ RepeatedPtrFieldBackInsertIterator<T>& operator++() {
+ return *this;
+ }
+ RepeatedPtrFieldBackInsertIterator<T>& operator++(int /*ignores_parameter*/) {
+ return *this;
+ }
+
+ private:
+ RepeatedPtrField<T>* field_;
+};
+
+// A back inserter for RepeatedPtrFields that inserts by transfering ownership
+// of a pointer.
+template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
+ : public std::iterator<std::output_iterator_tag, T> {
+ public:
+ explicit AllocatedRepeatedPtrFieldBackInsertIterator(
+ RepeatedPtrField<T>* const mutable_field)
+ : field_(mutable_field) {
+ }
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
+ T* const ptr_to_value) {
+ field_->AddAllocated(ptr_to_value);
+ return *this;
+ }
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
+ return *this;
+ }
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
+ return *this;
+ }
+ AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
+ int /*ignores_parameter*/) {
+ return *this;
+ }
+
+ private:
+ RepeatedPtrField<T>* field_;
+};
+} // namespace internal
+
+// Provides a back insert iterator for RepeatedField instances,
+// similar to std::back_inserter(). Note the identically named
+// function for RepeatedPtrField instances.
+template<typename T> internal::RepeatedFieldBackInsertIterator<T>
+RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
+ return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Provides a back insert iterator for RepeatedPtrField instances,
+// similar to std::back_inserter(). Note the identically named
+// function for RepeatedField instances.
+template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
+RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
+ return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Provides a back insert iterator for RepeatedPtrField instances
+// similar to std::back_inserter() which transfers the ownership while
+// copying elements.
+template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
+AllocatedRepeatedPtrFieldBackInserter(
+ RepeatedPtrField<T>* const mutable_field) {
+ return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
+ mutable_field);
+}
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/repeated_field_unittest.cc b/src/third_party/protobuf/src/google/protobuf/repeated_field_unittest.cc
new file mode 100644
index 0000000..e7e1e99
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/repeated_field_unittest.cc
@@ -0,0 +1,1086 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// TODO(kenton): Improve this unittest to bring it up to the standards of
+// other proto2 unittests.
+
+#include <algorithm>
+#include <list>
+#include <vector>
+
+#include <google/protobuf/repeated_field.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+using protobuf_unittest::TestAllTypes;
+
+namespace protobuf {
+namespace {
+
+// Test operations on a RepeatedField which is small enough that it does
+// not allocate a separate array for storage.
+TEST(RepeatedField, Small) {
+ RepeatedField<int> field;
+
+ EXPECT_EQ(field.size(), 0);
+
+ field.Add(5);
+
+ EXPECT_EQ(field.size(), 1);
+ EXPECT_EQ(field.Get(0), 5);
+
+ field.Add(42);
+
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.Get(1), 42);
+
+ field.Set(1, 23);
+
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), 5);
+ EXPECT_EQ(field.Get(1), 23);
+ EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0);
+
+ field.RemoveLast();
+
+ EXPECT_EQ(field.size(), 1);
+ EXPECT_EQ(field.Get(0), 5);
+
+ field.Clear();
+
+ EXPECT_EQ(field.size(), 0);
+ EXPECT_EQ(field.SpaceUsedExcludingSelf(), 0);
+}
+
+// Test operations on a RepeatedField which is large enough to allocate a
+// separate array.
+TEST(RepeatedField, Large) {
+ RepeatedField<int> field;
+
+ for (int i = 0; i < 16; i++) {
+ field.Add(i * i);
+ }
+
+ EXPECT_EQ(field.size(), 16);
+
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field.Get(i), i * i);
+ }
+
+ int expected_usage = 16 * sizeof(int);
+ EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage);
+}
+
+// Test swapping between various types of RepeatedFields.
+TEST(RepeatedField, SwapSmallSmall) {
+ RepeatedField<int> field1;
+ RepeatedField<int> field2;
+
+ field1.Add(5);
+ field1.Add(42);
+
+ field1.Swap(&field2);
+
+ EXPECT_EQ(field1.size(), 0);
+ EXPECT_EQ(field2.size(), 2);
+ EXPECT_EQ(field2.Get(0), 5);
+ EXPECT_EQ(field2.Get(1), 42);
+}
+
+TEST(RepeatedField, SwapLargeSmall) {
+ RepeatedField<int> field1;
+ RepeatedField<int> field2;
+
+ for (int i = 0; i < 16; i++) {
+ field1.Add(i * i);
+ }
+ field2.Add(5);
+ field2.Add(42);
+ field1.Swap(&field2);
+
+ EXPECT_EQ(field1.size(), 2);
+ EXPECT_EQ(field1.Get(0), 5);
+ EXPECT_EQ(field1.Get(1), 42);
+ EXPECT_EQ(field2.size(), 16);
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field2.Get(i), i * i);
+ }
+}
+
+TEST(RepeatedField, SwapLargeLarge) {
+ RepeatedField<int> field1;
+ RepeatedField<int> field2;
+
+ field1.Add(5);
+ field1.Add(42);
+ for (int i = 0; i < 16; i++) {
+ field1.Add(i);
+ field2.Add(i * i);
+ }
+ field2.Swap(&field1);
+
+ EXPECT_EQ(field1.size(), 16);
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field1.Get(i), i * i);
+ }
+ EXPECT_EQ(field2.size(), 18);
+ EXPECT_EQ(field2.Get(0), 5);
+ EXPECT_EQ(field2.Get(1), 42);
+ for (int i = 2; i < 18; i++) {
+ EXPECT_EQ(field2.Get(i), i - 2);
+ }
+}
+
+// Determines how much space was reserved by the given field by adding elements
+// to it until it re-allocates its space.
+static int ReservedSpace(RepeatedField<int>* field) {
+ const int* ptr = field->data();
+ do {
+ field->Add(0);
+ } while (field->data() == ptr);
+
+ return field->size() - 1;
+}
+
+TEST(RepeatedField, ReserveMoreThanDouble) {
+ // Reserve more than double the previous space in the field and expect the
+ // field to reserve exactly the amount specified.
+ RepeatedField<int> field;
+ field.Reserve(20);
+
+ EXPECT_EQ(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, ReserveLessThanDouble) {
+ // Reserve less than double the previous space in the field and expect the
+ // field to grow by double instead.
+ RepeatedField<int> field;
+ field.Reserve(20);
+ field.Reserve(30);
+
+ EXPECT_EQ(40, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, ReserveLessThanExisting) {
+ // Reserve less than the previous space in the field and expect the
+ // field to not re-allocate at all.
+ RepeatedField<int> field;
+ field.Reserve(20);
+ const int* previous_ptr = field.data();
+ field.Reserve(10);
+
+ EXPECT_EQ(previous_ptr, field.data());
+ EXPECT_EQ(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedField, MergeFrom) {
+ RepeatedField<int> source, destination;
+
+ source.Add(4);
+ source.Add(5);
+
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination.MergeFrom(source);
+
+ ASSERT_EQ(5, destination.size());
+
+ EXPECT_EQ(1, destination.Get(0));
+ EXPECT_EQ(2, destination.Get(1));
+ EXPECT_EQ(3, destination.Get(2));
+ EXPECT_EQ(4, destination.Get(3));
+ EXPECT_EQ(5, destination.Get(4));
+}
+
+TEST(RepeatedField, CopyFrom) {
+ RepeatedField<int> source, destination;
+
+ source.Add(4);
+ source.Add(5);
+
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination.CopyFrom(source);
+
+ ASSERT_EQ(2, destination.size());
+
+ EXPECT_EQ(4, destination.Get(0));
+ EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, CopyConstruct) {
+ RepeatedField<int> source;
+ source.Add(1);
+ source.Add(2);
+
+ RepeatedField<int> destination(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ(1, destination.Get(0));
+ EXPECT_EQ(2, destination.Get(1));
+}
+
+TEST(RepeatedField, CopyAssign) {
+ RepeatedField<int> source, destination;
+
+ source.Add(4);
+ source.Add(5);
+
+ destination.Add(1);
+ destination.Add(2);
+ destination.Add(3);
+
+ destination = source;
+
+ ASSERT_EQ(2, destination.size());
+
+ EXPECT_EQ(4, destination.Get(0));
+ EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, MutableDataIsMutable) {
+ RepeatedField<int> field;
+ field.Add(1);
+ EXPECT_EQ(1, field.Get(0));
+ // The fact that this line compiles would be enough, but we'll check the
+ // value anyway.
+ *field.mutable_data() = 2;
+ EXPECT_EQ(2, field.Get(0));
+}
+
+TEST(RepeatedField, Truncate) {
+ RepeatedField<int> field;
+
+ field.Add(12);
+ field.Add(34);
+ field.Add(56);
+ field.Add(78);
+ EXPECT_EQ(4, field.size());
+
+ field.Truncate(3);
+ EXPECT_EQ(3, field.size());
+
+ field.Add(90);
+ EXPECT_EQ(4, field.size());
+ EXPECT_EQ(90, field.Get(3));
+
+ // Truncations that don't change the size are allowed, but growing is not
+ // allowed.
+ field.Truncate(field.size());
+#ifdef GTEST_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size");
+#endif
+}
+
+
+// ===================================================================
+// RepeatedPtrField tests. These pretty much just mirror the RepeatedField
+// tests above.
+
+TEST(RepeatedPtrField, Small) {
+ RepeatedPtrField<string> field;
+
+ EXPECT_EQ(field.size(), 0);
+
+ field.Add()->assign("foo");
+
+ EXPECT_EQ(field.size(), 1);
+ EXPECT_EQ(field.Get(0), "foo");
+
+ field.Add()->assign("bar");
+
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.Get(1), "bar");
+
+ field.Mutable(1)->assign("baz");
+
+ EXPECT_EQ(field.size(), 2);
+ EXPECT_EQ(field.Get(0), "foo");
+ EXPECT_EQ(field.Get(1), "baz");
+
+ field.RemoveLast();
+
+ EXPECT_EQ(field.size(), 1);
+ EXPECT_EQ(field.Get(0), "foo");
+
+ field.Clear();
+
+ EXPECT_EQ(field.size(), 0);
+}
+
+TEST(RepeatedPtrField, Large) {
+ RepeatedPtrField<string> field;
+
+ for (int i = 0; i < 16; i++) {
+ *field.Add() += 'a' + i;
+ }
+
+ EXPECT_EQ(field.size(), 16);
+
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field.Get(i).size(), 1);
+ EXPECT_EQ(field.Get(i)[0], 'a' + i);
+ }
+
+ int min_expected_usage = 16 * sizeof(string);
+ EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage);
+}
+
+TEST(RepeatedPtrField, SwapSmallSmall) {
+ RepeatedPtrField<string> field1;
+ RepeatedPtrField<string> field2;
+
+ field1.Add()->assign("foo");
+ field1.Add()->assign("bar");
+ field1.Swap(&field2);
+
+ EXPECT_EQ(field1.size(), 0);
+ EXPECT_EQ(field2.size(), 2);
+ EXPECT_EQ(field2.Get(0), "foo");
+ EXPECT_EQ(field2.Get(1), "bar");
+}
+
+TEST(RepeatedPtrField, SwapLargeSmall) {
+ RepeatedPtrField<string> field1;
+ RepeatedPtrField<string> field2;
+
+ field2.Add()->assign("foo");
+ field2.Add()->assign("bar");
+ for (int i = 0; i < 16; i++) {
+ *field1.Add() += 'a' + i;
+ }
+ field1.Swap(&field2);
+
+ EXPECT_EQ(field1.size(), 2);
+ EXPECT_EQ(field1.Get(0), "foo");
+ EXPECT_EQ(field1.Get(1), "bar");
+ EXPECT_EQ(field2.size(), 16);
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field2.Get(i).size(), 1);
+ EXPECT_EQ(field2.Get(i)[0], 'a' + i);
+ }
+}
+
+TEST(RepeatedPtrField, SwapLargeLarge) {
+ RepeatedPtrField<string> field1;
+ RepeatedPtrField<string> field2;
+
+ field1.Add()->assign("foo");
+ field1.Add()->assign("bar");
+ for (int i = 0; i < 16; i++) {
+ *field1.Add() += 'A' + i;
+ *field2.Add() += 'a' + i;
+ }
+ field2.Swap(&field1);
+
+ EXPECT_EQ(field1.size(), 16);
+ for (int i = 0; i < 16; i++) {
+ EXPECT_EQ(field1.Get(i).size(), 1);
+ EXPECT_EQ(field1.Get(i)[0], 'a' + i);
+ }
+ EXPECT_EQ(field2.size(), 18);
+ EXPECT_EQ(field2.Get(0), "foo");
+ EXPECT_EQ(field2.Get(1), "bar");
+ for (int i = 2; i < 18; i++) {
+ EXPECT_EQ(field2.Get(i).size(), 1);
+ EXPECT_EQ(field2.Get(i)[0], 'A' + i - 2);
+ }
+}
+
+static int ReservedSpace(RepeatedPtrField<string>* field) {
+ const string* const* ptr = field->data();
+ do {
+ field->Add();
+ } while (field->data() == ptr);
+
+ return field->size() - 1;
+}
+
+TEST(RepeatedPtrField, ReserveMoreThanDouble) {
+ RepeatedPtrField<string> field;
+ field.Reserve(20);
+
+ EXPECT_EQ(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveLessThanDouble) {
+ RepeatedPtrField<string> field;
+ field.Reserve(20);
+ field.Reserve(30);
+
+ EXPECT_EQ(40, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveLessThanExisting) {
+ RepeatedPtrField<string> field;
+ field.Reserve(20);
+ const string* const* previous_ptr = field.data();
+ field.Reserve(10);
+
+ EXPECT_EQ(previous_ptr, field.data());
+ EXPECT_EQ(20, ReservedSpace(&field));
+}
+
+TEST(RepeatedPtrField, ReserveDoesntLoseAllocated) {
+ // Check that a bug is fixed: An earlier implementation of Reserve()
+ // failed to copy pointers to allocated-but-cleared objects, possibly
+ // leading to segfaults.
+ RepeatedPtrField<string> field;
+ string* first = field.Add();
+ field.RemoveLast();
+
+ field.Reserve(20);
+ EXPECT_EQ(first, field.Add());
+}
+
+// Clearing elements is tricky with RepeatedPtrFields since the memory for
+// the elements is retained and reused.
+TEST(RepeatedPtrField, ClearedElements) {
+ RepeatedPtrField<string> field;
+
+ string* original = field.Add();
+ *original = "foo";
+
+ EXPECT_EQ(field.ClearedCount(), 0);
+
+ field.RemoveLast();
+ EXPECT_TRUE(original->empty());
+ EXPECT_EQ(field.ClearedCount(), 1);
+
+ EXPECT_EQ(field.Add(), original); // Should return same string for reuse.
+
+ EXPECT_EQ(field.ReleaseLast(), original); // We take ownership.
+ EXPECT_EQ(field.ClearedCount(), 0);
+
+ EXPECT_NE(field.Add(), original); // Should NOT return the same string.
+ EXPECT_EQ(field.ClearedCount(), 0);
+
+ field.AddAllocated(original); // Give ownership back.
+ EXPECT_EQ(field.ClearedCount(), 0);
+ EXPECT_EQ(field.Mutable(1), original);
+
+ field.Clear();
+ EXPECT_EQ(field.ClearedCount(), 2);
+ EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again.
+ EXPECT_EQ(field.ClearedCount(), 1);
+ EXPECT_NE(field.Add(), original);
+ EXPECT_EQ(field.ClearedCount(), 0);
+ EXPECT_NE(field.Add(), original);
+ EXPECT_EQ(field.ClearedCount(), 0);
+
+ field.AddCleared(original); // Give ownership back, but as a cleared object.
+ EXPECT_EQ(field.ClearedCount(), 1);
+ EXPECT_EQ(field.Add(), original);
+ EXPECT_EQ(field.ClearedCount(), 0);
+}
+
+// Test all code paths in AddAllocated().
+TEST(RepeatedPtrField, AddAlocated) {
+ RepeatedPtrField<string> field;
+ while (field.size() < field.Capacity()) {
+ field.Add()->assign("filler");
+ }
+
+ int index = field.size();
+
+ // First branch: Field is at capacity with no cleared objects.
+ string* foo = new string("foo");
+ field.AddAllocated(foo);
+ EXPECT_EQ(index + 1, field.size());
+ EXPECT_EQ(0, field.ClearedCount());
+ EXPECT_EQ(foo, &field.Get(index));
+
+ // Last branch: Field is not at capacity and there are no cleared objects.
+ string* bar = new string("bar");
+ field.AddAllocated(bar);
+ ++index;
+ EXPECT_EQ(index + 1, field.size());
+ EXPECT_EQ(0, field.ClearedCount());
+ EXPECT_EQ(bar, &field.Get(index));
+
+ // Third branch: Field is not at capacity and there are no cleared objects.
+ field.RemoveLast();
+ string* baz = new string("baz");
+ field.AddAllocated(baz);
+ EXPECT_EQ(index + 1, field.size());
+ EXPECT_EQ(1, field.ClearedCount());
+ EXPECT_EQ(baz, &field.Get(index));
+
+ // Second branch: Field is at capacity but has some cleared objects.
+ while (field.size() < field.Capacity()) {
+ field.Add()->assign("filler2");
+ }
+ field.RemoveLast();
+ index = field.size();
+ string* qux = new string("qux");
+ field.AddAllocated(qux);
+ EXPECT_EQ(index + 1, field.size());
+ // We should have discarded the cleared object.
+ EXPECT_EQ(0, field.ClearedCount());
+ EXPECT_EQ(qux, &field.Get(index));
+}
+
+TEST(RepeatedPtrField, MergeFrom) {
+ RepeatedPtrField<string> source, destination;
+
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination.MergeFrom(source);
+
+ ASSERT_EQ(5, destination.size());
+
+ EXPECT_EQ("1", destination.Get(0));
+ EXPECT_EQ("2", destination.Get(1));
+ EXPECT_EQ("3", destination.Get(2));
+ EXPECT_EQ("4", destination.Get(3));
+ EXPECT_EQ("5", destination.Get(4));
+}
+
+TEST(RepeatedPtrField, CopyFrom) {
+ RepeatedPtrField<string> source, destination;
+
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination.CopyFrom(source);
+
+ ASSERT_EQ(2, destination.size());
+
+ EXPECT_EQ("4", destination.Get(0));
+ EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, CopyConstruct) {
+ RepeatedPtrField<string> source;
+
+ source.Add()->assign("1");
+ source.Add()->assign("2");
+
+ RepeatedPtrField<string> destination(source);
+
+ ASSERT_EQ(2, destination.size());
+ EXPECT_EQ("1", destination.Get(0));
+ EXPECT_EQ("2", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, CopyAssign) {
+ RepeatedPtrField<string> source, destination;
+
+ source.Add()->assign("4");
+ source.Add()->assign("5");
+
+ destination.Add()->assign("1");
+ destination.Add()->assign("2");
+ destination.Add()->assign("3");
+
+ destination = source;
+
+ ASSERT_EQ(2, destination.size());
+
+ EXPECT_EQ("4", destination.Get(0));
+ EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, MutableDataIsMutable) {
+ RepeatedPtrField<string> field;
+ *field.Add() = "1";
+ EXPECT_EQ("1", field.Get(0));
+ // The fact that this line compiles would be enough, but we'll check the
+ // value anyway.
+ string** data = field.mutable_data();
+ **data = "2";
+ EXPECT_EQ("2", field.Get(0));
+}
+
+// ===================================================================
+
+// Iterator tests stolen from net/proto/proto-array_unittest.
+class RepeatedFieldIteratorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ for (int i = 0; i < 3; ++i) {
+ proto_array_.Add(i);
+ }
+ }
+
+ RepeatedField<int> proto_array_;
+};
+
+TEST_F(RepeatedFieldIteratorTest, Convertible) {
+ RepeatedField<int>::iterator iter = proto_array_.begin();
+ RepeatedField<int>::const_iterator c_iter = iter;
+ RepeatedField<int>::value_type value = *c_iter;
+ EXPECT_EQ(0, value);
+}
+
+TEST_F(RepeatedFieldIteratorTest, MutableIteration) {
+ RepeatedField<int>::iterator iter = proto_array_.begin();
+ EXPECT_EQ(0, *iter);
+ ++iter;
+ EXPECT_EQ(1, *iter++);
+ EXPECT_EQ(2, *iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.end() == iter);
+
+ EXPECT_EQ(2, *(proto_array_.end() - 1));
+}
+
+TEST_F(RepeatedFieldIteratorTest, ConstIteration) {
+ const RepeatedField<int>& const_proto_array = proto_array_;
+ RepeatedField<int>::const_iterator iter = const_proto_array.begin();
+ EXPECT_EQ(0, *iter);
+ ++iter;
+ EXPECT_EQ(1, *iter++);
+ EXPECT_EQ(2, *iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.end() == iter);
+ EXPECT_EQ(2, *(proto_array_.end() - 1));
+}
+
+TEST_F(RepeatedFieldIteratorTest, Mutation) {
+ RepeatedField<int>::iterator iter = proto_array_.begin();
+ *iter = 7;
+ EXPECT_EQ(7, proto_array_.Get(0));
+}
+
+// -------------------------------------------------------------------
+
+class RepeatedPtrFieldIteratorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ proto_array_.Add()->assign("foo");
+ proto_array_.Add()->assign("bar");
+ proto_array_.Add()->assign("baz");
+ }
+
+ RepeatedPtrField<string> proto_array_;
+};
+
+TEST_F(RepeatedPtrFieldIteratorTest, Convertible) {
+ RepeatedPtrField<string>::iterator iter = proto_array_.begin();
+ RepeatedPtrField<string>::const_iterator c_iter = iter;
+ RepeatedPtrField<string>::value_type value = *c_iter;
+ EXPECT_EQ("foo", value);
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) {
+ RepeatedPtrField<string>::iterator iter = proto_array_.begin();
+ EXPECT_EQ("foo", *iter);
+ ++iter;
+ EXPECT_EQ("bar", *(iter++));
+ EXPECT_EQ("baz", *iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.end() == iter);
+ EXPECT_EQ("baz", *(--proto_array_.end()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, ConstIteration) {
+ const RepeatedPtrField<string>& const_proto_array = proto_array_;
+ RepeatedPtrField<string>::const_iterator iter = const_proto_array.begin();
+ EXPECT_EQ("foo", *iter);
+ ++iter;
+ EXPECT_EQ("bar", *(iter++));
+ EXPECT_EQ("baz", *iter);
+ ++iter;
+ EXPECT_TRUE(const_proto_array.end() == iter);
+ EXPECT_EQ("baz", *(--const_proto_array.end()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, RandomAccess) {
+ RepeatedPtrField<string>::iterator iter = proto_array_.begin();
+ RepeatedPtrField<string>::iterator iter2 = iter;
+ ++iter2;
+ ++iter2;
+ EXPECT_TRUE(iter + 2 == iter2);
+ EXPECT_TRUE(iter == iter2 - 2);
+ EXPECT_EQ("baz", iter[2]);
+ EXPECT_EQ("baz", *(iter + 2));
+ EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, Comparable) {
+ RepeatedPtrField<string>::const_iterator iter = proto_array_.begin();
+ RepeatedPtrField<string>::const_iterator iter2 = iter + 1;
+ EXPECT_TRUE(iter == iter);
+ EXPECT_TRUE(iter != iter2);
+ EXPECT_TRUE(iter < iter2);
+ EXPECT_TRUE(iter <= iter2);
+ EXPECT_TRUE(iter <= iter);
+ EXPECT_TRUE(iter2 > iter);
+ EXPECT_TRUE(iter2 >= iter);
+ EXPECT_TRUE(iter >= iter);
+}
+
+// Uninitialized iterator does not point to any of the RepeatedPtrField.
+TEST_F(RepeatedPtrFieldIteratorTest, UninitializedIterator) {
+ RepeatedPtrField<string>::iterator iter;
+ EXPECT_TRUE(iter != proto_array_.begin());
+ EXPECT_TRUE(iter != proto_array_.begin() + 1);
+ EXPECT_TRUE(iter != proto_array_.begin() + 2);
+ EXPECT_TRUE(iter != proto_array_.begin() + 3);
+ EXPECT_TRUE(iter != proto_array_.end());
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, STLAlgorithms_lower_bound) {
+ proto_array_.Clear();
+ proto_array_.Add()->assign("a");
+ proto_array_.Add()->assign("c");
+ proto_array_.Add()->assign("d");
+ proto_array_.Add()->assign("n");
+ proto_array_.Add()->assign("p");
+ proto_array_.Add()->assign("x");
+ proto_array_.Add()->assign("y");
+
+ string v = "f";
+ RepeatedPtrField<string>::const_iterator it =
+ lower_bound(proto_array_.begin(), proto_array_.end(), v);
+
+ EXPECT_EQ(*it, "n");
+ EXPECT_TRUE(it == proto_array_.begin() + 3);
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, Mutation) {
+ RepeatedPtrField<string>::iterator iter = proto_array_.begin();
+ *iter = "qux";
+ EXPECT_EQ("qux", proto_array_.Get(0));
+}
+
+// -------------------------------------------------------------------
+
+class RepeatedPtrFieldPtrsIteratorTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ proto_array_.Add()->assign("foo");
+ proto_array_.Add()->assign("bar");
+ proto_array_.Add()->assign("baz");
+ }
+
+ RepeatedPtrField<string> proto_array_;
+};
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) {
+ RepeatedPtrField<string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) {
+ RepeatedPtrField<string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ EXPECT_EQ("foo", **iter);
+ ++iter;
+ EXPECT_EQ("bar", **(iter++));
+ EXPECT_EQ("baz", **iter);
+ ++iter;
+ EXPECT_TRUE(proto_array_.pointer_end() == iter);
+ EXPECT_EQ("baz", **(--proto_array_.pointer_end()));
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) {
+ RepeatedPtrField<string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ RepeatedPtrField<string>::pointer_iterator iter2 = iter;
+ ++iter2;
+ ++iter2;
+ EXPECT_TRUE(iter + 2 == iter2);
+ EXPECT_TRUE(iter == iter2 - 2);
+ EXPECT_EQ("baz", *iter[2]);
+ EXPECT_EQ("baz", **(iter + 2));
+ EXPECT_EQ(3, proto_array_.end() - proto_array_.begin());
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) {
+ RepeatedPtrField<string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ RepeatedPtrField<string>::pointer_iterator iter2 = iter + 1;
+ EXPECT_TRUE(iter == iter);
+ EXPECT_TRUE(iter != iter2);
+ EXPECT_TRUE(iter < iter2);
+ EXPECT_TRUE(iter <= iter2);
+ EXPECT_TRUE(iter <= iter);
+ EXPECT_TRUE(iter2 > iter);
+ EXPECT_TRUE(iter2 >= iter);
+ EXPECT_TRUE(iter >= iter);
+}
+
+// Uninitialized iterator does not point to any of the RepeatedPtrOverPtrs.
+// Dereferencing an uninitialized iterator crashes the process.
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) {
+ RepeatedPtrField<string>::pointer_iterator iter;
+ EXPECT_TRUE(iter != proto_array_.pointer_begin());
+ EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1);
+ EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2);
+ EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3);
+ EXPECT_TRUE(iter != proto_array_.pointer_end());
+}
+
+
+// This comparison functor is required by the tests for RepeatedPtrOverPtrs.
+// They operate on strings and need to compare strings as strings in
+// any stl algorithm, even though the iterator returns a pointer to a string
+// - i.e. *iter has type string*.
+struct StringLessThan {
+ bool operator()(const string* z, const string& y) {
+ return *z < y;
+ }
+ bool operator()(const string* z, const string* y) {
+ return *z < *y;
+ }
+};
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_lower_bound) {
+ proto_array_.Clear();
+ proto_array_.Add()->assign("a");
+ proto_array_.Add()->assign("c");
+ proto_array_.Add()->assign("d");
+ proto_array_.Add()->assign("n");
+ proto_array_.Add()->assign("p");
+ proto_array_.Add()->assign("x");
+ proto_array_.Add()->assign("y");
+
+ RepeatedPtrField<string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ string v = "f";
+ RepeatedPtrField<string>::pointer_iterator it =
+ lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(),
+ &v, StringLessThan());
+
+ GOOGLE_CHECK(*it != NULL);
+
+ EXPECT_EQ(**it, "n");
+ EXPECT_TRUE(it == proto_array_.pointer_begin() + 3);
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) {
+ RepeatedPtrField<string>::pointer_iterator iter =
+ proto_array_.pointer_begin();
+ **iter = "qux";
+ EXPECT_EQ("qux", proto_array_.Get(0));
+
+ EXPECT_EQ("bar", proto_array_.Get(1));
+ EXPECT_EQ("baz", proto_array_.Get(2));
+ ++iter;
+ delete *iter;
+ *iter = new string("a");
+ ++iter;
+ delete *iter;
+ *iter = new string("b");
+ EXPECT_EQ("a", proto_array_.Get(1));
+ EXPECT_EQ("b", proto_array_.Get(2));
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) {
+ proto_array_.Add()->assign("c");
+ proto_array_.Add()->assign("d");
+ proto_array_.Add()->assign("n");
+ proto_array_.Add()->assign("p");
+ proto_array_.Add()->assign("a");
+ proto_array_.Add()->assign("y");
+ proto_array_.Add()->assign("x");
+ EXPECT_EQ("foo", proto_array_.Get(0));
+ EXPECT_EQ("n", proto_array_.Get(5));
+ EXPECT_EQ("x", proto_array_.Get(9));
+ sort(proto_array_.pointer_begin(),
+ proto_array_.pointer_end(),
+ StringLessThan());
+ EXPECT_EQ("a", proto_array_.Get(0));
+ EXPECT_EQ("baz", proto_array_.Get(2));
+ EXPECT_EQ("y", proto_array_.Get(9));
+}
+
+
+// -----------------------------------------------------------------------------
+// Unit-tests for the insert iterators
+// google::protobuf::RepeatedFieldBackInserter,
+// google::protobuf::AllocatedRepeatedPtrFieldBackInserter
+// Ported from util/gtl/proto-array-iterators_unittest.
+
+class RepeatedFieldInsertionIteratorsTest : public testing::Test {
+ protected:
+ std::list<double> halves;
+ std::list<int> fibonacci;
+ std::vector<string> words;
+ typedef TestAllTypes::NestedMessage Nested;
+ Nested nesteds[2];
+ std::vector<Nested*> nested_ptrs;
+ TestAllTypes protobuffer;
+
+ virtual void SetUp() {
+ fibonacci.push_back(1);
+ fibonacci.push_back(1);
+ fibonacci.push_back(2);
+ fibonacci.push_back(3);
+ fibonacci.push_back(5);
+ fibonacci.push_back(8);
+ std::copy(fibonacci.begin(), fibonacci.end(),
+ RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32()));
+
+ halves.push_back(1.0);
+ halves.push_back(0.5);
+ halves.push_back(0.25);
+ halves.push_back(0.125);
+ halves.push_back(0.0625);
+ std::copy(halves.begin(), halves.end(),
+ RepeatedFieldBackInserter(protobuffer.mutable_repeated_double()));
+
+ words.push_back("Able");
+ words.push_back("was");
+ words.push_back("I");
+ words.push_back("ere");
+ words.push_back("I");
+ words.push_back("saw");
+ words.push_back("Elba");
+ std::copy(words.begin(), words.end(),
+ RepeatedFieldBackInserter(protobuffer.mutable_repeated_string()));
+
+ nesteds[0].set_bb(17);
+ nesteds[1].set_bb(4711);
+ std::copy(&nesteds[0], &nesteds[2],
+ RepeatedFieldBackInserter(
+ protobuffer.mutable_repeated_nested_message()));
+
+ nested_ptrs.push_back(new Nested);
+ nested_ptrs.back()->set_bb(170);
+ nested_ptrs.push_back(new Nested);
+ nested_ptrs.back()->set_bb(47110);
+ std::copy(nested_ptrs.begin(), nested_ptrs.end(),
+ RepeatedFieldBackInserter(
+ protobuffer.mutable_repeated_nested_message()));
+
+ }
+
+ virtual void TearDown() {
+ STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end());
+ }
+};
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) {
+ EXPECT_TRUE(std::equal(fibonacci.begin(),
+ fibonacci.end(),
+ protobuffer.repeated_int32().begin()));
+ EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(),
+ protobuffer.repeated_int32().end(),
+ fibonacci.begin()));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) {
+ EXPECT_TRUE(std::equal(halves.begin(),
+ halves.end(),
+ protobuffer.repeated_double().begin()));
+ EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(),
+ protobuffer.repeated_double().end(),
+ halves.begin()));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Words) {
+ ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
+ EXPECT_EQ(words.at(0), protobuffer.repeated_string(0));
+ EXPECT_EQ(words.at(1), protobuffer.repeated_string(1));
+ EXPECT_EQ(words.at(2), protobuffer.repeated_string(2));
+ EXPECT_EQ(words.at(3), protobuffer.repeated_string(3));
+ EXPECT_EQ(words.at(4), protobuffer.repeated_string(4));
+ EXPECT_EQ(words.at(5), protobuffer.repeated_string(5));
+ EXPECT_EQ(words.at(6), protobuffer.repeated_string(6));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) {
+ ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4);
+ EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17);
+ EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711);
+ EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170);
+ EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110);
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+ AllocatedRepeatedPtrFieldWithStringIntData) {
+ vector<Nested*> data;
+ TestAllTypes goldenproto;
+ for (int i = 0; i < 10; ++i) {
+ Nested* new_data = new Nested;
+ new_data->set_bb(i);
+ data.push_back(new_data);
+
+ new_data = goldenproto.add_repeated_nested_message();
+ new_data->set_bb(i);
+ }
+ TestAllTypes testproto;
+ copy(data.begin(), data.end(),
+ AllocatedRepeatedPtrFieldBackInserter(
+ testproto.mutable_repeated_nested_message()));
+ EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+ AllocatedRepeatedPtrFieldWithString) {
+ vector<string*> data;
+ TestAllTypes goldenproto;
+ for (int i = 0; i < 10; ++i) {
+ string* new_data = new string;
+ *new_data = "name-" + SimpleItoa(i);
+ data.push_back(new_data);
+
+ new_data = goldenproto.add_repeated_string();
+ *new_data = "name-" + SimpleItoa(i);
+ }
+ TestAllTypes testproto;
+ copy(data.begin(), data.end(),
+ AllocatedRepeatedPtrFieldBackInserter(
+ testproto.mutable_repeated_string()));
+ EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
+}
+
+} // namespace
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/service.cc b/src/third_party/protobuf/src/google/protobuf/service.cc
new file mode 100644
index 0000000..caf968c
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/service.cc
@@ -0,0 +1,46 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/service.h>
+
+namespace google {
+namespace protobuf {
+
+Service::~Service() {}
+RpcChannel::~RpcChannel() {}
+RpcController::~RpcController() {}
+
+} // namespace protobuf
+
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/service.h b/src/third_party/protobuf/src/google/protobuf/service.h
new file mode 100644
index 0000000..a6a7d16
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/service.h
@@ -0,0 +1,291 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// DEPRECATED: This module declares the abstract interfaces underlying proto2
+// RPC services. These are intented to be independent of any particular RPC
+// implementation, so that proto2 services can be used on top of a variety
+// of implementations. Starting with version 2.3.0, RPC implementations should
+// not try to build on these, but should instead provide code generator plugins
+// which generate code specific to the particular RPC implementation. This way
+// the generated code can be more appropriate for the implementation in use
+// and can avoid unnecessary layers of indirection.
+//
+//
+// When you use the protocol compiler to compile a service definition, it
+// generates two classes: An abstract interface for the service (with
+// methods matching the service definition) and a "stub" implementation.
+// A stub is just a type-safe wrapper around an RpcChannel which emulates a
+// local implementation of the service.
+//
+// For example, the service definition:
+// service MyService {
+// rpc Foo(MyRequest) returns(MyResponse);
+// }
+// will generate abstract interface "MyService" and class "MyService::Stub".
+// You could implement a MyService as follows:
+// class MyServiceImpl : public MyService {
+// public:
+// MyServiceImpl() {}
+// ~MyServiceImpl() {}
+//
+// // implements MyService ---------------------------------------
+//
+// void Foo(google::protobuf::RpcController* controller,
+// const MyRequest* request,
+// MyResponse* response,
+// Closure* done) {
+// // ... read request and fill in response ...
+// done->Run();
+// }
+// };
+// You would then register an instance of MyServiceImpl with your RPC server
+// implementation. (How to do that depends on the implementation.)
+//
+// To call a remote MyServiceImpl, first you need an RpcChannel connected to it.
+// How to construct a channel depends, again, on your RPC implementation.
+// Here we use a hypothentical "MyRpcChannel" as an example:
+// MyRpcChannel channel("rpc:hostname:1234/myservice");
+// MyRpcController controller;
+// MyServiceImpl::Stub stub(&channel);
+// FooRequest request;
+// FooRespnose response;
+//
+// // ... fill in request ...
+//
+// stub.Foo(&controller, request, &response, NewCallback(HandleResponse));
+//
+// On Thread-Safety:
+//
+// Different RPC implementations may make different guarantees about what
+// threads they may run callbacks on, and what threads the application is
+// allowed to use to call the RPC system. Portable software should be ready
+// for callbacks to be called on any thread, but should not try to call the
+// RPC system from any thread except for the ones on which it received the
+// callbacks. Realistically, though, simple software will probably want to
+// use a single-threaded RPC system while high-end software will want to
+// use multiple threads. RPC implementations should provide multiple
+// choices.
+
+#ifndef GOOGLE_PROTOBUF_SERVICE_H__
+#define GOOGLE_PROTOBUF_SERVICE_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class Service;
+class RpcController;
+class RpcChannel;
+
+// Defined in other files.
+class Descriptor; // descriptor.h
+class ServiceDescriptor; // descriptor.h
+class MethodDescriptor; // descriptor.h
+class Message; // message.h
+
+// Abstract base interface for protocol-buffer-based RPC services. Services
+// themselves are abstract interfaces (implemented either by servers or as
+// stubs), but they subclass this base interface. The methods of this
+// interface can be used to call the methods of the Service without knowing
+// its exact type at compile time (analogous to Reflection).
+class LIBPROTOBUF_EXPORT Service {
+ public:
+ inline Service() {}
+ virtual ~Service();
+
+ // When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second
+ // parameter to the constructor to tell it to delete its RpcChannel when
+ // destroyed.
+ enum ChannelOwnership {
+ STUB_OWNS_CHANNEL,
+ STUB_DOESNT_OWN_CHANNEL
+ };
+
+ // Get the ServiceDescriptor describing this service and its methods.
+ virtual const ServiceDescriptor* GetDescriptor() = 0;
+
+ // Call a method of the service specified by MethodDescriptor. This is
+ // normally implemented as a simple switch() that calls the standard
+ // definitions of the service's methods.
+ //
+ // Preconditions:
+ // * method->service() == GetDescriptor()
+ // * request and response are of the exact same classes as the objects
+ // returned by GetRequestPrototype(method) and
+ // GetResponsePrototype(method).
+ // * After the call has started, the request must not be modified and the
+ // response must not be accessed at all until "done" is called.
+ // * "controller" is of the correct type for the RPC implementation being
+ // used by this Service. For stubs, the "correct type" depends on the
+ // RpcChannel which the stub is using. Server-side Service
+ // implementations are expected to accept whatever type of RpcController
+ // the server-side RPC implementation uses.
+ //
+ // Postconditions:
+ // * "done" will be called when the method is complete. This may be
+ // before CallMethod() returns or it may be at some point in the future.
+ // * If the RPC succeeded, "response" contains the response returned by
+ // the server.
+ // * If the RPC failed, "response"'s contents are undefined. The
+ // RpcController can be queried to determine if an error occurred and
+ // possibly to get more information about the error.
+ virtual void CallMethod(const MethodDescriptor* method,
+ RpcController* controller,
+ const Message* request,
+ Message* response,
+ Closure* done) = 0;
+
+ // CallMethod() requires that the request and response passed in are of a
+ // particular subclass of Message. GetRequestPrototype() and
+ // GetResponsePrototype() get the default instances of these required types.
+ // You can then call Message::New() on these instances to construct mutable
+ // objects which you can then pass to CallMethod().
+ //
+ // Example:
+ // const MethodDescriptor* method =
+ // service->GetDescriptor()->FindMethodByName("Foo");
+ // Message* request = stub->GetRequestPrototype (method)->New();
+ // Message* response = stub->GetResponsePrototype(method)->New();
+ // request->ParseFromString(input);
+ // service->CallMethod(method, *request, response, callback);
+ virtual const Message& GetRequestPrototype(
+ const MethodDescriptor* method) const = 0;
+ virtual const Message& GetResponsePrototype(
+ const MethodDescriptor* method) const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service);
+};
+
+// An RpcController mediates a single method call. The primary purpose of
+// the controller is to provide a way to manipulate settings specific to the
+// RPC implementation and to find out about RPC-level errors.
+//
+// The methods provided by the RpcController interface are intended to be a
+// "least common denominator" set of features which we expect all
+// implementations to support. Specific implementations may provide more
+// advanced features (e.g. deadline propagation).
+class LIBPROTOBUF_EXPORT RpcController {
+ public:
+ inline RpcController() {}
+ virtual ~RpcController();
+
+ // Client-side methods ---------------------------------------------
+ // These calls may be made from the client side only. Their results
+ // are undefined on the server side (may crash).
+
+ // Resets the RpcController to its initial state so that it may be reused in
+ // a new call. Must not be called while an RPC is in progress.
+ virtual void Reset() = 0;
+
+ // After a call has finished, returns true if the call failed. The possible
+ // reasons for failure depend on the RPC implementation. Failed() must not
+ // be called before a call has finished. If Failed() returns true, the
+ // contents of the response message are undefined.
+ virtual bool Failed() const = 0;
+
+ // If Failed() is true, returns a human-readable description of the error.
+ virtual string ErrorText() const = 0;
+
+ // Advises the RPC system that the caller desires that the RPC call be
+ // canceled. The RPC system may cancel it immediately, may wait awhile and
+ // then cancel it, or may not even cancel the call at all. If the call is
+ // canceled, the "done" callback will still be called and the RpcController
+ // will indicate that the call failed at that time.
+ virtual void StartCancel() = 0;
+
+ // Server-side methods ---------------------------------------------
+ // These calls may be made from the server side only. Their results
+ // are undefined on the client side (may crash).
+
+ // Causes Failed() to return true on the client side. "reason" will be
+ // incorporated into the message returned by ErrorText(). If you find
+ // you need to return machine-readable information about failures, you
+ // should incorporate it into your response protocol buffer and should
+ // NOT call SetFailed().
+ virtual void SetFailed(const string& reason) = 0;
+
+ // If true, indicates that the client canceled the RPC, so the server may
+ // as well give up on replying to it. The server should still call the
+ // final "done" callback.
+ virtual bool IsCanceled() const = 0;
+
+ // Asks that the given callback be called when the RPC is canceled. The
+ // callback will always be called exactly once. If the RPC completes without
+ // being canceled, the callback will be called after completion. If the RPC
+ // has already been canceled when NotifyOnCancel() is called, the callback
+ // will be called immediately.
+ //
+ // NotifyOnCancel() must be called no more than once per request.
+ virtual void NotifyOnCancel(Closure* callback) = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController);
+};
+
+// Abstract interface for an RPC channel. An RpcChannel represents a
+// communication line to a Service which can be used to call that Service's
+// methods. The Service may be running on another machine. Normally, you
+// should not call an RpcChannel directly, but instead construct a stub Service
+// wrapping it. Example:
+// RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234");
+// MyService* service = new MyService::Stub(channel);
+// service->MyMethod(request, &response, callback);
+class LIBPROTOBUF_EXPORT RpcChannel {
+ public:
+ inline RpcChannel() {}
+ virtual ~RpcChannel();
+
+ // Call the given method of the remote service. The signature of this
+ // procedure looks the same as Service::CallMethod(), but the requirements
+ // are less strict in one important way: the request and response objects
+ // need not be of any specific class as long as their descriptors are
+ // method->input_type() and method->output_type().
+ virtual void CallMethod(const MethodDescriptor* method,
+ RpcController* controller,
+ const Message* request,
+ Message* response,
+ Closure* done) = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel);
+};
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_SERVICE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops.h b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops.h
new file mode 100644
index 0000000..3ace767
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops.h
@@ -0,0 +1,208 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The routines exported by this module are subtle. If you use them, even if
+// you get the code right, it will depend on careful reasoning about atomicity
+// and memory ordering; it will be less readable, and harder to maintain. If
+// you plan to use these routines, you should have a good reason, such as solid
+// evidence that performance would otherwise suffer, or there being no
+// alternative. You should assume only properties explicitly guaranteed by the
+// specifications in this file. You are almost certainly _not_ writing code
+// just for the x86; if you assume x86 semantics, x86 hardware bugs and
+// implementations on other archtectures will cause your code to break. If you
+// do not know what you are doing, avoid these routines, and use a Mutex.
+//
+// It is incorrect to make direct assignments to/from an atomic variable.
+// You should use one of the Load or Store routines. The NoBarrier
+// versions are provided when no barriers are needed:
+// NoBarrier_Store()
+// NoBarrier_Load()
+// Although there are currently no compiler enforcement, you are encouraged
+// to use these.
+
+// This header and the implementations for each platform (located in
+// atomicops_internals_*) must be kept in sync with the upstream code (V8).
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_H_
+
+// Don't include this file for people not concerned about thread safety.
+#ifndef GOOGLE_PROTOBUF_NO_THREADSAFETY
+
+#include <google/protobuf/stubs/platform_macros.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+typedef int32 Atomic32;
+#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
+// We need to be able to go between Atomic64 and AtomicWord implicitly. This
+// means Atomic64 and AtomicWord should be the same type on 64-bit.
+#if defined(GOOGLE_PROTOBUF_OS_NACL)
+// NaCl's intptr_t is not actually 64-bits on 64-bit!
+// http://code.google.com/p/nativeclient/issues/detail?id=1162
+typedef int64 Atomic64;
+#else
+typedef intptr_t Atomic64;
+#endif
+#endif
+
+// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or
+// Atomic64 routines below, depending on your architecture.
+typedef intptr_t AtomicWord;
+
+// Atomically execute:
+// result = *ptr;
+// if (*ptr == old_value)
+// *ptr = new_value;
+// return result;
+//
+// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+// Always return the old value of "*ptr"
+//
+// This routine implies no memory barriers.
+Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr. This routine implies no memory barriers.
+Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
+
+// Atomically increment *ptr by "increment". Returns the new value of
+// *ptr with the increment applied. This routine implies no memory barriers.
+Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
+
+Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment);
+
+// These following lower-level operations are typically useful only to people
+// implementing higher-level synchronization operations like spinlocks,
+// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or
+// a store with appropriate memory-ordering instructions. "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation. "Barrier" operations have both "Acquire" and "Release"
+// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+
+void MemoryBarrier();
+void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
+void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
+void Release_Store(volatile Atomic32* ptr, Atomic32 value);
+
+Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
+Atomic32 Acquire_Load(volatile const Atomic32* ptr);
+Atomic32 Release_Load(volatile const Atomic32* ptr);
+
+// 64-bit atomic operations (only available on 64-bit processors).
+#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
+Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value);
+Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
+Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
+Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
+
+Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value);
+Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value);
+void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
+void Acquire_Store(volatile Atomic64* ptr, Atomic64 value);
+void Release_Store(volatile Atomic64* ptr, Atomic64 value);
+Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
+Atomic64 Acquire_Load(volatile const Atomic64* ptr);
+Atomic64 Release_Load(volatile const Atomic64* ptr);
+#endif // GOOGLE_PROTOBUF_ARCH_64_BIT
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+// Include our platform specific implementation.
+#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \
+#error "Atomic operations are not supported on your platform"
+
+// MSVC.
+#if defined(_MSC_VER)
+#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
+#include <google/protobuf/stubs/atomicops_internals_x86_msvc.h>
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// Apple.
+#elif defined(GOOGLE_PROTOBUF_OS_APPLE)
+#include <google/protobuf/stubs/atomicops_internals_macosx.h>
+
+// LB shell platforms that don't fit any of the existing atomicops_internals_XXX
+#elif (defined(__LB_PS3__) || defined(__LB_WIIU__)) && !defined(__LB_HOST__)
+#define SHELL_BEGIN_ATOMICOPS_NAMESPACES namespace google { namespace protobuf { namespace internal {
+#define SHELL_END_ATOMICOPS_NAMESPACES } } }
+#include "atomicops_internals_shell.h" // from the platform lib
+
+// GCC.
+#elif defined(__GNUC__)
+#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
+#include <google/protobuf/stubs/atomicops_internals_x86_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_ARM)
+#include <google/protobuf/stubs/atomicops_internals_arm_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS)
+#include <google/protobuf/stubs/atomicops_internals_mips_gcc.h>
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// Unknown.
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// On some platforms we need additional declarations to make AtomicWord
+// compatible with our other Atomic* types.
+#if defined(GOOGLE_PROTOBUF_OS_APPLE)
+#include <google/protobuf/stubs/atomicops_internals_atomicword_compat.h>
+#endif
+
+#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+
+#endif // GOOGLE_PROTOBUF_NO_THREADSAFETY
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
new file mode 100644
index 0000000..1f4dedc
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
@@ -0,0 +1,151 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+//
+// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// 0xffff0fc0 is the hard coded address of a function provided by
+// the kernel which implements an atomic compare-exchange. On older
+// ARM architecture revisions (pre-v6) this may be implemented using
+// a syscall. This address is stable, and in active use (hard coded)
+// by at least glibc-2.7 and the Android C library.
+typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
+ Atomic32 new_value,
+ volatile Atomic32* ptr);
+LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) =
+ (LinuxKernelCmpxchgFunc) 0xffff0fc0;
+
+typedef void (*LinuxKernelMemoryBarrierFunc)(void);
+LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
+ (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
+
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value = *ptr;
+ do {
+ if (!pLinuxKernelCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 old_value;
+ do {
+ old_value = *ptr;
+ } while (pLinuxKernelCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr)));
+ return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ for (;;) {
+ // Atomic exchange the old value with an incremented one.
+ Atomic32 old_value = *ptr;
+ Atomic32 new_value = old_value + increment;
+ if (pLinuxKernelCmpxchg(old_value, new_value,
+ const_cast<Atomic32*>(ptr)) == 0) {
+ // The exchange took place as expected.
+ return new_value;
+ }
+ // Otherwise, *ptr changed mid-loop and we need to retry.
+ }
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void MemoryBarrier() {
+ pLinuxKernelMemoryBarrier();
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
new file mode 100644
index 0000000..e9d8679
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
+
+// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32,
+// which in turn means int. On some LP32 platforms, intptr_t is an int, but
+// on others, it's a long. When AtomicWord and Atomic32 are based on different
+// fundamental types, their pointers are incompatible.
+//
+// This file defines function overloads to allow both AtomicWord and Atomic32
+// data to be used with this interface.
+//
+// On LP64 platforms, AtomicWord and Atomic64 are both always long,
+// so this problem doesn't occur.
+
+#if !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return NoBarrier_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
+ AtomicWord new_value) {
+ return NoBarrier_AtomicExchange(
+ reinterpret_cast<volatile Atomic32*>(ptr), new_value);
+}
+
+inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
+ AtomicWord increment) {
+ return NoBarrier_AtomicIncrement(
+ reinterpret_cast<volatile Atomic32*>(ptr), increment);
+}
+
+inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
+ AtomicWord increment) {
+ return Barrier_AtomicIncrement(
+ reinterpret_cast<volatile Atomic32*>(ptr), increment);
+}
+
+inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return Acquire_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return Release_CompareAndSwap(
+ reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
+ NoBarrier_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ return Acquire_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ return Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
+ return NoBarrier_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
+ return Acquire_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
+ return Release_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h
new file mode 100644
index 0000000..f9b7581
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h
@@ -0,0 +1,225 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
+
+#include <libkern/OSAtomic.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap32(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 old_value;
+ do {
+ old_value = *ptr;
+ } while (!OSAtomicCompareAndSwap32(old_value, new_value,
+ const_cast<Atomic32*>(ptr)));
+ return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
+}
+
+inline void MemoryBarrier() {
+ OSMemoryBarrier();
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return Acquire_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#ifdef __LP64__
+
+// 64-bit implementation on 64-bit platform
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap64(old_value, new_value,
+ reinterpret_cast<volatile int64_t*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ Atomic64 old_value;
+ do {
+ old_value = *ptr;
+ } while (!OSAtomicCompareAndSwap64(old_value, new_value,
+ reinterpret_cast<volatile int64_t*>(ptr)));
+ return old_value;
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr));
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return OSAtomicAdd64Barrier(increment,
+ reinterpret_cast<volatile int64_t*>(ptr));
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap64Barrier(
+ old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ // The lib kern interface does not distinguish between
+ // Acquire and Release memory barriers; they are equivalent.
+ return Acquire_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#endif // defined(__LP64__)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
new file mode 100644
index 0000000..dc46851
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
@@ -0,0 +1,187 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Atomically execute:
+// result = *ptr;
+// if (*ptr == old_value)
+// *ptr = new_value;
+// return result;
+//
+// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+// Always return the old value of "*ptr"
+//
+// This routine implies no memory barriers.
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev, tmp;
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "ll %0, %5\n" // prev = *ptr
+ "bne %0, %3, 2f\n" // if (prev != old_value) goto 2
+ "move %2, %4\n" // tmp = new_value
+ "sc %2, %1\n" // *ptr = tmp (with atomic check)
+ "beqz %2, 1b\n" // start again on atomic error
+ "nop\n" // delay slot nop
+ "2:\n"
+ ".set pop\n"
+ : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
+ : "Ir" (old_value), "r" (new_value), "m" (*ptr)
+ : "memory");
+ return prev;
+}
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr. This routine implies no memory barriers.
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 temp, old;
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "ll %1, %2\n" // old = *ptr
+ "move %0, %3\n" // temp = new_value
+ "sc %0, %2\n" // *ptr = temp (with atomic check)
+ "beqz %0, 1b\n" // start again on atomic error
+ "nop\n" // delay slot nop
+ ".set pop\n"
+ : "=&r" (temp), "=&r" (old), "=m" (*ptr)
+ : "r" (new_value), "m" (*ptr)
+ : "memory");
+
+ return old;
+}
+
+// Atomically increment *ptr by "increment". Returns the new value of
+// *ptr with the increment applied. This routine implies no memory barriers.
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ Atomic32 temp, temp2;
+
+ __asm__ __volatile__(".set push\n"
+ ".set noreorder\n"
+ "1:\n"
+ "ll %0, %2\n" // temp = *ptr
+ "addu %1, %0, %3\n" // temp2 = temp + increment
+ "sc %1, %2\n" // *ptr = temp2 (with atomic check)
+ "beqz %1, 1b\n" // start again on atomic error
+ "addu %1, %0, %3\n" // temp2 = temp + increment
+ ".set pop\n"
+ : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
+ : "Ir" (increment), "m" (*ptr)
+ : "memory");
+ // temp2 now holds the final value.
+ return temp2;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ ATOMICOPS_COMPILER_BARRIER();
+ Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment);
+ ATOMICOPS_COMPILER_BARRIER();
+ return res;
+}
+
+// "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation. "Barrier" operations have both "Acquire" and "Release"
+// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ ATOMICOPS_COMPILER_BARRIER();
+ Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ ATOMICOPS_COMPILER_BARRIER();
+ return res;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ ATOMICOPS_COMPILER_BARRIER();
+ Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ ATOMICOPS_COMPILER_BARRIER();
+ return res;
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void MemoryBarrier() {
+ __asm__ __volatile__("sync" : : : "memory");
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
new file mode 100644
index 0000000..0774872
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
@@ -0,0 +1,137 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This module gets enough CPU information to optimize the
+// atomicops module on x86.
+
+#include <cstring>
+
+#include <google/protobuf/stubs/atomicops.h>
+
+// This file only makes sense with atomicops_internals_x86_gcc.h -- it
+// depends on structs that are defined in that file. If atomicops.h
+// doesn't sub-include that file, then we aren't needed, and shouldn't
+// try to do anything.
+#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+
+// Inline cpuid instruction. In PIC compilations, %ebx contains the address
+// of the global offset table. To avoid breaking such executables, this code
+// must preserve that register's value across cpuid instructions.
+#if defined(__i386__)
+#define cpuid(a, b, c, d, inp) \
+ asm("mov %%ebx, %%edi\n" \
+ "cpuid\n" \
+ "xchg %%edi, %%ebx\n" \
+ : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+#elif defined(__x86_64__)
+#define cpuid(a, b, c, d, inp) \
+ asm("mov %%rbx, %%rdi\n" \
+ "cpuid\n" \
+ "xchg %%rdi, %%rbx\n" \
+ : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+#endif
+
+#if defined(cpuid) // initialize the struct only on x86
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Set the flags so that code will run correctly and conservatively, so even
+// if we haven't been initialized yet, we're probably single threaded, and our
+// default values should hopefully be pretty safe.
+struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
+ false, // bug can't exist before process spawns multiple threads
+ false, // no SSE2
+};
+
+namespace {
+
+// Initialize the AtomicOps_Internalx86CPUFeatures struct.
+void AtomicOps_Internalx86CPUFeaturesInit() {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+
+ // Get vendor string (issue CPUID with eax = 0)
+ cpuid(eax, ebx, ecx, edx, 0);
+ char vendor[13];
+ memcpy(vendor, &ebx, 4);
+ memcpy(vendor + 4, &edx, 4);
+ memcpy(vendor + 8, &ecx, 4);
+ vendor[12] = 0;
+
+ // get feature flags in ecx/edx, and family/model in eax
+ cpuid(eax, ebx, ecx, edx, 1);
+
+ int family = (eax >> 8) & 0xf; // family and model fields
+ int model = (eax >> 4) & 0xf;
+ if (family == 0xf) { // use extended family and model fields
+ family += (eax >> 20) & 0xff;
+ model += ((eax >> 16) & 0xf) << 4;
+ }
+
+ // Opteron Rev E has a bug in which on very rare occasions a locked
+ // instruction doesn't act as a read-acquire barrier if followed by a
+ // non-locked read-modify-write instruction. Rev F has this bug in
+ // pre-release versions, but not in versions released to customers,
+ // so we test only for Rev E, which is family 15, model 32..63 inclusive.
+ if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD
+ family == 15 &&
+ 32 <= model && model <= 63) {
+ AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
+ } else {
+ AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
+ }
+
+ // edx bit 26 is SSE2 which we use to tell use whether we can use mfence
+ AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
+}
+
+class AtomicOpsx86Initializer {
+ public:
+ AtomicOpsx86Initializer() {
+ AtomicOps_Internalx86CPUFeaturesInit();
+ }
+};
+
+// A global to get use initialized on startup via static initialization :/
+AtomicOpsx86Initializer g_initer;
+
+} // namespace
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // __i386__
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
new file mode 100644
index 0000000..5324dfb
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
@@ -0,0 +1,293 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// This struct is not part of the public API of this module; clients may not
+// use it.
+// Features of this x86. Values may not be correct before main() is run,
+// but are set conservatively.
+struct AtomicOps_x86CPUFeatureStruct {
+ bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence
+ // after acquire compare-and-swap.
+ bool has_sse2; // Processor has SSE2.
+};
+extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+// 32-bit low-level operations on any platform.
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev;
+ __asm__ __volatile__("lock; cmpxchgl %1,%2"
+ : "=a" (prev)
+ : "q" (new_value), "m" (*ptr), "0" (old_value)
+ : "memory");
+ return prev;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ __asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg.
+ : "=r" (new_value)
+ : "m" (*ptr), "0" (new_value)
+ : "memory");
+ return new_value; // Now it's the previous value.
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ Atomic32 temp = increment;
+ __asm__ __volatile__("lock; xaddl %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now holds the old value of *ptr
+ return temp + increment;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ Atomic32 temp = increment;
+ __asm__ __volatile__("lock; xaddl %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now holds the old value of *ptr
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return temp + increment;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return x;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+#if defined(__x86_64__)
+
+// 64-bit implementations of memory barrier can be simpler, because it
+// "mfence" is guaranteed to exist.
+inline void MemoryBarrier() {
+ __asm__ __volatile__("mfence" : : : "memory");
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+#else
+
+inline void MemoryBarrier() {
+ if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
+ __asm__ __volatile__("mfence" : : : "memory");
+ } else { // mfence is faster but not present on PIII
+ Atomic32 x = 0;
+ NoBarrier_AtomicExchange(&x, 0); // acts as a barrier on PIII
+ }
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
+ *ptr = value;
+ __asm__ __volatile__("mfence" : : : "memory");
+ } else {
+ NoBarrier_AtomicExchange(ptr, value);
+ // acts as a barrier on PIII
+ }
+}
+#endif
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ ATOMICOPS_COMPILER_BARRIER();
+ *ptr = value; // An x86 store acts as a release barrier.
+ // See comments in Atomic64 version of Release_Store(), below.
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr; // An x86 load acts as a acquire barrier.
+ // See comments in Atomic64 version of Release_Store(), below.
+ ATOMICOPS_COMPILER_BARRIER();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#if defined(__x86_64__)
+
+// 64-bit low-level operations on 64-bit platform.
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 prev;
+ __asm__ __volatile__("lock; cmpxchgq %1,%2"
+ : "=a" (prev)
+ : "q" (new_value), "m" (*ptr), "0" (old_value)
+ : "memory");
+ return prev;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ __asm__ __volatile__("xchgq %1,%0" // The lock prefix is implicit for xchg.
+ : "=r" (new_value)
+ : "m" (*ptr), "0" (new_value)
+ : "memory");
+ return new_value; // Now it's the previous value.
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ Atomic64 temp = increment;
+ __asm__ __volatile__("lock; xaddq %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now contains the previous value of *ptr
+ return temp + increment;
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ Atomic64 temp = increment;
+ __asm__ __volatile__("lock; xaddq %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now contains the previous value of *ptr
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return temp + increment;
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ ATOMICOPS_COMPILER_BARRIER();
+
+ *ptr = value; // An x86 store acts as a release barrier
+ // for current AMD/Intel chips as of Jan 2008.
+ // See also Acquire_Load(), below.
+
+ // When new chips come out, check:
+ // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+ // System Programming Guide, Chatper 7: Multiple-processor management,
+ // Section 7.2, Memory Ordering.
+ // Last seen at:
+ // http://developer.intel.com/design/pentium4/manuals/index_new.htm
+ //
+ // x86 stores/loads fail to act as barriers for a few instructions (clflush
+ // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
+ // not generated by the compiler, and are rare. Users of these instructions
+ // need to know about cache behaviour in any case since all of these involve
+ // either flushing cache lines or non-temporal cache hints.
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,
+ // for current AMD/Intel chips as of Jan 2008.
+ // See also Release_Store(), above.
+ ATOMICOPS_COMPILER_BARRIER();
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return x;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+#endif // defined(__x86_64__)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
new file mode 100644
index 0000000..8366a89
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
@@ -0,0 +1,112 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The compilation of extension_set.cc fails when windows.h is included.
+// Therefore we move the code depending on windows.h to this separate cc file.
+
+// Don't compile this file for people not concerned about thread safety.
+#ifndef GOOGLE_PROTOBUF_NO_THREADSAFETY
+
+#include <google/protobuf/stubs/atomicops.h>
+
+#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+
+#include <windows.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline void MemoryBarrier() {
+ // We use MemoryBarrier from WinNT.h
+ ::MemoryBarrier();
+}
+
+Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ LONG result = InterlockedCompareExchange(
+ reinterpret_cast<volatile LONG*>(ptr),
+ static_cast<LONG>(new_value),
+ static_cast<LONG>(old_value));
+ return static_cast<Atomic32>(result);
+}
+
+Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ LONG result = InterlockedExchange(
+ reinterpret_cast<volatile LONG*>(ptr),
+ static_cast<LONG>(new_value));
+ return static_cast<Atomic32>(result);
+}
+
+Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return InterlockedExchangeAdd(
+ reinterpret_cast<volatile LONG*>(ptr),
+ static_cast<LONG>(increment)) + increment;
+}
+
+#if defined(_WIN64)
+
+// 64-bit low-level operations on 64-bit platform.
+
+Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ PVOID result = InterlockedCompareExchangePointer(
+ reinterpret_cast<volatile PVOID*>(ptr),
+ reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
+ return reinterpret_cast<Atomic64>(result);
+}
+
+Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ PVOID result = InterlockedExchangePointer(
+ reinterpret_cast<volatile PVOID*>(ptr),
+ reinterpret_cast<PVOID>(new_value));
+ return reinterpret_cast<Atomic64>(result);
+}
+
+Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return InterlockedExchangeAdd64(
+ reinterpret_cast<volatile LONGLONG*>(ptr),
+ static_cast<LONGLONG>(increment)) + increment;
+}
+
+#endif // defined(_WIN64)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+#endif // GOOGLE_PROTOBUF_NO_THREADSAFETY
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
new file mode 100644
index 0000000..6f9869d
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
@@ -0,0 +1,150 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return Barrier_AtomicIncrement(ptr, increment);
+}
+
+#if !(defined(_MSC_VER) && _MSC_VER >= 1400)
+#error "We require at least vs2005 for MemoryBarrier"
+#endif
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ NoBarrier_AtomicExchange(ptr, value);
+ // acts as a barrier in this implementation
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value; // works w/o barrier for current Intel chips as of June 2005
+ // See comments in Atomic64 version of Release_Store() below.
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#if defined(_WIN64)
+
+// 64-bit low-level operations on 64-bit platform.
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+ NoBarrier_AtomicExchange(ptr, value);
+ // acts as a barrier in this implementation
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+ *ptr = value; // works w/o barrier for current Intel chips as of June 2005
+
+ // When new chips come out, check:
+ // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+ // System Programming Guide, Chatper 7: Multiple-processor management,
+ // Section 7.2, Memory Ordering.
+ // Last seen at:
+ // http://developer.intel.com/design/pentium4/manuals/index_new.htm
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+ Atomic64 value = *ptr;
+ return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+#endif // defined(_WIN64)
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/common.cc b/src/third_party/protobuf/src/google/protobuf/stubs/common.cc
new file mode 100644
index 0000000..7b15be4
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/common.cc
@@ -0,0 +1,377 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <stdio.h>
+#include <errno.h>
+#include <vector>
+
+#include "config.h"
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN // We only need minimal includes
+#include <windows.h>
+#define snprintf _snprintf // see comment in strutil.cc
+#elif defined(HAVE_PTHREAD)
+#include <pthread.h>
+#else
+#error "No suitable threading library available."
+#endif
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+void VerifyVersion(int headerVersion,
+ int minLibraryVersion,
+ const char* filename) {
+ if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) {
+ // Library is too old for headers.
+ GOOGLE_LOG(FATAL)
+ << "This program requires version " << VersionString(minLibraryVersion)
+ << " of the Protocol Buffer runtime library, but the installed version "
+ "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update "
+ "your library. If you compiled the program yourself, make sure that "
+ "your headers are from the same version of Protocol Buffers as your "
+ "link-time library. (Version verification failed in \""
+ << filename << "\".)";
+ }
+ if (headerVersion < kMinHeaderVersionForLibrary) {
+ // Headers are too old for library.
+ GOOGLE_LOG(FATAL)
+ << "This program was compiled against version "
+ << VersionString(headerVersion) << " of the Protocol Buffer runtime "
+ "library, which is not compatible with the installed version ("
+ << VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program "
+ "author for an update. If you compiled the program yourself, make "
+ "sure that your headers are from the same version of Protocol Buffers "
+ "as your link-time library. (Version verification failed in \""
+ << filename << "\".)";
+ }
+}
+
+string VersionString(int version) {
+ int major = version / 1000000;
+ int minor = (version / 1000) % 1000;
+ int micro = version % 1000;
+
+ // 128 bytes should always be enough, but we use snprintf() anyway to be
+ // safe.
+ char buffer[128];
+ snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro);
+
+ // Guard against broken MSVC snprintf().
+ buffer[sizeof(buffer)-1] = '\0';
+
+ return buffer;
+}
+
+} // namespace internal
+
+// ===================================================================
+// emulates google3/base/logging.cc
+
+namespace internal {
+
+void DefaultLogHandler(LogLevel level, const char* filename, int line,
+ const string& message) {
+ static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
+
+ // We use fprintf() instead of cerr because we want this to work at static
+ // initialization time.
+ fprintf(stderr, "libprotobuf %s %s:%d] %s\n",
+ level_names[level], filename, line, message.c_str());
+ fflush(stderr); // Needed on MSVC.
+}
+
+void NullLogHandler(LogLevel level, const char* filename, int line,
+ const string& message) {
+ // Nothing.
+}
+
+static LogHandler* log_handler_ = &DefaultLogHandler;
+static int log_silencer_count_ = 0;
+
+static Mutex* log_silencer_count_mutex_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_);
+
+void DeleteLogSilencerCount() {
+ delete log_silencer_count_mutex_;
+ log_silencer_count_mutex_ = NULL;
+}
+void InitLogSilencerCount() {
+ log_silencer_count_mutex_ = new Mutex;
+ OnShutdown(&DeleteLogSilencerCount);
+}
+void InitLogSilencerCountOnce() {
+ GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount);
+}
+
+LogMessage& LogMessage::operator<<(const string& value) {
+ message_ += value;
+ return *this;
+}
+
+LogMessage& LogMessage::operator<<(const char* value) {
+ message_ += value;
+ return *this;
+}
+
+// Since this is just for logging, we don't care if the current locale changes
+// the results -- in fact, we probably prefer that. So we use snprintf()
+// instead of Simple*toa().
+#undef DECLARE_STREAM_OPERATOR
+#define DECLARE_STREAM_OPERATOR(TYPE, FORMAT) \
+ LogMessage& LogMessage::operator<<(TYPE value) { \
+ /* 128 bytes should be big enough for any of the primitive */ \
+ /* values which we print with this, but well use snprintf() */ \
+ /* anyway to be extra safe. */ \
+ char buffer[128]; \
+ snprintf(buffer, sizeof(buffer), FORMAT, value); \
+ /* Guard against broken MSVC snprintf(). */ \
+ buffer[sizeof(buffer)-1] = '\0'; \
+ message_ += buffer; \
+ return *this; \
+ }
+
+DECLARE_STREAM_OPERATOR(char , "%c" )
+DECLARE_STREAM_OPERATOR(int , "%d" )
+DECLARE_STREAM_OPERATOR(uint , "%u" )
+DECLARE_STREAM_OPERATOR(long , "%ld")
+DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
+DECLARE_STREAM_OPERATOR(double , "%g" )
+#undef DECLARE_STREAM_OPERATOR
+
+LogMessage::LogMessage(LogLevel level, const char* filename, int line)
+ : level_(level), filename_(filename), line_(line) {}
+LogMessage::~LogMessage() {}
+
+void LogMessage::Finish() {
+ bool suppress = false;
+
+ if (level_ != LOGLEVEL_FATAL) {
+ InitLogSilencerCountOnce();
+ MutexLock lock(log_silencer_count_mutex_);
+ suppress = internal::log_silencer_count_ > 0;
+ }
+
+ if (!suppress) {
+ internal::log_handler_(level_, filename_, line_, message_);
+ }
+
+ if (level_ == LOGLEVEL_FATAL) {
+#ifdef PROTOBUF_USE_EXCEPTIONS
+ throw FatalException(filename_, line_, message_);
+#else
+ abort();
+#endif
+ }
+}
+
+void LogFinisher::operator=(LogMessage& other) {
+ other.Finish();
+}
+
+} // namespace internal
+
+LogHandler* SetLogHandler(LogHandler* new_func) {
+ LogHandler* old = internal::log_handler_;
+ if (old == &internal::NullLogHandler) {
+ old = NULL;
+ }
+ if (new_func == NULL) {
+ internal::log_handler_ = &internal::NullLogHandler;
+ } else {
+ internal::log_handler_ = new_func;
+ }
+ return old;
+}
+
+LogSilencer::LogSilencer() {
+ internal::InitLogSilencerCountOnce();
+ MutexLock lock(internal::log_silencer_count_mutex_);
+ ++internal::log_silencer_count_;
+};
+
+LogSilencer::~LogSilencer() {
+ internal::InitLogSilencerCountOnce();
+ MutexLock lock(internal::log_silencer_count_mutex_);
+ --internal::log_silencer_count_;
+};
+
+// ===================================================================
+// emulates google3/base/callback.cc
+
+Closure::~Closure() {}
+
+namespace internal { FunctionClosure0::~FunctionClosure0() {} }
+
+void DoNothing() {}
+
+// ===================================================================
+// emulates google3/base/mutex.cc
+
+#ifdef _WIN32
+
+struct Mutex::Internal {
+ CRITICAL_SECTION mutex;
+#ifndef NDEBUG
+ // Used only to implement AssertHeld().
+ DWORD thread_id;
+#endif
+};
+
+Mutex::Mutex()
+ : mInternal(new Internal) {
+ InitializeCriticalSection(&mInternal->mutex);
+}
+
+Mutex::~Mutex() {
+ DeleteCriticalSection(&mInternal->mutex);
+ delete mInternal;
+}
+
+void Mutex::Lock() {
+ EnterCriticalSection(&mInternal->mutex);
+#ifndef NDEBUG
+ mInternal->thread_id = GetCurrentThreadId();
+#endif
+}
+
+void Mutex::Unlock() {
+#ifndef NDEBUG
+ mInternal->thread_id = 0;
+#endif
+ LeaveCriticalSection(&mInternal->mutex);
+}
+
+void Mutex::AssertHeld() {
+#ifndef NDEBUG
+ GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
+#endif
+}
+
+#elif defined(HAVE_PTHREAD)
+
+struct Mutex::Internal {
+ pthread_mutex_t mutex;
+};
+
+Mutex::Mutex()
+ : mInternal(new Internal) {
+ pthread_mutex_init(&mInternal->mutex, NULL);
+}
+
+Mutex::~Mutex() {
+ pthread_mutex_destroy(&mInternal->mutex);
+ delete mInternal;
+}
+
+void Mutex::Lock() {
+ int result = pthread_mutex_lock(&mInternal->mutex);
+ if (result != 0) {
+ GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
+ }
+}
+
+void Mutex::Unlock() {
+ int result = pthread_mutex_unlock(&mInternal->mutex);
+ if (result != 0) {
+ GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
+ }
+}
+
+void Mutex::AssertHeld() {
+ // pthreads dosn't provide a way to check which thread holds the mutex.
+ // TODO(kenton): Maybe keep track of locking thread ID like with WIN32?
+}
+
+#endif
+
+// ===================================================================
+// Shutdown support.
+
+namespace internal {
+
+typedef void OnShutdownFunc();
+vector<void (*)()>* shutdown_functions = NULL;
+Mutex* shutdown_functions_mutex = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
+
+void InitShutdownFunctions() {
+ shutdown_functions = new vector<void (*)()>;
+ shutdown_functions_mutex = new Mutex;
+}
+
+inline void InitShutdownFunctionsOnce() {
+ GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
+}
+
+void OnShutdown(void (*func)()) {
+ InitShutdownFunctionsOnce();
+ MutexLock lock(shutdown_functions_mutex);
+ shutdown_functions->push_back(func);
+}
+
+} // namespace internal
+
+void ShutdownProtobufLibrary() {
+ internal::InitShutdownFunctionsOnce();
+
+ // We don't need to lock shutdown_functions_mutex because it's up to the
+ // caller to make sure that no one is using the library before this is
+ // called.
+
+ // Make it safe to call this multiple times.
+ if (internal::shutdown_functions == NULL) return;
+
+ for (int i = 0; i < internal::shutdown_functions->size(); i++) {
+ internal::shutdown_functions->at(i)();
+ }
+ delete internal::shutdown_functions;
+ internal::shutdown_functions = NULL;
+ delete internal::shutdown_functions_mutex;
+ internal::shutdown_functions_mutex = NULL;
+}
+
+#ifdef PROTOBUF_USE_EXCEPTIONS
+FatalException::~FatalException() throw() {}
+
+const char* FatalException::what() const throw() {
+ return message_.c_str();
+}
+#endif
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/common.h b/src/third_party/protobuf/src/google/protobuf/stubs/common.h
new file mode 100644
index 0000000..c2fd174
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/common.h
@@ -0,0 +1,1216 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda) and others
+//
+// Contains basic types and utilities used by the rest of the library.
+
+#ifndef GOOGLE_PROTOBUF_COMMON_H__
+#define GOOGLE_PROTOBUF_COMMON_H__
+
+#include <assert.h>
+#include <string>
+
+#ifndef STARBOARD
+#include <stdlib.h>
+#include <cstddef>
+#include <string.h>
+#if defined(__osf__)
+// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of
+// what stdint.h would define.
+#include <inttypes.h>
+#elif !defined(_MSC_VER)
+#include <stdint.h>
+#endif
+#else
+#include "starboard/types.h"
+#endif // STARBOARD
+
+#if defined(_MSC_VER) && defined(_CPPUNWIND)
+ #define PROTOBUF_USE_EXCEPTIONS
+#elif defined(__EXCEPTIONS)
+ #define PROTOBUF_USE_EXCEPTIONS
+#endif
+#ifdef PROTOBUF_USE_EXCEPTIONS
+#include <exception>
+#endif
+
+#if defined(_WIN32) && defined(GetMessage)
+// Allow GetMessage to be used as a valid method name in protobuf classes.
+// windows.h defines GetMessage() as a macro. Let's re-define it as an inline
+// function. The inline function should be equivalent for C++ users.
+inline BOOL GetMessage_Win32(
+ LPMSG lpMsg, HWND hWnd,
+ UINT wMsgFilterMin, UINT wMsgFilterMax) {
+ return GetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
+}
+#undef GetMessage
+inline BOOL GetMessage(
+ LPMSG lpMsg, HWND hWnd,
+ UINT wMsgFilterMin, UINT wMsgFilterMax) {
+ return GetMessage_Win32(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
+}
+#endif
+
+
+namespace std {}
+
+namespace google {
+namespace protobuf {
+
+#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
+#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+
+#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS)
+ #ifdef LIBPROTOBUF_EXPORTS
+ #define LIBPROTOBUF_EXPORT __declspec(dllexport)
+ #else
+ #define LIBPROTOBUF_EXPORT __declspec(dllimport)
+ #endif
+ #ifdef LIBPROTOC_EXPORTS
+ #define LIBPROTOC_EXPORT __declspec(dllexport)
+ #else
+ #define LIBPROTOC_EXPORT __declspec(dllimport)
+ #endif
+#else
+ #define LIBPROTOBUF_EXPORT
+ #define LIBPROTOC_EXPORT
+#endif
+
+namespace internal {
+
+// Some of these constants are macros rather than const ints so that they can
+// be used in #if directives.
+
+// The current version, represented as a single integer to make comparison
+// easier: major * 10^6 + minor * 10^3 + micro
+#define GOOGLE_PROTOBUF_VERSION 2004002
+
+// The minimum library version which works with the current version of the
+// headers.
+#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2004000
+
+// The minimum header version which works with the current version of
+// the library. This constant should only be used by protoc's C++ code
+// generator.
+static const int kMinHeaderVersionForLibrary = 2004000;
+
+// The minimum protoc version which works with the current version of the
+// headers.
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2004000
+
+// The minimum header version which works with the current version of
+// protoc. This constant should only be used in VerifyVersion().
+static const int kMinHeaderVersionForProtoc = 2004000;
+
+// Verifies that the headers and libraries are compatible. Use the macro
+// below to call this.
+void LIBPROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion,
+ const char* filename);
+
+// Converts a numeric version number to a string.
+std::string LIBPROTOBUF_EXPORT VersionString(int version);
+
+} // namespace internal
+
+// Place this macro in your main() function (or somewhere before you attempt
+// to use the protobuf library) to verify that the version you link against
+// matches the headers you compiled against. If a version mismatch is
+// detected, the process will abort.
+#define GOOGLE_PROTOBUF_VERIFY_VERSION \
+ ::google::protobuf::internal::VerifyVersion( \
+ GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION, \
+ __FILE__)
+
+// ===================================================================
+// from google3/base/port.h
+
+typedef unsigned int uint;
+
+#ifdef _MSC_VER
+typedef __int8 int8;
+typedef __int16 int16;
+typedef __int32 int32;
+typedef __int64 int64;
+
+typedef unsigned __int8 uint8;
+typedef unsigned __int16 uint16;
+typedef unsigned __int32 uint32;
+typedef unsigned __int64 uint64;
+#else
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
+#endif
+
+// long long macros to be used because gcc and vc++ use different suffixes,
+// and different size specifiers in format strings
+#undef GOOGLE_LONGLONG
+#undef GOOGLE_ULONGLONG
+#undef GOOGLE_LL_FORMAT
+
+#ifdef _MSC_VER
+#define GOOGLE_LONGLONG(x) x##I64
+#define GOOGLE_ULONGLONG(x) x##UI64
+#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...)
+#else
+#define GOOGLE_LONGLONG(x) x##LL
+#define GOOGLE_ULONGLONG(x) x##ULL
+#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also.
+#endif
+
+static const int32 kint32max = 0x7FFFFFFF;
+static const int32 kint32min = -kint32max - 1;
+static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF);
+static const int64 kint64min = -kint64max - 1;
+static const uint32 kuint32max = 0xFFFFFFFFu;
+static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
+
+// -------------------------------------------------------------------
+// Annotations: Some parts of the code have been annotated in ways that might
+// be useful to some compilers or tools, but are not supported universally.
+// You can #define these annotations yourself if the default implementation
+// is not right for you.
+
+#ifndef GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+#if defined(__GNUC__) && (__GNUC__ > 3 ||(__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+// For functions we want to force inline.
+// Introduced in gcc 3.1.
+#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((always_inline))
+#else
+// Other compilers will have to figure it out for themselves.
+#define GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+#endif
+#endif
+
+#ifndef GOOGLE_ATTRIBUTE_DEPRECATED
+#ifdef __GNUC__
+// If the method/variable/type is used anywhere, produce a warning.
+#define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define GOOGLE_ATTRIBUTE_DEPRECATED
+#endif
+#endif
+
+#ifndef GOOGLE_PREDICT_TRUE
+#ifdef __GNUC__
+// Provided at least since GCC 3.0.
+#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
+#else
+#define GOOGLE_PREDICT_TRUE
+#endif
+#endif
+
+// Delimits a block of code which may write to memory which is simultaneously
+// written by other threads, but which has been determined to be thread-safe
+// (e.g. because it is an idempotent write).
+#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN
+#define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN()
+#endif
+#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END
+#define GOOGLE_SAFE_CONCURRENT_WRITES_END()
+#endif
+
+// ===================================================================
+// from google3/base/basictypes.h
+
+// The GOOGLE_ARRAYSIZE(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example.
+//
+// GOOGLE_ARRAYSIZE catches a few type errors. If you see a compiler error
+//
+// "warning: division by zero in ..."
+//
+// when using GOOGLE_ARRAYSIZE, you are (wrongfully) giving it a pointer.
+// You should only use GOOGLE_ARRAYSIZE on statically allocated arrays.
+//
+// The following comments are on the implementation details, and can
+// be ignored by the users.
+//
+// ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in
+// the array) and sizeof(*(arr)) (the # of bytes in one array
+// element). If the former is divisible by the latter, perhaps arr is
+// indeed an array, in which case the division result is the # of
+// elements in the array. Otherwise, arr cannot possibly be an array,
+// and we generate a compiler error to prevent the code from
+// compiling.
+//
+// Since the size of bool is implementation-defined, we need to cast
+// !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final
+// result has type size_t.
+//
+// This macro is not perfect as it wrongfully accepts certain
+// pointers, namely where the pointer size is divisible by the pointee
+// size. Since all our code has to go through a 32-bit compiler,
+// where a pointer is 4 bytes, this means all pointers to a type whose
+// size is 3 or greater than 4 will be (righteously) rejected.
+//
+// Kudos to Jorg Brown for this simple and elegant implementation.
+
+#undef GOOGLE_ARRAYSIZE
+#define GOOGLE_ARRAYSIZE(a) \
+ ((sizeof(a) / sizeof(*(a))) / \
+ static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+
+namespace internal {
+
+// Use implicit_cast as a safe version of static_cast or const_cast
+// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
+// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
+// a const pointer to Foo).
+// When you use implicit_cast, the compiler checks that the cast is safe.
+// Such explicit implicit_casts are necessary in surprisingly many
+// situations where C++ demands an exact type match instead of an
+// argument type convertable to a target type.
+//
+// The From type can be inferred, so the preferred syntax for using
+// implicit_cast is the same as for static_cast etc.:
+//
+// implicit_cast<ToType>(expr)
+//
+// implicit_cast would have been part of the C++ standard library,
+// but the proposal was submitted too late. It will probably make
+// its way into the language in the future.
+template<typename To, typename From>
+inline To implicit_cast(From const &f) {
+ return f;
+}
+
+// When you upcast (that is, cast a pointer from type Foo to type
+// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
+// always succeed. When you downcast (that is, cast a pointer from
+// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
+// how do you know the pointer is really of type SubclassOfFoo? It
+// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
+// when you downcast, you should use this macro. In debug mode, we
+// use dynamic_cast<> to double-check the downcast is legal (we die
+// if it's not). In normal mode, we do the efficient static_cast<>
+// instead. Thus, it's important to test in debug mode to make sure
+// the cast is legal!
+// This is the only place in the code we should use dynamic_cast<>.
+// In particular, you SHOULDN'T be using dynamic_cast<> in order to
+// do RTTI (eg code like this:
+// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
+// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
+// You should design the code some other way not to need this.
+
+template<typename To, typename From> // use like this: down_cast<T*>(foo);
+inline To down_cast(From* f) { // so we only accept pointers
+ // Ensures that To is a sub-type of From *. This test is here only
+ // for compile-time type checking, and has no overhead in an
+ // optimized build at run-time, as it will be optimized away
+ // completely.
+ if (false) {
+ implicit_cast<From*, To>(0);
+ }
+
+#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI)
+ assert(f == NULL || dynamic_cast<To>(f) != NULL); // RTTI: debug mode only!
+#endif
+ return static_cast<To>(f);
+}
+
+} // namespace internal
+
+// We made these internal so that they would show up as such in the docs,
+// but we don't want to stick "internal::" in front of them everywhere.
+using internal::implicit_cast;
+using internal::down_cast;
+
+// The COMPILE_ASSERT macro can be used to verify that a compile time
+// expression is true. For example, you could use it to verify the
+// size of a static array:
+//
+// COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES,
+// content_type_names_incorrect_size);
+//
+// or to make sure a struct is smaller than a certain size:
+//
+// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
+//
+// The second argument to the macro is the name of the variable. If
+// the expression is false, most compilers will issue a warning/error
+// containing the name of the variable.
+
+namespace internal {
+
+template <bool>
+struct CompileAssert {
+};
+
+} // namespace internal
+
+#undef GOOGLE_COMPILE_ASSERT
+#define GOOGLE_COMPILE_ASSERT(expr, msg) \
+ typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \
+ msg[bool(expr) ? 1 : -1]
+
+
+// Implementation details of COMPILE_ASSERT:
+//
+// - COMPILE_ASSERT works by defining an array type that has -1
+// elements (and thus is invalid) when the expression is false.
+//
+// - The simpler definition
+//
+// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
+//
+// does not work, as gcc supports variable-length arrays whose sizes
+// are determined at run-time (this is gcc's extension and not part
+// of the C++ standard). As a result, gcc fails to reject the
+// following code with the simple definition:
+//
+// int foo;
+// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
+// // not a compile-time constant.
+//
+// - By using the type CompileAssert<(bool(expr))>, we ensures that
+// expr is a compile-time constant. (Template arguments must be
+// determined at compile-time.)
+//
+// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
+// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
+//
+// CompileAssert<bool(expr)>
+//
+// instead, these compilers will refuse to compile
+//
+// COMPILE_ASSERT(5 > 0, some_message);
+//
+// (They seem to think the ">" in "5 > 0" marks the end of the
+// template argument list.)
+//
+// - The array size is (bool(expr) ? 1 : -1), instead of simply
+//
+// ((expr) ? 1 : -1).
+//
+// This is to avoid running into a bug in MS VC 7.1, which
+// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
+
+// ===================================================================
+// from google3/base/memory/scoped_ptr.h
+
+namespace internal {
+
+// This is an implementation designed to match the anticipated future TR2
+// implementation of the scoped_ptr class, and its closely-related brethren,
+// scoped_array, scoped_ptr_malloc, and make_scoped_ptr.
+
+template <class C> class scoped_ptr;
+template <class C> class scoped_array;
+
+// A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
+// automatically deletes the pointer it holds (if any).
+// That is, scoped_ptr<T> owns the T object that it points to.
+// Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
+//
+// The size of a scoped_ptr is small:
+// sizeof(scoped_ptr<C>) == sizeof(C*)
+template <class C>
+class scoped_ptr {
+ public:
+
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to intializing with NULL.
+ // There is no way to create an uninitialized scoped_ptr.
+ // The input parameter must be allocated with new.
+ explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
+
+ // Destructor. If there is a C object, delete it.
+ // We don't need to test ptr_ == NULL because C++ does that for us.
+ ~scoped_ptr() {
+ enum { type_must_be_complete = sizeof(C) };
+ delete ptr_;
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (p != ptr_) {
+ enum { type_must_be_complete = sizeof(C) };
+ delete ptr_;
+ ptr_ = p;
+ }
+ }
+
+ // Accessors to get the owned object.
+ // operator* and operator-> will assert() if there is no current object.
+ C& operator*() const {
+ assert(ptr_ != NULL);
+ return *ptr_;
+ }
+ C* operator->() const {
+ assert(ptr_ != NULL);
+ return ptr_;
+ }
+ C* get() const { return ptr_; }
+
+ // Comparison operators.
+ // These return whether two scoped_ptr refer to the same object, not just to
+ // two different but equal objects.
+ bool operator==(C* p) const { return ptr_ == p; }
+ bool operator!=(C* p) const { return ptr_ != p; }
+
+ // Swap two scoped pointers.
+ void swap(scoped_ptr& p2) {
+ C* tmp = ptr_;
+ ptr_ = p2.ptr_;
+ p2.ptr_ = tmp;
+ }
+
+ // Release a pointer.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() {
+ C* retVal = ptr_;
+ ptr_ = NULL;
+ return retVal;
+ }
+
+ private:
+ C* ptr_;
+
+ // Forbid comparison of scoped_ptr types. If C2 != C, it totally doesn't
+ // make sense, and if C2 == C, it still doesn't make sense because you should
+ // never have the same object owned by two different scoped_ptrs.
+ template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
+ template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
+
+ // Disallow evil constructors
+ scoped_ptr(const scoped_ptr&);
+ void operator=(const scoped_ptr&);
+};
+
+// scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
+// with new [] and the destructor deletes objects with delete [].
+//
+// As with scoped_ptr<C>, a scoped_array<C> either points to an object
+// or is NULL. A scoped_array<C> owns the object that it points to.
+//
+// Size: sizeof(scoped_array<C>) == sizeof(C*)
+template <class C>
+class scoped_array {
+ public:
+
+ // The element type
+ typedef C element_type;
+
+ // Constructor. Defaults to intializing with NULL.
+ // There is no way to create an uninitialized scoped_array.
+ // The input parameter must be allocated with new [].
+ explicit scoped_array(C* p = NULL) : array_(p) { }
+
+ // Destructor. If there is a C object, delete it.
+ // We don't need to test ptr_ == NULL because C++ does that for us.
+ ~scoped_array() {
+ enum { type_must_be_complete = sizeof(C) };
+ delete[] array_;
+ }
+
+ // Reset. Deletes the current owned object, if any.
+ // Then takes ownership of a new object, if given.
+ // this->reset(this->get()) works.
+ void reset(C* p = NULL) {
+ if (p != array_) {
+ enum { type_must_be_complete = sizeof(C) };
+ delete[] array_;
+ array_ = p;
+ }
+ }
+
+ // Get one element of the current object.
+ // Will assert() if there is no current object, or index i is negative.
+ C& operator[](std::ptrdiff_t i) const {
+ assert(i >= 0);
+ assert(array_ != NULL);
+ return array_[i];
+ }
+
+ // Get a pointer to the zeroth element of the current object.
+ // If there is no current object, return NULL.
+ C* get() const {
+ return array_;
+ }
+
+ // Comparison operators.
+ // These return whether two scoped_array refer to the same object, not just to
+ // two different but equal objects.
+ bool operator==(C* p) const { return array_ == p; }
+ bool operator!=(C* p) const { return array_ != p; }
+
+ // Swap two scoped arrays.
+ void swap(scoped_array& p2) {
+ C* tmp = array_;
+ array_ = p2.array_;
+ p2.array_ = tmp;
+ }
+
+ // Release an array.
+ // The return value is the current pointer held by this object.
+ // If this object holds a NULL pointer, the return value is NULL.
+ // After this operation, this object will hold a NULL pointer,
+ // and will not own the object any more.
+ C* release() {
+ C* retVal = array_;
+ array_ = NULL;
+ return retVal;
+ }
+
+ private:
+ C* array_;
+
+ // Forbid comparison of different scoped_array types.
+ template <class C2> bool operator==(scoped_array<C2> const& p2) const;
+ template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
+
+ // Disallow evil constructors
+ scoped_array(const scoped_array&);
+ void operator=(const scoped_array&);
+};
+
+} // namespace internal
+
+// We made these internal so that they would show up as such in the docs,
+// but we don't want to stick "internal::" in front of them everywhere.
+using internal::scoped_ptr;
+using internal::scoped_array;
+
+// ===================================================================
+// emulates google3/base/logging.h
+
+enum LogLevel {
+ LOGLEVEL_INFO, // Informational. This is never actually used by
+ // libprotobuf.
+ LOGLEVEL_WARNING, // Warns about issues that, although not technically a
+ // problem now, could cause problems in the future. For
+ // example, a // warning will be printed when parsing a
+ // message that is near the message size limit.
+ LOGLEVEL_ERROR, // An error occurred which should never happen during
+ // normal use.
+ LOGLEVEL_FATAL, // An error occurred from which the library cannot
+ // recover. This usually indicates a programming error
+ // in the code which calls the library, especially when
+ // compiled in debug mode.
+
+#ifdef NDEBUG
+ LOGLEVEL_DFATAL = LOGLEVEL_ERROR
+#else
+ LOGLEVEL_DFATAL = LOGLEVEL_FATAL
+#endif
+};
+
+namespace internal {
+
+class LogFinisher;
+
+class LIBPROTOBUF_EXPORT LogMessage {
+ public:
+ LogMessage(LogLevel level, const char* filename, int line);
+ ~LogMessage();
+
+ LogMessage& operator<<(const std::string& value);
+ LogMessage& operator<<(const char* value);
+ LogMessage& operator<<(char value);
+ LogMessage& operator<<(int value);
+ LogMessage& operator<<(uint value);
+ LogMessage& operator<<(long value);
+ LogMessage& operator<<(unsigned long value);
+ LogMessage& operator<<(double value);
+
+ private:
+ friend class LogFinisher;
+ void Finish();
+
+ LogLevel level_;
+ const char* filename_;
+ int line_;
+ std::string message_;
+};
+
+// Used to make the entire "LOG(BLAH) << etc." expression have a void return
+// type and print a newline after each message.
+class LIBPROTOBUF_EXPORT LogFinisher {
+ public:
+ void operator=(LogMessage& other);
+};
+
+} // namespace internal
+
+// Undef everything in case we're being mixed with some other Google library
+// which already defined them itself. Presumably all Google libraries will
+// support the same syntax for these so it should not be a big deal if they
+// end up using our definitions instead.
+#undef GOOGLE_LOG
+#undef GOOGLE_LOG_IF
+
+#undef GOOGLE_CHECK
+#undef GOOGLE_CHECK_EQ
+#undef GOOGLE_CHECK_NE
+#undef GOOGLE_CHECK_LT
+#undef GOOGLE_CHECK_LE
+#undef GOOGLE_CHECK_GT
+#undef GOOGLE_CHECK_GE
+
+#undef GOOGLE_DLOG
+#undef GOOGLE_DCHECK
+#undef GOOGLE_DCHECK_EQ
+#undef GOOGLE_DCHECK_NE
+#undef GOOGLE_DCHECK_LT
+#undef GOOGLE_DCHECK_LE
+#undef GOOGLE_DCHECK_GT
+#undef GOOGLE_DCHECK_GE
+
+#define GOOGLE_LOG(LEVEL) \
+ ::google::protobuf::internal::LogFinisher() = \
+ ::google::protobuf::internal::LogMessage( \
+ ::google::protobuf::LOGLEVEL_##LEVEL, __FILE__, __LINE__)
+#define GOOGLE_LOG_IF(LEVEL, CONDITION) \
+ !(CONDITION) ? (void)0 : GOOGLE_LOG(LEVEL)
+
+#define GOOGLE_CHECK(EXPRESSION) \
+ GOOGLE_LOG_IF(FATAL, !(EXPRESSION)) << "CHECK failed: " #EXPRESSION ": "
+#define GOOGLE_CHECK_EQ(A, B) GOOGLE_CHECK((A) == (B))
+#define GOOGLE_CHECK_NE(A, B) GOOGLE_CHECK((A) != (B))
+#define GOOGLE_CHECK_LT(A, B) GOOGLE_CHECK((A) < (B))
+#define GOOGLE_CHECK_LE(A, B) GOOGLE_CHECK((A) <= (B))
+#define GOOGLE_CHECK_GT(A, B) GOOGLE_CHECK((A) > (B))
+#define GOOGLE_CHECK_GE(A, B) GOOGLE_CHECK((A) >= (B))
+
+#ifdef NDEBUG
+
+#define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false)
+
+#define GOOGLE_DCHECK(EXPRESSION) while(false) GOOGLE_CHECK(EXPRESSION)
+#define GOOGLE_DCHECK_EQ(A, B) GOOGLE_DCHECK((A) == (B))
+#define GOOGLE_DCHECK_NE(A, B) GOOGLE_DCHECK((A) != (B))
+#define GOOGLE_DCHECK_LT(A, B) GOOGLE_DCHECK((A) < (B))
+#define GOOGLE_DCHECK_LE(A, B) GOOGLE_DCHECK((A) <= (B))
+#define GOOGLE_DCHECK_GT(A, B) GOOGLE_DCHECK((A) > (B))
+#define GOOGLE_DCHECK_GE(A, B) GOOGLE_DCHECK((A) >= (B))
+
+#else // NDEBUG
+
+#define GOOGLE_DLOG GOOGLE_LOG
+
+#define GOOGLE_DCHECK GOOGLE_CHECK
+#define GOOGLE_DCHECK_EQ GOOGLE_CHECK_EQ
+#define GOOGLE_DCHECK_NE GOOGLE_CHECK_NE
+#define GOOGLE_DCHECK_LT GOOGLE_CHECK_LT
+#define GOOGLE_DCHECK_LE GOOGLE_CHECK_LE
+#define GOOGLE_DCHECK_GT GOOGLE_CHECK_GT
+#define GOOGLE_DCHECK_GE GOOGLE_CHECK_GE
+
+#endif // !NDEBUG
+
+typedef void LogHandler(LogLevel level, const char* filename, int line,
+ const std::string& message);
+
+// The protobuf library sometimes writes warning and error messages to
+// stderr. These messages are primarily useful for developers, but may
+// also help end users figure out a problem. If you would prefer that
+// these messages be sent somewhere other than stderr, call SetLogHandler()
+// to set your own handler. This returns the old handler. Set the handler
+// to NULL to ignore log messages (but see also LogSilencer, below).
+//
+// Obviously, SetLogHandler is not thread-safe. You should only call it
+// at initialization time, and probably not from library code. If you
+// simply want to suppress log messages temporarily (e.g. because you
+// have some code that tends to trigger them frequently and you know
+// the warnings are not important to you), use the LogSilencer class
+// below.
+LIBPROTOBUF_EXPORT LogHandler* SetLogHandler(LogHandler* new_func);
+
+// Create a LogSilencer if you want to temporarily suppress all log
+// messages. As long as any LogSilencer objects exist, non-fatal
+// log messages will be discarded (the current LogHandler will *not*
+// be called). Constructing a LogSilencer is thread-safe. You may
+// accidentally suppress log messages occurring in another thread, but
+// since messages are generally for debugging purposes only, this isn't
+// a big deal. If you want to intercept log messages, use SetLogHandler().
+class LIBPROTOBUF_EXPORT LogSilencer {
+ public:
+ LogSilencer();
+ ~LogSilencer();
+};
+
+// ===================================================================
+// emulates google3/base/callback.h
+
+// Abstract interface for a callback. When calling an RPC, you must provide
+// a Closure to call when the procedure completes. See the Service interface
+// in service.h.
+//
+// To automatically construct a Closure which calls a particular function or
+// method with a particular set of parameters, use the NewCallback() function.
+// Example:
+// void FooDone(const FooResponse* response) {
+// ...
+// }
+//
+// void CallFoo() {
+// ...
+// // When done, call FooDone() and pass it a pointer to the response.
+// Closure* callback = NewCallback(&FooDone, response);
+// // Make the call.
+// service->Foo(controller, request, response, callback);
+// }
+//
+// Example that calls a method:
+// class Handler {
+// public:
+// ...
+//
+// void FooDone(const FooResponse* response) {
+// ...
+// }
+//
+// void CallFoo() {
+// ...
+// // When done, call FooDone() and pass it a pointer to the response.
+// Closure* callback = NewCallback(this, &Handler::FooDone, response);
+// // Make the call.
+// service->Foo(controller, request, response, callback);
+// }
+// };
+//
+// Currently NewCallback() supports binding zero, one, or two arguments.
+//
+// Callbacks created with NewCallback() automatically delete themselves when
+// executed. They should be used when a callback is to be called exactly
+// once (usually the case with RPC callbacks). If a callback may be called
+// a different number of times (including zero), create it with
+// NewPermanentCallback() instead. You are then responsible for deleting the
+// callback (using the "delete" keyword as normal).
+//
+// Note that NewCallback() is a bit touchy regarding argument types. Generally,
+// the values you provide for the parameter bindings must exactly match the
+// types accepted by the callback function. For example:
+// void Foo(string s);
+// NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string
+// NewCallback(&Foo, string("foo")); // WORKS
+// Also note that the arguments cannot be references:
+// void Foo(const string& s);
+// string my_str;
+// NewCallback(&Foo, my_str); // WON'T WORK: Can't use referecnes.
+// However, correctly-typed pointers will work just fine.
+class LIBPROTOBUF_EXPORT Closure {
+ public:
+ Closure() {}
+ virtual ~Closure();
+
+ virtual void Run() = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure);
+};
+
+namespace internal {
+
+class LIBPROTOBUF_EXPORT FunctionClosure0 : public Closure {
+ public:
+ typedef void (*FunctionType)();
+
+ FunctionClosure0(FunctionType function, bool self_deleting)
+ : function_(function), self_deleting_(self_deleting) {}
+ ~FunctionClosure0();
+
+ void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
+ function_();
+ if (needs_delete) delete this;
+ }
+
+ private:
+ FunctionType function_;
+ bool self_deleting_;
+};
+
+template <typename Class>
+class MethodClosure0 : public Closure {
+ public:
+ typedef void (Class::*MethodType)();
+
+ MethodClosure0(Class* object, MethodType method, bool self_deleting)
+ : object_(object), method_(method), self_deleting_(self_deleting) {}
+ ~MethodClosure0() {}
+
+ void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
+ (object_->*method_)();
+ if (needs_delete) delete this;
+ }
+
+ private:
+ Class* object_;
+ MethodType method_;
+ bool self_deleting_;
+};
+
+template <typename Arg1>
+class FunctionClosure1 : public Closure {
+ public:
+ typedef void (*FunctionType)(Arg1 arg1);
+
+ FunctionClosure1(FunctionType function, bool self_deleting,
+ Arg1 arg1)
+ : function_(function), self_deleting_(self_deleting),
+ arg1_(arg1) {}
+ ~FunctionClosure1() {}
+
+ void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
+ function_(arg1_);
+ if (needs_delete) delete this;
+ }
+
+ private:
+ FunctionType function_;
+ bool self_deleting_;
+ Arg1 arg1_;
+};
+
+template <typename Class, typename Arg1>
+class MethodClosure1 : public Closure {
+ public:
+ typedef void (Class::*MethodType)(Arg1 arg1);
+
+ MethodClosure1(Class* object, MethodType method, bool self_deleting,
+ Arg1 arg1)
+ : object_(object), method_(method), self_deleting_(self_deleting),
+ arg1_(arg1) {}
+ ~MethodClosure1() {}
+
+ void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
+ (object_->*method_)(arg1_);
+ if (needs_delete) delete this;
+ }
+
+ private:
+ Class* object_;
+ MethodType method_;
+ bool self_deleting_;
+ Arg1 arg1_;
+};
+
+template <typename Arg1, typename Arg2>
+class FunctionClosure2 : public Closure {
+ public:
+ typedef void (*FunctionType)(Arg1 arg1, Arg2 arg2);
+
+ FunctionClosure2(FunctionType function, bool self_deleting,
+ Arg1 arg1, Arg2 arg2)
+ : function_(function), self_deleting_(self_deleting),
+ arg1_(arg1), arg2_(arg2) {}
+ ~FunctionClosure2() {}
+
+ void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
+ function_(arg1_, arg2_);
+ if (needs_delete) delete this;
+ }
+
+ private:
+ FunctionType function_;
+ bool self_deleting_;
+ Arg1 arg1_;
+ Arg2 arg2_;
+};
+
+template <typename Class, typename Arg1, typename Arg2>
+class MethodClosure2 : public Closure {
+ public:
+ typedef void (Class::*MethodType)(Arg1 arg1, Arg2 arg2);
+
+ MethodClosure2(Class* object, MethodType method, bool self_deleting,
+ Arg1 arg1, Arg2 arg2)
+ : object_(object), method_(method), self_deleting_(self_deleting),
+ arg1_(arg1), arg2_(arg2) {}
+ ~MethodClosure2() {}
+
+ void Run() {
+ bool needs_delete = self_deleting_; // read in case callback deletes
+ (object_->*method_)(arg1_, arg2_);
+ if (needs_delete) delete this;
+ }
+
+ private:
+ Class* object_;
+ MethodType method_;
+ bool self_deleting_;
+ Arg1 arg1_;
+ Arg2 arg2_;
+};
+
+} // namespace internal
+
+// See Closure.
+inline Closure* NewCallback(void (*function)()) {
+ return new internal::FunctionClosure0(function, true);
+}
+
+// See Closure.
+inline Closure* NewPermanentCallback(void (*function)()) {
+ return new internal::FunctionClosure0(function, false);
+}
+
+// See Closure.
+template <typename Class>
+inline Closure* NewCallback(Class* object, void (Class::*method)()) {
+ return new internal::MethodClosure0<Class>(object, method, true);
+}
+
+// See Closure.
+template <typename Class>
+inline Closure* NewPermanentCallback(Class* object, void (Class::*method)()) {
+ return new internal::MethodClosure0<Class>(object, method, false);
+}
+
+// See Closure.
+template <typename Arg1>
+inline Closure* NewCallback(void (*function)(Arg1),
+ Arg1 arg1) {
+ return new internal::FunctionClosure1<Arg1>(function, true, arg1);
+}
+
+// See Closure.
+template <typename Arg1>
+inline Closure* NewPermanentCallback(void (*function)(Arg1),
+ Arg1 arg1) {
+ return new internal::FunctionClosure1<Arg1>(function, false, arg1);
+}
+
+// See Closure.
+template <typename Class, typename Arg1>
+inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1),
+ Arg1 arg1) {
+ return new internal::MethodClosure1<Class, Arg1>(object, method, true, arg1);
+}
+
+// See Closure.
+template <typename Class, typename Arg1>
+inline Closure* NewPermanentCallback(Class* object, void (Class::*method)(Arg1),
+ Arg1 arg1) {
+ return new internal::MethodClosure1<Class, Arg1>(object, method, false, arg1);
+}
+
+// See Closure.
+template <typename Arg1, typename Arg2>
+inline Closure* NewCallback(void (*function)(Arg1, Arg2),
+ Arg1 arg1, Arg2 arg2) {
+ return new internal::FunctionClosure2<Arg1, Arg2>(
+ function, true, arg1, arg2);
+}
+
+// See Closure.
+template <typename Arg1, typename Arg2>
+inline Closure* NewPermanentCallback(void (*function)(Arg1, Arg2),
+ Arg1 arg1, Arg2 arg2) {
+ return new internal::FunctionClosure2<Arg1, Arg2>(
+ function, false, arg1, arg2);
+}
+
+// See Closure.
+template <typename Class, typename Arg1, typename Arg2>
+inline Closure* NewCallback(Class* object, void (Class::*method)(Arg1, Arg2),
+ Arg1 arg1, Arg2 arg2) {
+ return new internal::MethodClosure2<Class, Arg1, Arg2>(
+ object, method, true, arg1, arg2);
+}
+
+// See Closure.
+template <typename Class, typename Arg1, typename Arg2>
+inline Closure* NewPermanentCallback(
+ Class* object, void (Class::*method)(Arg1, Arg2),
+ Arg1 arg1, Arg2 arg2) {
+ return new internal::MethodClosure2<Class, Arg1, Arg2>(
+ object, method, false, arg1, arg2);
+}
+
+// A function which does nothing. Useful for creating no-op callbacks, e.g.:
+// Closure* nothing = NewCallback(&DoNothing);
+void LIBPROTOBUF_EXPORT DoNothing();
+
+// ===================================================================
+// emulates google3/base/mutex.h
+
+namespace internal {
+
+// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T
+// may hold a mutex at a given time. If T attempts to Lock() the same Mutex
+// while holding it, T will deadlock.
+class LIBPROTOBUF_EXPORT Mutex {
+ public:
+ // Create a Mutex that is not held by anybody.
+ Mutex();
+
+ // Destructor
+ ~Mutex();
+
+ // Block if necessary until this Mutex is free, then acquire it exclusively.
+ void Lock();
+
+ // Release this Mutex. Caller must hold it exclusively.
+ void Unlock();
+
+ // Crash if this Mutex is not held exclusively by this thread.
+ // May fail to crash when it should; will never crash when it should not.
+ void AssertHeld();
+
+ private:
+ struct Internal;
+ Internal* mInternal;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex);
+};
+
+// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
+class LIBPROTOBUF_EXPORT MutexLock {
+ public:
+ explicit MutexLock(Mutex *mu) : mu_(mu) { this->mu_->Lock(); }
+ ~MutexLock() { this->mu_->Unlock(); }
+ private:
+ Mutex *const mu_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLock);
+};
+
+// TODO(kenton): Implement these? Hard to implement portably.
+typedef MutexLock ReaderMutexLock;
+typedef MutexLock WriterMutexLock;
+
+// MutexLockMaybe is like MutexLock, but is a no-op when mu is NULL.
+class LIBPROTOBUF_EXPORT MutexLockMaybe {
+ public:
+ explicit MutexLockMaybe(Mutex *mu) :
+ mu_(mu) { if (this->mu_ != NULL) { this->mu_->Lock(); } }
+ ~MutexLockMaybe() { if (this->mu_ != NULL) { this->mu_->Unlock(); } }
+ private:
+ Mutex *const mu_;
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe);
+};
+
+} // namespace internal
+
+// We made these internal so that they would show up as such in the docs,
+// but we don't want to stick "internal::" in front of them everywhere.
+using internal::Mutex;
+using internal::MutexLock;
+using internal::ReaderMutexLock;
+using internal::WriterMutexLock;
+using internal::MutexLockMaybe;
+
+// ===================================================================
+// from google3/base/type_traits.h
+
+namespace internal {
+
+// Specified by TR1 [4.7.4] Pointer modifications.
+template<typename T> struct remove_pointer { typedef T type; };
+template<typename T> struct remove_pointer<T*> { typedef T type; };
+template<typename T> struct remove_pointer<T* const> { typedef T type; };
+template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
+template<typename T> struct remove_pointer<T* const volatile> {
+ typedef T type; };
+
+// ===================================================================
+
+// Checks if the buffer contains structurally-valid UTF-8. Implemented in
+// structurally_valid.cc.
+LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
+
+} // namespace internal
+
+// ===================================================================
+// Shutdown support.
+
+// Shut down the entire protocol buffers library, deleting all static-duration
+// objects allocated by the library or by generated .pb.cc files.
+//
+// There are two reasons you might want to call this:
+// * You use a draconian definition of "memory leak" in which you expect
+// every single malloc() to have a corresponding free(), even for objects
+// which live until program exit.
+// * You are writing a dynamically-loaded library which needs to clean up
+// after itself when the library is unloaded.
+//
+// It is safe to call this multiple times. However, it is not safe to use
+// any other part of the protocol buffers library after
+// ShutdownProtobufLibrary() has been called.
+LIBPROTOBUF_EXPORT void ShutdownProtobufLibrary();
+
+namespace internal {
+
+// Register a function to be called when ShutdownProtocolBuffers() is called.
+LIBPROTOBUF_EXPORT void OnShutdown(void (*func)());
+
+} // namespace internal
+
+#ifdef PROTOBUF_USE_EXCEPTIONS
+class FatalException : public std::exception {
+ public:
+ FatalException(const char* filename, int line, const std::string& message)
+ : filename_(filename), line_(line), message_(message) {}
+ virtual ~FatalException() throw();
+
+ virtual const char* what() const throw();
+
+ const char* filename() const { return filename_; }
+ int line() const { return line_; }
+ const std::string& message() const { return message_; }
+
+ private:
+ const char* filename_;
+ const int line_;
+ const std::string message_;
+};
+#endif
+
+// This is at the end of the file instead of the beginning to work around a bug
+// in some versions of MSVC.
+using namespace std; // Don't do this at home, kids.
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMMON_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/common_unittest.cc b/src/third_party/protobuf/src/google/protobuf/stubs/common_unittest.cc
new file mode 100644
index 0000000..4109a52
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/common_unittest.cc
@@ -0,0 +1,357 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+#include "config.h"
+
+namespace google {
+namespace protobuf {
+namespace {
+
+// TODO(kenton): More tests.
+
+#ifdef PACKAGE_VERSION // only defined when using automake, not MSVC
+
+TEST(VersionTest, VersionMatchesConfig) {
+ // Verify that the version string specified in config.h matches the one
+ // in common.h. The config.h version is a string which may have a suffix
+ // like "beta" or "rc1", so we remove that.
+ string version = PACKAGE_VERSION;
+ int pos = 0;
+ while (pos < version.size() &&
+ (ascii_isdigit(version[pos]) || version[pos] == '.')) {
+ ++pos;
+ }
+ version.erase(pos);
+
+ EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
+}
+
+#endif // PACKAGE_VERSION
+
+TEST(CommonTest, IntMinMaxConstants) {
+ // kint32min was declared incorrectly in the first release of protobufs.
+ // Ugh.
+ EXPECT_LT(kint32min, kint32max);
+ EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1);
+ EXPECT_LT(kint64min, kint64max);
+ EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1);
+ EXPECT_EQ(0, kuint32max + 1);
+ EXPECT_EQ(0, kuint64max + 1);
+}
+
+vector<string> captured_messages_;
+
+void CaptureLog(LogLevel level, const char* filename, int line,
+ const string& message) {
+ captured_messages_.push_back(
+ strings::Substitute("$0 $1:$2: $3",
+ implicit_cast<int>(level), filename, line, message));
+}
+
+TEST(LoggingTest, DefaultLogging) {
+ CaptureTestStderr();
+ int line = __LINE__;
+ GOOGLE_LOG(INFO ) << "A message.";
+ GOOGLE_LOG(WARNING) << "A warning.";
+ GOOGLE_LOG(ERROR ) << "An error.";
+
+ string text = GetCapturedTestStderr();
+ EXPECT_EQ(
+ "libprotobuf INFO "__FILE__":" + SimpleItoa(line + 1) + "] A message.\n"
+ "libprotobuf WARNING "__FILE__":" + SimpleItoa(line + 2) + "] A warning.\n"
+ "libprotobuf ERROR "__FILE__":" + SimpleItoa(line + 3) + "] An error.\n",
+ text);
+}
+
+TEST(LoggingTest, NullLogging) {
+ LogHandler* old_handler = SetLogHandler(NULL);
+
+ CaptureTestStderr();
+ GOOGLE_LOG(INFO ) << "A message.";
+ GOOGLE_LOG(WARNING) << "A warning.";
+ GOOGLE_LOG(ERROR ) << "An error.";
+
+ EXPECT_TRUE(SetLogHandler(old_handler) == NULL);
+
+ string text = GetCapturedTestStderr();
+ EXPECT_EQ("", text);
+}
+
+TEST(LoggingTest, CaptureLogging) {
+ captured_messages_.clear();
+
+ LogHandler* old_handler = SetLogHandler(&CaptureLog);
+
+ int start_line = __LINE__;
+ GOOGLE_LOG(ERROR) << "An error.";
+ GOOGLE_LOG(WARNING) << "A warning.";
+
+ EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
+
+ ASSERT_EQ(2, captured_messages_.size());
+ EXPECT_EQ(
+ "2 "__FILE__":" + SimpleItoa(start_line + 1) + ": An error.",
+ captured_messages_[0]);
+ EXPECT_EQ(
+ "1 "__FILE__":" + SimpleItoa(start_line + 2) + ": A warning.",
+ captured_messages_[1]);
+}
+
+TEST(LoggingTest, SilenceLogging) {
+ captured_messages_.clear();
+
+ LogHandler* old_handler = SetLogHandler(&CaptureLog);
+
+ int line1 = __LINE__; GOOGLE_LOG(INFO) << "Visible1";
+ LogSilencer* silencer1 = new LogSilencer;
+ GOOGLE_LOG(INFO) << "Not visible.";
+ LogSilencer* silencer2 = new LogSilencer;
+ GOOGLE_LOG(INFO) << "Not visible.";
+ delete silencer1;
+ GOOGLE_LOG(INFO) << "Not visible.";
+ delete silencer2;
+ int line2 = __LINE__; GOOGLE_LOG(INFO) << "Visible2";
+
+ EXPECT_TRUE(SetLogHandler(old_handler) == &CaptureLog);
+
+ ASSERT_EQ(2, captured_messages_.size());
+ EXPECT_EQ(
+ "0 "__FILE__":" + SimpleItoa(line1) + ": Visible1",
+ captured_messages_[0]);
+ EXPECT_EQ(
+ "0 "__FILE__":" + SimpleItoa(line2) + ": Visible2",
+ captured_messages_[1]);
+}
+
+class ClosureTest : public testing::Test {
+ public:
+ void SetA123Method() { a_ = 123; }
+ static void SetA123Function() { current_instance_->a_ = 123; }
+
+ void SetAMethod(int a) { a_ = a; }
+ void SetCMethod(string c) { c_ = c; }
+
+ static void SetAFunction(int a) { current_instance_->a_ = a; }
+ static void SetCFunction(string c) { current_instance_->c_ = c; }
+
+ void SetABMethod(int a, const char* b) { a_ = a; b_ = b; }
+ static void SetABFunction(int a, const char* b) {
+ current_instance_->a_ = a;
+ current_instance_->b_ = b;
+ }
+
+ virtual void SetUp() {
+ current_instance_ = this;
+ a_ = 0;
+ b_ = NULL;
+ c_.clear();
+ permanent_closure_ = NULL;
+ }
+
+ void DeleteClosureInCallback() {
+ delete permanent_closure_;
+ }
+
+ int a_;
+ const char* b_;
+ string c_;
+ Closure* permanent_closure_;
+
+ static ClosureTest* current_instance_;
+};
+
+ClosureTest* ClosureTest::current_instance_ = NULL;
+
+TEST_F(ClosureTest, TestClosureFunction0) {
+ Closure* closure = NewCallback(&SetA123Function);
+ EXPECT_NE(123, a_);
+ closure->Run();
+ EXPECT_EQ(123, a_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod0) {
+ Closure* closure = NewCallback(current_instance_,
+ &ClosureTest::SetA123Method);
+ EXPECT_NE(123, a_);
+ closure->Run();
+ EXPECT_EQ(123, a_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction1) {
+ Closure* closure = NewCallback(&SetAFunction, 456);
+ EXPECT_NE(456, a_);
+ closure->Run();
+ EXPECT_EQ(456, a_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod1) {
+ Closure* closure = NewCallback(current_instance_,
+ &ClosureTest::SetAMethod, 456);
+ EXPECT_NE(456, a_);
+ closure->Run();
+ EXPECT_EQ(456, a_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction1String) {
+ Closure* closure = NewCallback(&SetCFunction, string("test"));
+ EXPECT_NE("test", c_);
+ closure->Run();
+ EXPECT_EQ("test", c_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod1String) {
+ Closure* closure = NewCallback(current_instance_,
+ &ClosureTest::SetCMethod, string("test"));
+ EXPECT_NE("test", c_);
+ closure->Run();
+ EXPECT_EQ("test", c_);
+}
+
+TEST_F(ClosureTest, TestClosureFunction2) {
+ const char* cstr = "hello";
+ Closure* closure = NewCallback(&SetABFunction, 789, cstr);
+ EXPECT_NE(789, a_);
+ EXPECT_NE(cstr, b_);
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+}
+
+TEST_F(ClosureTest, TestClosureMethod2) {
+ const char* cstr = "hello";
+ Closure* closure = NewCallback(current_instance_,
+ &ClosureTest::SetABMethod, 789, cstr);
+ EXPECT_NE(789, a_);
+ EXPECT_NE(cstr, b_);
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+}
+
+// Repeat all of the above with NewPermanentCallback()
+
+TEST_F(ClosureTest, TestPermanentClosureFunction0) {
+ Closure* closure = NewPermanentCallback(&SetA123Function);
+ EXPECT_NE(123, a_);
+ closure->Run();
+ EXPECT_EQ(123, a_);
+ a_ = 0;
+ closure->Run();
+ EXPECT_EQ(123, a_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod0) {
+ Closure* closure = NewPermanentCallback(current_instance_,
+ &ClosureTest::SetA123Method);
+ EXPECT_NE(123, a_);
+ closure->Run();
+ EXPECT_EQ(123, a_);
+ a_ = 0;
+ closure->Run();
+ EXPECT_EQ(123, a_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureFunction1) {
+ Closure* closure = NewPermanentCallback(&SetAFunction, 456);
+ EXPECT_NE(456, a_);
+ closure->Run();
+ EXPECT_EQ(456, a_);
+ a_ = 0;
+ closure->Run();
+ EXPECT_EQ(456, a_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod1) {
+ Closure* closure = NewPermanentCallback(current_instance_,
+ &ClosureTest::SetAMethod, 456);
+ EXPECT_NE(456, a_);
+ closure->Run();
+ EXPECT_EQ(456, a_);
+ a_ = 0;
+ closure->Run();
+ EXPECT_EQ(456, a_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureFunction2) {
+ const char* cstr = "hello";
+ Closure* closure = NewPermanentCallback(&SetABFunction, 789, cstr);
+ EXPECT_NE(789, a_);
+ EXPECT_NE(cstr, b_);
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+ a_ = 0;
+ b_ = NULL;
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureMethod2) {
+ const char* cstr = "hello";
+ Closure* closure = NewPermanentCallback(current_instance_,
+ &ClosureTest::SetABMethod, 789, cstr);
+ EXPECT_NE(789, a_);
+ EXPECT_NE(cstr, b_);
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+ a_ = 0;
+ b_ = NULL;
+ closure->Run();
+ EXPECT_EQ(789, a_);
+ EXPECT_EQ(cstr, b_);
+ delete closure;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
+ permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
+ &ClosureTest::DeleteClosureInCallback);
+ permanent_closure_->Run();
+}
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/hash.h b/src/third_party/protobuf/src/google/protobuf/stubs/hash.h
new file mode 100644
index 0000000..822d605
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/hash.h
@@ -0,0 +1,220 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Deals with the fact that hash_map is not defined everywhere.
+
+#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
+#define GOOGLE_PROTOBUF_STUBS_HASH_H__
+
+#include <string.h>
+#include <google/protobuf/stubs/common.h>
+#include "config.h"
+
+#if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET)
+#include HASH_MAP_H
+#include HASH_SET_H
+#else
+#define MISSING_HASH
+#include <map>
+#include <set>
+#endif
+
+namespace google {
+namespace protobuf {
+
+#ifdef MISSING_HASH
+
+// This system doesn't have hash_map or hash_set. Emulate them using map and
+// set.
+
+// Make hash<T> be the same as less<T>. Note that everywhere where custom
+// hash functions are defined in the protobuf code, they are also defined such
+// that they can be used as "less" functions, which is required by MSVC anyway.
+template <typename Key>
+struct hash {
+ // Dummy, just to make derivative hash functions compile.
+ int operator()(const Key& key) {
+ GOOGLE_LOG(FATAL) << "Should never be called.";
+ return 0;
+ }
+
+ inline bool operator()(const Key& a, const Key& b) const {
+ return a < b;
+ }
+};
+
+// Make sure char* is compared by value.
+template <>
+struct hash<const char*> {
+ // Dummy, just to make derivative hash functions compile.
+ int operator()(const char* key) {
+ GOOGLE_LOG(FATAL) << "Should never be called.";
+ return 0;
+ }
+
+ inline bool operator()(const char* a, const char* b) const {
+ return strcmp(a, b) < 0;
+ }
+};
+
+template <typename Key, typename Data,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = int >
+class hash_map : public std::map<Key, Data, HashFcn> {
+};
+
+template <typename Key,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = int >
+class hash_set : public std::set<Key, HashFcn> {
+};
+
+#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
+
+template <typename Key>
+struct hash : public HASH_NAMESPACE::hash_compare<Key> {
+};
+
+// MSVC's hash_compare<const char*> hashes based on the string contents but
+// compares based on the string pointer. WTF?
+class CstringLess {
+ public:
+ inline bool operator()(const char* a, const char* b) const {
+ return strcmp(a, b) < 0;
+ }
+};
+
+template <>
+struct hash<const char*>
+ : public HASH_NAMESPACE::hash_compare<const char*, CstringLess> {
+};
+
+template <typename Key, typename Data,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = int >
+class hash_map : public HASH_NAMESPACE::hash_map<
+ Key, Data, HashFcn> {
+};
+
+template <typename Key,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = int >
+class hash_set : public HASH_NAMESPACE::hash_set<
+ Key, HashFcn> {
+};
+
+#else
+
+template <typename Key>
+struct hash : public HASH_NAMESPACE::hash<Key> {
+};
+
+template <typename Key>
+struct hash<const Key*> {
+ inline size_t operator()(const Key* key) const {
+ return reinterpret_cast<size_t>(key);
+ }
+};
+
+// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So,
+// we go ahead and provide our own implementation.
+template <>
+struct hash<const char*> {
+ inline size_t operator()(const char* str) const {
+ size_t result = 0;
+ for (; *str != '\0'; str++) {
+ result = 5 * result + *str;
+ }
+ return result;
+ }
+};
+
+template <typename Key, typename Data,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = std::equal_to<Key> >
+class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS<
+ Key, Data, HashFcn, EqualKey> {
+};
+
+template <typename Key,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = std::equal_to<Key> >
+class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS<
+ Key, HashFcn, EqualKey> {
+};
+
+#endif
+
+template <>
+struct hash<string> {
+ inline size_t operator()(const string& key) const {
+ return hash<const char*>()(key.c_str());
+ }
+
+ static const size_t bucket_size = 4;
+ static const size_t min_buckets = 8;
+ inline size_t operator()(const string& a, const string& b) const {
+ return a < b;
+ }
+};
+
+template <typename First, typename Second>
+struct hash<pair<First, Second> > {
+ inline size_t operator()(const pair<First, Second>& key) const {
+ size_t first_hash = hash<First>()(key.first);
+ size_t second_hash = hash<Second>()(key.second);
+
+ // FIXME(kenton): What is the best way to compute this hash? I have
+ // no idea! This seems a bit better than an XOR.
+ return first_hash * ((1 << 16) - 1) + second_hash;
+ }
+
+ static const size_t bucket_size = 4;
+ static const size_t min_buckets = 8;
+ inline size_t operator()(const pair<First, Second>& a,
+ const pair<First, Second>& b) const {
+ return a < b;
+ }
+};
+
+// Used by GCC/SGI STL only. (Why isn't this provided by the standard
+// library? :( )
+struct streq {
+ inline bool operator()(const char* a, const char* b) const {
+ return strcmp(a, b) == 0;
+ }
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/map-util.h b/src/third_party/protobuf/src/google/protobuf/stubs/map-util.h
new file mode 100644
index 0000000..f5c9d6b
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/map-util.h
@@ -0,0 +1,119 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/util/gtl/map-util.h
+// Author: Anton Carver
+
+#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// Perform a lookup in a map or hash_map.
+// If the key is present in the map then the value associated with that
+// key is returned, otherwise the value passed as a default is returned.
+template <class Collection>
+const typename Collection::value_type::second_type&
+FindWithDefault(const Collection& collection,
+ const typename Collection::value_type::first_type& key,
+ const typename Collection::value_type::second_type& value) {
+ typename Collection::const_iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return value;
+ }
+ return it->second;
+}
+
+// Perform a lookup in a map or hash_map.
+// If the key is present a const pointer to the associated value is returned,
+// otherwise a NULL pointer is returned.
+template <class Collection>
+const typename Collection::value_type::second_type*
+FindOrNull(const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::const_iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return 0;
+ }
+ return &it->second;
+}
+
+// Perform a lookup in a map or hash_map whose values are pointers.
+// If the key is present a const pointer to the associated value is returned,
+// otherwise a NULL pointer is returned.
+// This function does not distinguish between a missing key and a key mapped
+// to a NULL value.
+template <class Collection>
+const typename Collection::value_type::second_type
+FindPtrOrNull(const Collection& collection,
+ const typename Collection::value_type::first_type& key) {
+ typename Collection::const_iterator it = collection.find(key);
+ if (it == collection.end()) {
+ return 0;
+ }
+ return it->second;
+}
+
+// Change the value associated with a particular key in a map or hash_map.
+// If the key is not present in the map the key and value are inserted,
+// otherwise the value is updated to be a copy of the value provided.
+// True indicates that an insert took place, false indicates an update.
+template <class Collection, class Key, class Value>
+bool InsertOrUpdate(Collection * const collection,
+ const Key& key, const Value& value) {
+ pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(key, value));
+ if (!ret.second) {
+ // update
+ ret.first->second = value;
+ return false;
+ }
+ return true;
+}
+
+// Insert a new key and value into a map or hash_map.
+// If the key is not present in the map the key and value are
+// inserted, otherwise nothing happens. True indicates that an insert
+// took place, false indicates the key was already present.
+template <class Collection, class Key, class Value>
+bool InsertIfNotPresent(Collection * const collection,
+ const Key& key, const Value& value) {
+ pair<typename Collection::iterator, bool> ret =
+ collection->insert(typename Collection::value_type(key, value));
+ return ret.second;
+}
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/once.cc b/src/third_party/protobuf/src/google/protobuf/stubs/once.cc
new file mode 100644
index 0000000..1e24b85
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/once.cc
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// emulates google3/base/once.h
+//
+// This header is intended to be included only by internal .cc files and
+// generated .pb.cc files. Users should not use this directly.
+
+#include <google/protobuf/stubs/once.h>
+
+#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sched.h>
+#endif
+
+#include <google/protobuf/stubs/atomicops.h>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+void SchedYield() {
+#ifdef _WIN32
+ Sleep(0);
+#else // POSIX
+ sched_yield();
+#endif
+}
+
+} // namespace
+
+void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) {
+ internal::AtomicWord state = internal::Acquire_Load(once);
+ // Fast path. The provided closure was already executed.
+ if (state == ONCE_STATE_DONE) {
+ return;
+ }
+ // The closure execution did not complete yet. The once object can be in one
+ // of the two following states:
+ // - UNINITIALIZED: We are the first thread calling this function.
+ // - EXECUTING_CLOSURE: Another thread is already executing the closure.
+ //
+ // First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE
+ // atomically.
+ state = internal::Acquire_CompareAndSwap(
+ once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE);
+ if (state == ONCE_STATE_UNINITIALIZED) {
+ // We are the first thread to call this function, so we have to call the
+ // closure.
+ closure->Run();
+ internal::Release_Store(once, ONCE_STATE_DONE);
+ } else {
+ // Another thread has already started executing the closure. We need to
+ // wait until it completes the initialization.
+ while (state == ONCE_STATE_EXECUTING_CLOSURE) {
+ // Note that futex() could be used here on Linux as an improvement.
+ SchedYield();
+ state = internal::Acquire_Load(once);
+ }
+ }
+}
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/once.h b/src/third_party/protobuf/src/google/protobuf/stubs/once.h
new file mode 100644
index 0000000..c8cbe24
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/once.h
@@ -0,0 +1,147 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// emulates google3/base/once.h
+//
+// This header is intended to be included only by internal .cc files and
+// generated .pb.cc files. Users should not use this directly.
+//
+// This is basically a portable version of pthread_once().
+//
+// This header declares:
+// * A type called ProtobufOnceType.
+// * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type
+// ProtobufOnceType. This is the only legal way to declare such a variable.
+// The macro may only be used at the global scope (you cannot create local or
+// class member variables of this type).
+// * A function GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()).
+// This function, when invoked multiple times given the same ProtobufOnceType
+// object, will invoke init_func on the first call only, and will make sure
+// none of the calls return before that first call to init_func has finished.
+// * The user can provide a parameter which GoogleOnceInit() forwards to the
+// user-provided function when it is called. Usage example:
+// int a = 10;
+// GoogleOnceInit(&my_once, &MyFunctionExpectingIntArgument, &a);
+// * This implementation guarantees that ProtobufOnceType is a POD (i.e. no
+// static initializer generated).
+//
+// This implements a way to perform lazy initialization. It's more efficient
+// than using mutexes as no lock is needed if initialization has already
+// happened.
+//
+// Example usage:
+// void Init();
+// GOOGLE_PROTOBUF_DECLARE_ONCE(once_init);
+//
+// // Calls Init() exactly once.
+// void InitOnce() {
+// GoogleOnceInit(&once_init, &Init);
+// }
+//
+// Note that if GoogleOnceInit() is called before main() has begun, it must
+// only be called by the thread that will eventually call main() -- that is,
+// the thread that performs dynamic initialization. In general this is a safe
+// assumption since people don't usually construct threads before main() starts,
+// but it is technically not guaranteed. Unfortunately, Win32 provides no way
+// whatsoever to statically-initialize its synchronization primitives, so our
+// only choice is to assume that dynamic initialization is single-threaded.
+
+#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__
+#define GOOGLE_PROTOBUF_STUBS_ONCE_H__
+
+#include <google/protobuf/stubs/atomicops.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+typedef bool ProtobufOnceType;
+
+#define GOOGLE_PROTOBUF_ONCE_INIT false
+
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
+ if (!*once) {
+ *once = true;
+ init_func();
+ }
+}
+
+template <typename Arg>
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg),
+ Arg arg) {
+ if (!*once) {
+ *once = true;
+ init_func(arg);
+ }
+}
+
+#else
+
+enum {
+ ONCE_STATE_UNINITIALIZED = 0,
+ ONCE_STATE_EXECUTING_CLOSURE = 1,
+ ONCE_STATE_DONE = 2
+};
+
+typedef internal::AtomicWord ProtobufOnceType;
+
+#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED
+
+void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure);
+
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
+ if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
+ internal::FunctionClosure0 func(init_func, false);
+ GoogleOnceInitImpl(once, &func);
+ }
+}
+
+template <typename Arg>
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*),
+ Arg* arg) {
+ if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
+ internal::FunctionClosure1<Arg*> func(init_func, false, arg);
+ GoogleOnceInitImpl(once, &func);
+ }
+}
+
+#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
+ ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/once_unittest.cc b/src/third_party/protobuf/src/google/protobuf/stubs/once_unittest.cc
new file mode 100644
index 0000000..b8f86a0
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/once_unittest.cc
@@ -0,0 +1,253 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <pthread.h>
+#endif
+
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+class OnceInitTest : public testing::Test {
+ protected:
+ void SetUp() {
+ state_ = INIT_NOT_STARTED;
+ current_test_ = this;
+ }
+
+ // Since ProtobufOnceType is only allowed to be allocated in static storage,
+ // each test must use a different pair of ProtobufOnceType objects which it
+ // must declare itself.
+ void SetOnces(ProtobufOnceType* once, ProtobufOnceType* recursive_once) {
+ once_ = once;
+ recursive_once_ = recursive_once;
+ }
+
+ void InitOnce() {
+ GoogleOnceInit(once_, &InitStatic);
+ }
+ void InitRecursiveOnce() {
+ GoogleOnceInit(recursive_once_, &InitRecursiveStatic);
+ }
+
+ void BlockInit() { init_blocker_.Lock(); }
+ void UnblockInit() { init_blocker_.Unlock(); }
+
+ class TestThread {
+ public:
+ TestThread(Closure* callback)
+ : done_(false), joined_(false), callback_(callback) {
+#ifdef _WIN32
+ thread_ = CreateThread(NULL, 0, &Start, this, 0, NULL);
+#else
+ pthread_create(&thread_, NULL, &Start, this);
+#endif
+ }
+ ~TestThread() {
+ if (!joined_) Join();
+ }
+
+ bool IsDone() {
+ MutexLock lock(&done_mutex_);
+ return done_;
+ }
+ void Join() {
+ joined_ = true;
+#ifdef _WIN32
+ WaitForSingleObject(thread_, INFINITE);
+ CloseHandle(thread_);
+#else
+ pthread_join(thread_, NULL);
+#endif
+ }
+
+ private:
+#ifdef _WIN32
+ HANDLE thread_;
+#else
+ pthread_t thread_;
+#endif
+
+ Mutex done_mutex_;
+ bool done_;
+ bool joined_;
+ Closure* callback_;
+
+#ifdef _WIN32
+ static DWORD WINAPI Start(LPVOID arg) {
+#else
+ static void* Start(void* arg) {
+#endif
+ reinterpret_cast<TestThread*>(arg)->Run();
+ return 0;
+ }
+
+ void Run() {
+ callback_->Run();
+ MutexLock lock(&done_mutex_);
+ done_ = true;
+ }
+ };
+
+ TestThread* RunInitOnceInNewThread() {
+ return new TestThread(NewCallback(this, &OnceInitTest::InitOnce));
+ }
+ TestThread* RunInitRecursiveOnceInNewThread() {
+ return new TestThread(NewCallback(this, &OnceInitTest::InitRecursiveOnce));
+ }
+
+ enum State {
+ INIT_NOT_STARTED,
+ INIT_STARTED,
+ INIT_DONE
+ };
+ State CurrentState() {
+ MutexLock lock(&mutex_);
+ return state_;
+ }
+
+ void WaitABit() {
+#ifdef _WIN32
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+ }
+
+ private:
+ Mutex mutex_;
+ Mutex init_blocker_;
+ State state_;
+ ProtobufOnceType* once_;
+ ProtobufOnceType* recursive_once_;
+
+ void Init() {
+ MutexLock lock(&mutex_);
+ EXPECT_EQ(INIT_NOT_STARTED, state_);
+ state_ = INIT_STARTED;
+ mutex_.Unlock();
+ init_blocker_.Lock();
+ init_blocker_.Unlock();
+ mutex_.Lock();
+ state_ = INIT_DONE;
+ }
+
+ static OnceInitTest* current_test_;
+ static void InitStatic() { current_test_->Init(); }
+ static void InitRecursiveStatic() { current_test_->InitOnce(); }
+};
+
+OnceInitTest* OnceInitTest::current_test_ = NULL;
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(simple_once);
+
+TEST_F(OnceInitTest, Simple) {
+ SetOnces(&simple_once, NULL);
+
+ EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
+ InitOnce();
+ EXPECT_EQ(INIT_DONE, CurrentState());
+
+ // Calling again has no effect.
+ InitOnce();
+ EXPECT_EQ(INIT_DONE, CurrentState());
+}
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once1);
+GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once2);
+
+TEST_F(OnceInitTest, Recursive) {
+ SetOnces(&recursive_once1, &recursive_once2);
+
+ EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
+ InitRecursiveOnce();
+ EXPECT_EQ(INIT_DONE, CurrentState());
+}
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_once);
+
+TEST_F(OnceInitTest, MultipleThreads) {
+ SetOnces(&multiple_threads_once, NULL);
+
+ scoped_ptr<TestThread> threads[4];
+ EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
+ for (int i = 0; i < 4; i++) {
+ threads[i].reset(RunInitOnceInNewThread());
+ }
+ for (int i = 0; i < 4; i++) {
+ threads[i]->Join();
+ }
+ EXPECT_EQ(INIT_DONE, CurrentState());
+}
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once1);
+GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once2);
+
+TEST_F(OnceInitTest, MultipleThreadsBlocked) {
+ SetOnces(&multiple_threads_blocked_once1, &multiple_threads_blocked_once2);
+
+ scoped_ptr<TestThread> threads[8];
+ EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
+
+ BlockInit();
+ for (int i = 0; i < 4; i++) {
+ threads[i].reset(RunInitOnceInNewThread());
+ }
+ for (int i = 4; i < 8; i++) {
+ threads[i].reset(RunInitRecursiveOnceInNewThread());
+ }
+
+ WaitABit();
+
+ // We should now have one thread blocked inside Init(), four blocked waiting
+ // for Init() to complete, and three blocked waiting for InitRecursive() to
+ // complete.
+ EXPECT_EQ(INIT_STARTED, CurrentState());
+ UnblockInit();
+
+ for (int i = 0; i < 8; i++) {
+ threads[i]->Join();
+ }
+ EXPECT_EQ(INIT_DONE, CurrentState());
+}
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/platform_macros.h b/src/third_party/protobuf/src/google/protobuf/stubs/platform_macros.h
new file mode 100644
index 0000000..495ed19
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/platform_macros.h
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
+#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
+
+#include <google/protobuf/stubs/common.h>
+
+// Processor architecture detection. For more info on what's defined, see:
+// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+// http://www.agner.org/optimize/calling_conventions.pdf
+// or with gcc, run: "echo | gcc -E -dM -"
+#if defined(_M_X64) || defined(__x86_64__)
+#define GOOGLE_PROTOBUF_ARCH_X64 1
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#elif defined(_M_IX86) || defined(__i386__)
+#define GOOGLE_PROTOBUF_ARCH_IA32 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__ARMEL__)
+#define GOOGLE_PROTOBUF_ARCH_ARM 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__MIPSEL__)
+#define GOOGLE_PROTOBUF_ARCH_MIPS 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__ppc__) || defined(__PPC__)
+#define GOOGLE_PROTOBUF_ARCH_PPC 1
+#define GOOGLE_PROTOBUF_ARCH_32_bit 1
+#elif defined(__pnacl__)
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#else
+#error Host architecture was not detected as supported by protobuf
+#endif
+
+#if defined(__APPLE__)
+#define GOOGLE_PROTOBUF_OS_APPLE
+#elif defined(__native_client__)
+#define GOOGLE_PROTOBUF_OS_NACL
+#endif
+
+#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/stl_util-inl.h b/src/third_party/protobuf/src/google/protobuf/stubs/stl_util-inl.h
new file mode 100644
index 0000000..a2e671b
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/stl_util-inl.h
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/util/gtl/stl_util-inl.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
+#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// STLDeleteContainerPointers()
+// For a range within a container of pointers, calls delete
+// (non-array version) on these pointers.
+// NOTE: for these three functions, we could just implement a DeleteObject
+// functor and then call for_each() on the range and functor, but this
+// requires us to pull in all of algorithm.h, which seems expensive.
+// For hash_[multi]set, it is important that this deletes behind the iterator
+// because the hash_set may call the hash function on the iterator when it is
+// advanced, which could result in the hash function trying to deference a
+// stale pointer.
+template <class ForwardIterator>
+void STLDeleteContainerPointers(ForwardIterator begin,
+ ForwardIterator end) {
+ while (begin != end) {
+ ForwardIterator temp = begin;
+ ++begin;
+ delete *temp;
+ }
+}
+
+// Inside Google, this function implements a horrible, disgusting hack in which
+// we reach into the string's private implementation and resize it without
+// initializing the new bytes. In some cases doing this can significantly
+// improve performance. However, since it's totally non-portable it has no
+// place in open source code. Feel free to fill this function in with your
+// own disgusting hack if you want the perf boost.
+inline void STLStringResizeUninitialized(string* s, size_t new_size) {
+ s->resize(new_size);
+}
+
+// Return a mutable char* pointing to a string's internal buffer,
+// which may not be null-terminated. Writing through this pointer will
+// modify the string.
+//
+// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
+// next call to a string method that invalidates iterators.
+//
+// As of 2006-04, there is no standard-blessed way of getting a
+// mutable reference to a string's internal buffer. However, issue 530
+// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
+// proposes this as the method. According to Matt Austern, this should
+// already work on all current implementations.
+inline char* string_as_array(string* str) {
+ // DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
+ return str->empty() ? NULL : &*str->begin();
+}
+
+// STLDeleteElements() deletes all the elements in an STL container and clears
+// the container. This function is suitable for use with a vector, set,
+// hash_set, or any other STL container which defines sensible begin(), end(),
+// and clear() methods.
+//
+// If container is NULL, this function is a no-op.
+//
+// As an alternative to calling STLDeleteElements() directly, consider
+// ElementDeleter (defined below), which ensures that your container's elements
+// are deleted when the ElementDeleter goes out of scope.
+template <class T>
+void STLDeleteElements(T *container) {
+ if (!container) return;
+ STLDeleteContainerPointers(container->begin(), container->end());
+ container->clear();
+}
+
+// Given an STL container consisting of (key, value) pairs, STLDeleteValues
+// deletes all the "value" components and clears the container. Does nothing
+// in the case it's given a NULL pointer.
+
+template <class T>
+void STLDeleteValues(T *v) {
+ if (!v) return;
+ for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
+ delete i->second;
+ }
+ v->clear();
+}
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_INL_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/structurally_valid.cc b/src/third_party/protobuf/src/google/protobuf/stubs/structurally_valid.cc
new file mode 100644
index 0000000..0f6afe6
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/structurally_valid.cc
@@ -0,0 +1,536 @@
+// Copyright 2005-2008 Google Inc. All Rights Reserved.
+// Author: jrm@google.com (Jim Meehan)
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// These four-byte entries compactly encode how many bytes 0..255 to delete
+// in making a string replacement, how many bytes to add 0..255, and the offset
+// 0..64k-1 of the replacement string in remap_string.
+struct RemapEntry {
+ uint8 delete_bytes;
+ uint8 add_bytes;
+ uint16 bytes_offset;
+};
+
+// Exit type codes for state tables. All but the first get stuffed into
+// signed one-byte entries. The first is only generated by executable code.
+// To distinguish from next-state entries, these must be contiguous and
+// all <= kExitNone
+typedef enum {
+ kExitDstSpaceFull = 239,
+ kExitIllegalStructure, // 240
+ kExitOK, // 241
+ kExitReject, // ...
+ kExitReplace1,
+ kExitReplace2,
+ kExitReplace3,
+ kExitReplace21,
+ kExitReplace31,
+ kExitReplace32,
+ kExitReplaceOffset1,
+ kExitReplaceOffset2,
+ kExitReplace1S0,
+ kExitSpecial,
+ kExitDoAgain,
+ kExitRejectAlt,
+ kExitNone // 255
+} ExitReason;
+
+
+// This struct represents one entire state table. The three initialized byte
+// areas are state_table, remap_base, and remap_string. state0 and state0_size
+// give the byte offset and length within state_table of the initial state --
+// table lookups are expected to start and end in this state, but for
+// truncated UTF-8 strings, may end in a different state. These allow a quick
+// test for that condition. entry_shift is 8 for tables subscripted by a full
+// byte value and 6 for space-optimized tables subscripted by only six
+// significant bits in UTF-8 continuation bytes.
+typedef struct {
+ const uint32 state0;
+ const uint32 state0_size;
+ const uint32 total_size;
+ const int max_expand;
+ const int entry_shift;
+ const int bytes_per_entry;
+ const uint32 losub;
+ const uint32 hiadd;
+ const uint8* state_table;
+ const RemapEntry* remap_base;
+ const uint8* remap_string;
+ const uint8* fast_state;
+} UTF8StateMachineObj;
+
+typedef UTF8StateMachineObj UTF8ScanObj;
+
+#define X__ (kExitIllegalStructure)
+#define RJ_ (kExitReject)
+#define S1_ (kExitReplace1)
+#define S2_ (kExitReplace2)
+#define S3_ (kExitReplace3)
+#define S21 (kExitReplace21)
+#define S31 (kExitReplace31)
+#define S32 (kExitReplace32)
+#define T1_ (kExitReplaceOffset1)
+#define T2_ (kExitReplaceOffset2)
+#define S11 (kExitReplace1S0)
+#define SP_ (kExitSpecial)
+#define D__ (kExitDoAgain)
+#define RJA (kExitRejectAlt)
+
+// Entire table has 9 state blocks of 256 entries each
+static const unsigned int utf8acceptnonsurrogates_STATE0 = 0; // state[0]
+static const unsigned int utf8acceptnonsurrogates_STATE0_SIZE = 256; // =[1]
+static const unsigned int utf8acceptnonsurrogates_TOTAL_SIZE = 2304;
+static const unsigned int utf8acceptnonsurrogates_MAX_EXPAND_X4 = 0;
+static const unsigned int utf8acceptnonsurrogates_SHIFT = 8;
+static const unsigned int utf8acceptnonsurrogates_BYTES = 1;
+static const unsigned int utf8acceptnonsurrogates_LOSUB = 0x20202020;
+static const unsigned int utf8acceptnonsurrogates_HIADD = 0x00000000;
+
+static const uint8 utf8acceptnonsurrogates[] = {
+// state[0] 0x000000 Byte 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, 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,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 3,
+ 4, 5, 5, 5, 6, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[1] 0x000080 Byte 2 of 2
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 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,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[2] 0x000000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[3] 0x001000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[4] 0x000000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[5] 0x040000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[6] 0x100000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[7] 0x00d000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[8] 0x00d800 Byte 3 of 3
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__, X__,
+};
+
+// Remap base[0] = (del, add, string_offset)
+static const RemapEntry utf8acceptnonsurrogates_remap_base[] = {
+{0, 0, 0} };
+
+// Remap string[0]
+static const unsigned char utf8acceptnonsurrogates_remap_string[] = {
+0 };
+
+static const unsigned char utf8acceptnonsurrogates_fast[256] = {
+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, 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,
+
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+static const UTF8ScanObj utf8acceptnonsurrogates_obj = {
+ utf8acceptnonsurrogates_STATE0,
+ utf8acceptnonsurrogates_STATE0_SIZE,
+ utf8acceptnonsurrogates_TOTAL_SIZE,
+ utf8acceptnonsurrogates_MAX_EXPAND_X4,
+ utf8acceptnonsurrogates_SHIFT,
+ utf8acceptnonsurrogates_BYTES,
+ utf8acceptnonsurrogates_LOSUB,
+ utf8acceptnonsurrogates_HIADD,
+ utf8acceptnonsurrogates,
+ utf8acceptnonsurrogates_remap_base,
+ utf8acceptnonsurrogates_remap_string,
+ utf8acceptnonsurrogates_fast
+};
+
+
+#undef X__
+#undef RJ_
+#undef S1_
+#undef S2_
+#undef S3_
+#undef S21
+#undef S31
+#undef S32
+#undef T1_
+#undef T2_
+#undef S11
+#undef SP_
+#undef D__
+#undef RJA
+
+// Return true if current Tbl pointer is within state0 range
+// Note that unsigned compare checks both ends of range simultaneously
+static inline bool InStateZero(const UTF8ScanObj* st, const uint8* Tbl) {
+ const uint8* Tbl0 = &st->state_table[st->state0];
+ return (static_cast<uint32>(Tbl - Tbl0) < st->state0_size);
+}
+
+// Scan a UTF-8 string based on state table.
+// Always scan complete UTF-8 characters
+// Set number of bytes scanned. Return reason for exiting
+int UTF8GenericScan(const UTF8ScanObj* st,
+ const char * str,
+ int str_length,
+ int* bytes_consumed) {
+ *bytes_consumed = 0;
+ if (str_length == 0) return kExitOK;
+
+ int eshift = st->entry_shift;
+ const uint8* isrc = reinterpret_cast<const uint8*>(str);
+ const uint8* src = isrc;
+ const uint8* srclimit = isrc + str_length;
+ const uint8* srclimit8 = srclimit - 7;
+ const uint8* Tbl_0 = &st->state_table[st->state0];
+
+ DoAgain:
+ // Do state-table scan
+ int e = 0;
+ uint8 c;
+ const uint8* Tbl2 = &st->fast_state[0];
+ const uint32 losub = st->losub;
+ const uint32 hiadd = st->hiadd;
+ // Check initial few bytes one at a time until 8-byte aligned
+ //----------------------------
+ while ((((uintptr_t)src & 0x07) != 0) &&
+ (src < srclimit) &&
+ Tbl2[src[0]] == 0) {
+ src++;
+ }
+ if (((uintptr_t)src & 0x07) == 0) {
+ // Do fast for groups of 8 identity bytes.
+ // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop,
+ // including slowing slightly on cr/lf/ht
+ //----------------------------
+ while (src < srclimit8) {
+ uint32 s0123 = (reinterpret_cast<const uint32 *>(src))[0];
+ uint32 s4567 = (reinterpret_cast<const uint32 *>(src))[1];
+ src += 8;
+ // This is a fast range check for all bytes in [lowsub..0x80-hiadd)
+ uint32 temp = (s0123 - losub) | (s0123 + hiadd) |
+ (s4567 - losub) | (s4567 + hiadd);
+ if ((temp & 0x80808080) != 0) {
+ // We typically end up here on cr/lf/ht; src was incremented
+ int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) |
+ (Tbl2[src[-6]] | Tbl2[src[-5]]);
+ if (e0123 != 0) {
+ src -= 8;
+ break;
+ } // Exit on Non-interchange
+ e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) |
+ (Tbl2[src[-2]] | Tbl2[src[-1]]);
+ if (e0123 != 0) {
+ src -= 4;
+ break;
+ } // Exit on Non-interchange
+ // Else OK, go around again
+ }
+ }
+ }
+ //----------------------------
+
+ // Byte-at-a-time scan
+ //----------------------------
+ const uint8* Tbl = Tbl_0;
+ while (src < srclimit) {
+ c = *src;
+ e = Tbl[c];
+ src++;
+ if (e >= kExitIllegalStructure) {break;}
+ Tbl = &Tbl_0[e << eshift];
+ }
+ //----------------------------
+
+
+ // Exit posibilities:
+ // Some exit code, !state0, back up over last char
+ // Some exit code, state0, back up one byte exactly
+ // source consumed, !state0, back up over partial char
+ // source consumed, state0, exit OK
+ // For illegal byte in state0, avoid backup up over PREVIOUS char
+ // For truncated last char, back up to beginning of it
+
+ if (e >= kExitIllegalStructure) {
+ // Back up over exactly one byte of rejected/illegal UTF-8 character
+ src--;
+ // Back up more if needed
+ if (!InStateZero(st, Tbl)) {
+ do {
+ src--;
+ } while ((src > isrc) && ((src[0] & 0xc0) == 0x80));
+ }
+ } else if (!InStateZero(st, Tbl)) {
+ // Back up over truncated UTF-8 character
+ e = kExitIllegalStructure;
+ do {
+ src--;
+ } while ((src > isrc) && ((src[0] & 0xc0) == 0x80));
+ } else {
+ // Normal termination, source fully consumed
+ e = kExitOK;
+ }
+
+ if (e == kExitDoAgain) {
+ // Loop back up to the fast scan
+ goto DoAgain;
+ }
+
+ *bytes_consumed = src - isrc;
+ return e;
+}
+
+int UTF8GenericScanFastAscii(const UTF8ScanObj* st,
+ const char * str,
+ int str_length,
+ int* bytes_consumed) {
+ *bytes_consumed = 0;
+ if (str_length == 0) return kExitOK;
+
+ const uint8* isrc = reinterpret_cast<const uint8*>(str);
+ const uint8* src = isrc;
+ const uint8* srclimit = isrc + str_length;
+ const uint8* srclimit8 = srclimit - 7;
+ int n;
+ int rest_consumed;
+ int exit_reason;
+ do {
+ // Check initial few bytes one at a time until 8-byte aligned
+ while ((((uintptr_t)src & 0x07) != 0) &&
+ (src < srclimit) && (src[0] < 0x80)) {
+ src++;
+ }
+ if (((uintptr_t)src & 0x07) == 0) {
+ while ((src < srclimit8) &&
+ (((reinterpret_cast<const uint32*>(src)[0] |
+ reinterpret_cast<const uint32*>(src)[1]) & 0x80808080) == 0)) {
+ src += 8;
+ }
+ }
+ while ((src < srclimit) && (src[0] < 0x80)) {
+ src++;
+ }
+ // Run state table on the rest
+ n = src - isrc;
+ exit_reason = UTF8GenericScan(st, str + n, str_length - n, &rest_consumed);
+ src += rest_consumed;
+ } while ( exit_reason == kExitDoAgain );
+
+ *bytes_consumed = src - isrc;
+ return exit_reason;
+}
+
+// Hack: On some compilers the static tables are initialized at startup.
+// We can't use them until they are initialized. However, some Protocol
+// Buffer parsing happens at static init time and may try to validate
+// UTF-8 strings. Since UTF-8 validation is only used for debugging
+// anyway, we simply always return success if initialization hasn't
+// occurred yet.
+namespace {
+
+bool module_initialized_ = false;
+
+struct InitDetector {
+ InitDetector() {
+ module_initialized_ = true;
+ }
+};
+InitDetector init_detector;
+
+} // namespace
+
+bool IsStructurallyValidUTF8(const char* buf, int len) {
+ if (!module_initialized_) return true;
+
+ int bytes_consumed = 0;
+ UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
+ buf, len, &bytes_consumed);
+ return (bytes_consumed == len);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/structurally_valid_unittest.cc b/src/third_party/protobuf/src/google/protobuf/stubs/structurally_valid_unittest.cc
new file mode 100644
index 0000000..9088888
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/structurally_valid_unittest.cc
@@ -0,0 +1,40 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+// Author: xpeng@google.com (Peter Peng)
+
+#include <google/protobuf/stubs/common.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(StructurallyValidTest, ValidUTF8String) {
+ // On GCC, this string can be written as:
+ // "abcd 1234 - \u2014\u2013\u2212"
+ // MSVC seems to interpret \u differently.
+ string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789");
+ EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(),
+ valid_str.size()));
+ // Additional check for pointer alignment
+ for (int i = 1; i < 8; ++i) {
+ EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data() + i,
+ valid_str.size() - i));
+ }
+}
+
+TEST(StructurallyValidTest, InvalidUTF8String) {
+ const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789");
+ EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(),
+ invalid_str.size()));
+ // Additional check for pointer alignment
+ for (int i = 1; i < 8; ++i) {
+ EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data() + i,
+ invalid_str.size() - i));
+ }
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/strutil.cc b/src/third_party/protobuf/src/google/protobuf/stubs/strutil.cc
new file mode 100644
index 0000000..ee07ce7
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/strutil.cc
@@ -0,0 +1,1173 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/strings/strutil.cc
+
+#include <google/protobuf/stubs/strutil.h>
+#include <errno.h>
+#include <float.h> // FLT_DIG and DBL_DIG
+#include <limits>
+#include <limits.h>
+#include <stdio.h>
+#include <iterator>
+
+#ifdef _WIN32
+// MSVC has only _snprintf, not snprintf.
+//
+// MinGW has both snprintf and _snprintf, but they appear to be different
+// functions. The former is buggy. When invoked like so:
+// char buffer[32];
+// snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f);
+// it prints "1.23000e+10". This is plainly wrong: %g should never print
+// trailing zeros after the decimal point. For some reason this bug only
+// occurs with some input values, not all. In any case, _snprintf does the
+// right thing, so we use it.
+#define snprintf _snprintf
+#endif
+
+namespace google {
+namespace protobuf {
+
+inline bool IsNaN(double value) {
+ // NaN is never equal to anything, even itself.
+ return value != value;
+}
+
+// These are defined as macros on some platforms. #undef them so that we can
+// redefine them.
+#undef isxdigit
+#undef isprint
+
+// The definitions of these in ctype.h change based on locale. Since our
+// string manipulation is all in relation to the protocol buffer and C++
+// languages, we always want to use the C locale. So, we re-define these
+// exactly as we want them.
+inline bool isxdigit(char c) {
+ return ('0' <= c && c <= '9') ||
+ ('a' <= c && c <= 'f') ||
+ ('A' <= c && c <= 'F');
+}
+
+inline bool isprint(char c) {
+ return c >= 0x20 && c <= 0x7E;
+}
+
+// ----------------------------------------------------------------------
+// StripString
+// Replaces any occurrence of the character 'remove' (or the characters
+// in 'remove') with the character 'replacewith'.
+// ----------------------------------------------------------------------
+void StripString(string* s, const char* remove, char replacewith) {
+ const char * str_start = s->c_str();
+ const char * str = str_start;
+ for (str = strpbrk(str, remove);
+ str != NULL;
+ str = strpbrk(str + 1, remove)) {
+ (*s)[str - str_start] = replacewith;
+ }
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+// Replace the "old" pattern with the "new" pattern in a string,
+// and append the result to "res". If replace_all is false,
+// it only replaces the first instance of "old."
+// ----------------------------------------------------------------------
+
+void StringReplace(const string& s, const string& oldsub,
+ const string& newsub, bool replace_all,
+ string* res) {
+ if (oldsub.empty()) {
+ res->append(s); // if empty, append the given string.
+ return;
+ }
+
+ string::size_type start_pos = 0;
+ string::size_type pos;
+ do {
+ pos = s.find(oldsub, start_pos);
+ if (pos == string::npos) {
+ break;
+ }
+ res->append(s, start_pos, pos - start_pos);
+ res->append(newsub);
+ start_pos = pos + oldsub.size(); // start searching again after the "old"
+ } while (replace_all);
+ res->append(s, start_pos, s.length() - start_pos);
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+// Give me a string and two patterns "old" and "new", and I replace
+// the first instance of "old" in the string with "new", if it
+// exists. If "global" is true; call this repeatedly until it
+// fails. RETURN a new string, regardless of whether the replacement
+// happened or not.
+// ----------------------------------------------------------------------
+
+string StringReplace(const string& s, const string& oldsub,
+ const string& newsub, bool replace_all) {
+ string ret;
+ StringReplace(s, oldsub, newsub, replace_all, &ret);
+ return ret;
+}
+
+// ----------------------------------------------------------------------
+// SplitStringUsing()
+// Split a string using a character delimiter. Append the components
+// to 'result'.
+//
+// Note: For multi-character delimiters, this routine will split on *ANY* of
+// the characters in the string, not the entire string as a single delimiter.
+// ----------------------------------------------------------------------
+template <typename ITR>
+static inline
+void SplitStringToIteratorUsing(const string& full,
+ const char* delim,
+ ITR& result) {
+ // Optimize the common case where delim is a single character.
+ if (delim[0] != '\0' && delim[1] == '\0') {
+ char c = delim[0];
+ const char* p = full.data();
+ const char* end = p + full.size();
+ while (p != end) {
+ if (*p == c) {
+ ++p;
+ } else {
+ const char* start = p;
+ while (++p != end && *p != c);
+ *result++ = string(start, p - start);
+ }
+ }
+ return;
+ }
+
+ string::size_type begin_index, end_index;
+ begin_index = full.find_first_not_of(delim);
+ while (begin_index != string::npos) {
+ end_index = full.find_first_of(delim, begin_index);
+ if (end_index == string::npos) {
+ *result++ = full.substr(begin_index);
+ return;
+ }
+ *result++ = full.substr(begin_index, (end_index - begin_index));
+ begin_index = full.find_first_not_of(delim, end_index);
+ }
+}
+
+void SplitStringUsing(const string& full,
+ const char* delim,
+ vector<string>* result) {
+ back_insert_iterator< vector<string> > it(*result);
+ SplitStringToIteratorUsing(full, delim, it);
+}
+
+// ----------------------------------------------------------------------
+// JoinStrings()
+// This merges a vector of string components with delim inserted
+// as separaters between components.
+//
+// ----------------------------------------------------------------------
+template <class ITERATOR>
+static void JoinStringsIterator(const ITERATOR& start,
+ const ITERATOR& end,
+ const char* delim,
+ string* result) {
+ GOOGLE_CHECK(result != NULL);
+ result->clear();
+ int delim_length = strlen(delim);
+
+ // Precompute resulting length so we can reserve() memory in one shot.
+ int length = 0;
+ for (ITERATOR iter = start; iter != end; ++iter) {
+ if (iter != start) {
+ length += delim_length;
+ }
+ length += iter->size();
+ }
+ result->reserve(length);
+
+ // Now combine everything.
+ for (ITERATOR iter = start; iter != end; ++iter) {
+ if (iter != start) {
+ result->append(delim, delim_length);
+ }
+ result->append(iter->data(), iter->size());
+ }
+}
+
+void JoinStrings(const vector<string>& components,
+ const char* delim,
+ string * result) {
+ JoinStringsIterator(components.begin(), components.end(), delim, result);
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeSequences()
+// This does all the unescaping that C does: \ooo, \r, \n, etc
+// Returns length of resulting string.
+// The implementation of \x parses any positive number of hex digits,
+// but it is an error if the value requires more than 8 bits, and the
+// result is truncated to 8 bits.
+//
+// The second call stores its errors in a supplied string vector.
+// If the string vector pointer is NULL, it reports the errors with LOG().
+// ----------------------------------------------------------------------
+
+#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7'))
+
+inline int hex_digit_to_int(char c) {
+ /* Assume ASCII. */
+ assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61);
+ assert(isxdigit(c));
+ int x = static_cast<unsigned char>(c);
+ if (x > '9') {
+ x += 9;
+ }
+ return x & 0xf;
+}
+
+// Protocol buffers doesn't ever care about errors, but I don't want to remove
+// the code.
+#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false)
+
+int UnescapeCEscapeSequences(const char* source, char* dest) {
+ return UnescapeCEscapeSequences(source, dest, NULL);
+}
+
+int UnescapeCEscapeSequences(const char* source, char* dest,
+ vector<string> *errors) {
+ GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented.";
+
+ char* d = dest;
+ const char* p = source;
+
+ // Small optimization for case where source = dest and there's no escaping
+ while ( p == d && *p != '\0' && *p != '\\' )
+ p++, d++;
+
+ while (*p != '\0') {
+ if (*p != '\\') {
+ *d++ = *p++;
+ } else {
+ switch ( *++p ) { // skip past the '\\'
+ case '\0':
+ LOG_STRING(ERROR, errors) << "String cannot end with \\";
+ *d = '\0';
+ return d - dest; // we're done with p
+ case 'a': *d++ = '\a'; break;
+ case 'b': *d++ = '\b'; break;
+ case 'f': *d++ = '\f'; break;
+ case 'n': *d++ = '\n'; break;
+ case 'r': *d++ = '\r'; break;
+ case 't': *d++ = '\t'; break;
+ case 'v': *d++ = '\v'; break;
+ case '\\': *d++ = '\\'; break;
+ case '?': *d++ = '\?'; break; // \? Who knew?
+ case '\'': *d++ = '\''; break;
+ case '"': *d++ = '\"'; break;
+ case '0': case '1': case '2': case '3': // octal digit: 1 to 3 digits
+ case '4': case '5': case '6': case '7': {
+ char ch = *p - '0';
+ if ( IS_OCTAL_DIGIT(p[1]) )
+ ch = ch * 8 + *++p - '0';
+ if ( IS_OCTAL_DIGIT(p[1]) ) // safe (and easy) to do this twice
+ ch = ch * 8 + *++p - '0'; // now points at last digit
+ *d++ = ch;
+ break;
+ }
+ case 'x': case 'X': {
+ if (!isxdigit(p[1])) {
+ if (p[1] == '\0') {
+ LOG_STRING(ERROR, errors) << "String cannot end with \\x";
+ } else {
+ LOG_STRING(ERROR, errors) <<
+ "\\x cannot be followed by non-hex digit: \\" << *p << p[1];
+ }
+ break;
+ }
+ unsigned int ch = 0;
+ const char *hex_start = p;
+ while (isxdigit(p[1])) // arbitrarily many hex digits
+ ch = (ch << 4) + hex_digit_to_int(*++p);
+ if (ch > 0xFF)
+ LOG_STRING(ERROR, errors) << "Value of " <<
+ "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits";
+ *d++ = ch;
+ break;
+ }
+#if 0 // TODO(kenton): Support \u and \U? Requires runetochar().
+ case 'u': {
+ // \uhhhh => convert 4 hex digits to UTF-8
+ char32 rune = 0;
+ const char *hex_start = p;
+ for (int i = 0; i < 4; ++i) {
+ if (isxdigit(p[1])) { // Look one char ahead.
+ rune = (rune << 4) + hex_digit_to_int(*++p); // Advance p.
+ } else {
+ LOG_STRING(ERROR, errors)
+ << "\\u must be followed by 4 hex digits: \\"
+ << string(hex_start, p+1-hex_start);
+ break;
+ }
+ }
+ d += runetochar(d, &rune);
+ break;
+ }
+ case 'U': {
+ // \Uhhhhhhhh => convert 8 hex digits to UTF-8
+ char32 rune = 0;
+ const char *hex_start = p;
+ for (int i = 0; i < 8; ++i) {
+ if (isxdigit(p[1])) { // Look one char ahead.
+ // Don't change rune until we're sure this
+ // is within the Unicode limit, but do advance p.
+ char32 newrune = (rune << 4) + hex_digit_to_int(*++p);
+ if (newrune > 0x10FFFF) {
+ LOG_STRING(ERROR, errors)
+ << "Value of \\"
+ << string(hex_start, p + 1 - hex_start)
+ << " exceeds Unicode limit (0x10FFFF)";
+ break;
+ } else {
+ rune = newrune;
+ }
+ } else {
+ LOG_STRING(ERROR, errors)
+ << "\\U must be followed by 8 hex digits: \\"
+ << string(hex_start, p+1-hex_start);
+ break;
+ }
+ }
+ d += runetochar(d, &rune);
+ break;
+ }
+#endif
+ default:
+ LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p;
+ }
+ p++; // read past letter we escaped
+ }
+ }
+ *d = '\0';
+ return d - dest;
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeString()
+// This does the same thing as UnescapeCEscapeSequences, but creates
+// a new string. The caller does not need to worry about allocating
+// a dest buffer. This should be used for non performance critical
+// tasks such as printing debug messages. It is safe for src and dest
+// to be the same.
+//
+// The second call stores its errors in a supplied string vector.
+// If the string vector pointer is NULL, it reports the errors with LOG().
+//
+// In the first and second calls, the length of dest is returned. In the
+// the third call, the new string is returned.
+// ----------------------------------------------------------------------
+int UnescapeCEscapeString(const string& src, string* dest) {
+ return UnescapeCEscapeString(src, dest, NULL);
+}
+
+int UnescapeCEscapeString(const string& src, string* dest,
+ vector<string> *errors) {
+ scoped_array<char> unescaped(new char[src.size() + 1]);
+ int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors);
+ GOOGLE_CHECK(dest);
+ dest->assign(unescaped.get(), len);
+ return len;
+}
+
+string UnescapeCEscapeString(const string& src) {
+ scoped_array<char> unescaped(new char[src.size() + 1]);
+ int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL);
+ return string(unescaped.get(), len);
+}
+
+// ----------------------------------------------------------------------
+// CEscapeString()
+// CHexEscapeString()
+// Copies 'src' to 'dest', escaping dangerous characters using
+// C-style escape sequences. This is very useful for preparing query
+// flags. 'src' and 'dest' should not overlap. The 'Hex' version uses
+// hexadecimal rather than octal sequences.
+// Returns the number of bytes written to 'dest' (not including the \0)
+// or -1 if there was insufficient space.
+//
+// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+int CEscapeInternal(const char* src, int src_len, char* dest,
+ int dest_len, bool use_hex, bool utf8_safe) {
+ const char* src_end = src + src_len;
+ int used = 0;
+ bool last_hex_escape = false; // true if last output char was \xNN
+
+ for (; src < src_end; src++) {
+ if (dest_len - used < 2) // Need space for two letter escape
+ return -1;
+
+ bool is_hex_escape = false;
+ switch (*src) {
+ case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break;
+ case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break;
+ case '\t': dest[used++] = '\\'; dest[used++] = 't'; break;
+ case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
+ case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
+ case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
+ default:
+ // Note that if we emit \xNN and the src character after that is a hex
+ // digit then that digit must be escaped too to prevent it being
+ // interpreted as part of the character code by C.
+ if ((!utf8_safe || static_cast<uint8>(*src) < 0x80) &&
+ (!isprint(*src) ||
+ (last_hex_escape && isxdigit(*src)))) {
+ if (dest_len - used < 4) // need space for 4 letter escape
+ return -1;
+ sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"),
+ static_cast<uint8>(*src));
+ is_hex_escape = use_hex;
+ used += 4;
+ } else {
+ dest[used++] = *src; break;
+ }
+ }
+ last_hex_escape = is_hex_escape;
+ }
+
+ if (dest_len - used < 1) // make sure that there is room for \0
+ return -1;
+
+ dest[used] = '\0'; // doesn't count towards return value though
+ return used;
+}
+
+int CEscapeString(const char* src, int src_len, char* dest, int dest_len) {
+ return CEscapeInternal(src, src_len, dest, dest_len, false, false);
+}
+
+// ----------------------------------------------------------------------
+// CEscape()
+// CHexEscape()
+// Copies 'src' to result, escaping dangerous characters using
+// C-style escape sequences. This is very useful for preparing query
+// flags. 'src' and 'dest' should not overlap. The 'Hex' version
+// hexadecimal rather than octal sequences.
+//
+// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+string CEscape(const string& src) {
+ const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
+ scoped_array<char> dest(new char[dest_length]);
+ const int len = CEscapeInternal(src.data(), src.size(),
+ dest.get(), dest_length, false, false);
+ GOOGLE_DCHECK_GE(len, 0);
+ return string(dest.get(), len);
+}
+
+namespace strings {
+
+string Utf8SafeCEscape(const string& src) {
+ const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
+ scoped_array<char> dest(new char[dest_length]);
+ const int len = CEscapeInternal(src.data(), src.size(),
+ dest.get(), dest_length, false, true);
+ GOOGLE_DCHECK_GE(len, 0);
+ return string(dest.get(), len);
+}
+
+string CHexEscape(const string& src) {
+ const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
+ scoped_array<char> dest(new char[dest_length]);
+ const int len = CEscapeInternal(src.data(), src.size(),
+ dest.get(), dest_length, true, false);
+ GOOGLE_DCHECK_GE(len, 0);
+ return string(dest.get(), len);
+}
+
+} // namespace strings
+
+// ----------------------------------------------------------------------
+// strto32_adaptor()
+// strtou32_adaptor()
+// Implementation of strto[u]l replacements that have identical
+// overflow and underflow characteristics for both ILP-32 and LP-64
+// platforms, including errno preservation in error-free calls.
+// ----------------------------------------------------------------------
+
+int32 strto32_adaptor(const char *nptr, char **endptr, int base) {
+ const int saved_errno = errno;
+ errno = 0;
+ const long result = strtol(nptr, endptr, base);
+ if (errno == ERANGE && result == LONG_MIN) {
+ return kint32min;
+ } else if (errno == ERANGE && result == LONG_MAX) {
+ return kint32max;
+ } else if (errno == 0 && result < kint32min) {
+ errno = ERANGE;
+ return kint32min;
+ } else if (errno == 0 && result > kint32max) {
+ errno = ERANGE;
+ return kint32max;
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<int32>(result);
+}
+
+uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) {
+ const int saved_errno = errno;
+ errno = 0;
+ const unsigned long result = strtoul(nptr, endptr, base);
+ if (errno == ERANGE && result == ULONG_MAX) {
+ return kuint32max;
+ } else if (errno == 0 && result > kuint32max) {
+ errno = ERANGE;
+ return kuint32max;
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<uint32>(result);
+}
+
+// ----------------------------------------------------------------------
+// FastIntToBuffer()
+// FastInt64ToBuffer()
+// FastHexToBuffer()
+// FastHex64ToBuffer()
+// FastHex32ToBuffer()
+// ----------------------------------------------------------------------
+
+// Offset into buffer where FastInt64ToBuffer places the end of string
+// null character. Also used by FastInt64ToBufferLeft.
+static const int kFastInt64ToBufferOffset = 21;
+
+char *FastInt64ToBuffer(int64 i, char* buffer) {
+ // We could collapse the positive and negative sections, but that
+ // would be slightly slower for positive numbers...
+ // 22 bytes is enough to store -2**64, -18446744073709551616.
+ char* p = buffer + kFastInt64ToBufferOffset;
+ *p-- = '\0';
+ if (i >= 0) {
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+ } else {
+ // On different platforms, % and / have different behaviors for
+ // negative numbers, so we need to jump through hoops to make sure
+ // we don't divide negative numbers.
+ if (i > -10) {
+ i = -i;
+ *p-- = '0' + i;
+ *p = '-';
+ return p;
+ } else {
+ // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+ i = i + 10;
+ i = -i;
+ *p-- = '0' + i % 10;
+ // Undo what we did a moment ago
+ i = i / 10 + 1;
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ *p = '-';
+ return p;
+ }
+ }
+}
+
+// Offset into buffer where FastInt32ToBuffer places the end of string
+// null character. Also used by FastInt32ToBufferLeft
+static const int kFastInt32ToBufferOffset = 11;
+
+// Yes, this is a duplicate of FastInt64ToBuffer. But, we need this for the
+// compiler to generate 32 bit arithmetic instructions. It's much faster, at
+// least with 32 bit binaries.
+char *FastInt32ToBuffer(int32 i, char* buffer) {
+ // We could collapse the positive and negative sections, but that
+ // would be slightly slower for positive numbers...
+ // 12 bytes is enough to store -2**32, -4294967296.
+ char* p = buffer + kFastInt32ToBufferOffset;
+ *p-- = '\0';
+ if (i >= 0) {
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+ } else {
+ // On different platforms, % and / have different behaviors for
+ // negative numbers, so we need to jump through hoops to make sure
+ // we don't divide negative numbers.
+ if (i > -10) {
+ i = -i;
+ *p-- = '0' + i;
+ *p = '-';
+ return p;
+ } else {
+ // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+ i = i + 10;
+ i = -i;
+ *p-- = '0' + i % 10;
+ // Undo what we did a moment ago
+ i = i / 10 + 1;
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ *p = '-';
+ return p;
+ }
+ }
+}
+
+char *FastHexToBuffer(int i, char* buffer) {
+ GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i;
+
+ static const char *hexdigits = "0123456789abcdef";
+ char *p = buffer + 21;
+ *p-- = '\0';
+ do {
+ *p-- = hexdigits[i & 15]; // mod by 16
+ i >>= 4; // divide by 16
+ } while (i > 0);
+ return p + 1;
+}
+
+char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) {
+ static const char *hexdigits = "0123456789abcdef";
+ buffer[num_byte] = '\0';
+ for (int i = num_byte - 1; i >= 0; i--) {
+#ifdef _M_X64
+ // MSVC x64 platform has a bug optimizing the uint32(value) in the #else
+ // block. Given that the uint32 cast was to improve performance on 32-bit
+ // platforms, we use 64-bit '&' directly.
+ buffer[i] = hexdigits[value & 0xf];
+#else
+ buffer[i] = hexdigits[uint32(value) & 0xf];
+#endif
+ value >>= 4;
+ }
+ return buffer;
+}
+
+char *FastHex64ToBuffer(uint64 value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 16);
+}
+
+char *FastHex32ToBuffer(uint32 value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 8);
+}
+
+static inline char* PlaceNum(char* p, int num, char prev_sep) {
+ *p-- = '0' + num % 10;
+ *p-- = '0' + num / 10;
+ *p-- = prev_sep;
+ return p;
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned). The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+static const char two_ASCII_digits[100][2] = {
+ {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'},
+ {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'},
+ {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'},
+ {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'},
+ {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'},
+ {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'},
+ {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'},
+ {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'},
+ {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'},
+ {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'},
+ {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'},
+ {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'},
+ {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'},
+ {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'},
+ {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'},
+ {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'},
+ {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'},
+ {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'},
+ {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'},
+ {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'}
+};
+
+char* FastUInt32ToBufferLeft(uint32 u, char* buffer) {
+ int digits;
+ const char *ASCII_digits = NULL;
+ // The idea of this implementation is to trim the number of divides to as few
+ // as possible by using multiplication and subtraction rather than mod (%),
+ // and by outputting two digits at a time rather than one.
+ // The huge-number case is first, in the hopes that the compiler will output
+ // that case in one branch-free block of code, and only output conditional
+ // branches into it from below.
+ if (u >= 1000000000) { // >= 1,000,000,000
+ digits = u / 100000000; // 100,000,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt100_000_000:
+ u -= digits * 100000000; // 100,000,000
+lt100_000_000:
+ digits = u / 1000000; // 1,000,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt1_000_000:
+ u -= digits * 1000000; // 1,000,000
+lt1_000_000:
+ digits = u / 10000; // 10,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt10_000:
+ u -= digits * 10000; // 10,000
+lt10_000:
+ digits = u / 100;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt100:
+ u -= digits * 100;
+lt100:
+ digits = u;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+done:
+ *buffer = 0;
+ return buffer;
+ }
+
+ if (u < 100) {
+ digits = u;
+ if (u >= 10) goto lt100;
+ *buffer++ = '0' + digits;
+ goto done;
+ }
+ if (u < 10000) { // 10,000
+ if (u >= 1000) goto lt10_000;
+ digits = u / 100;
+ *buffer++ = '0' + digits;
+ goto sublt100;
+ }
+ if (u < 1000000) { // 1,000,000
+ if (u >= 100000) goto lt1_000_000;
+ digits = u / 10000; // 10,000
+ *buffer++ = '0' + digits;
+ goto sublt10_000;
+ }
+ if (u < 100000000) { // 100,000,000
+ if (u >= 10000000) goto lt100_000_000;
+ digits = u / 1000000; // 1,000,000
+ *buffer++ = '0' + digits;
+ goto sublt1_000_000;
+ }
+ // we already know that u < 1,000,000,000
+ digits = u / 100000000; // 100,000,000
+ *buffer++ = '0' + digits;
+ goto sublt100_000_000;
+}
+
+char* FastInt32ToBufferLeft(int32 i, char* buffer) {
+ uint32 u = i;
+ if (i < 0) {
+ *buffer++ = '-';
+ u = -i;
+ }
+ return FastUInt32ToBufferLeft(u, buffer);
+}
+
+char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) {
+ int digits;
+ const char *ASCII_digits = NULL;
+
+ uint32 u = static_cast<uint32>(u64);
+ if (u == u64) return FastUInt32ToBufferLeft(u, buffer);
+
+ uint64 top_11_digits = u64 / 1000000000;
+ buffer = FastUInt64ToBufferLeft(top_11_digits, buffer);
+ u = u64 - (top_11_digits * 1000000000);
+
+ digits = u / 10000000; // 10,000,000
+ GOOGLE_DCHECK_LT(digits, 100);
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 10000000; // 10,000,000
+ digits = u / 100000; // 100,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 100000; // 100,000
+ digits = u / 1000; // 1,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 1000; // 1,000
+ digits = u / 10;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 10;
+ digits = u;
+ *buffer++ = '0' + digits;
+ *buffer = 0;
+ return buffer;
+}
+
+char* FastInt64ToBufferLeft(int64 i, char* buffer) {
+ uint64 u = i;
+ if (i < 0) {
+ *buffer++ = '-';
+ u = -i;
+ }
+ return FastUInt64ToBufferLeft(u, buffer);
+}
+
+// ----------------------------------------------------------------------
+// SimpleItoa()
+// Description: converts an integer to a string.
+//
+// Return value: string
+// ----------------------------------------------------------------------
+
+string SimpleItoa(int i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned int i) {
+ char buffer[kFastToBufferSize];
+ return string(buffer, (sizeof(i) == 4) ?
+ FastUInt32ToBufferLeft(i, buffer) :
+ FastUInt64ToBufferLeft(i, buffer));
+}
+
+string SimpleItoa(long i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned long i) {
+ char buffer[kFastToBufferSize];
+ return string(buffer, (sizeof(i) == 4) ?
+ FastUInt32ToBufferLeft(i, buffer) :
+ FastUInt64ToBufferLeft(i, buffer));
+}
+
+string SimpleItoa(long long i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned long long i) {
+ char buffer[kFastToBufferSize];
+ return string(buffer, (sizeof(i) == 4) ?
+ FastUInt32ToBufferLeft(i, buffer) :
+ FastUInt64ToBufferLeft(i, buffer));
+}
+
+// ----------------------------------------------------------------------
+// SimpleDtoa()
+// SimpleFtoa()
+// DoubleToBuffer()
+// FloatToBuffer()
+// We want to print the value without losing precision, but we also do
+// not want to print more digits than necessary. This turns out to be
+// trickier than it sounds. Numbers like 0.2 cannot be represented
+// exactly in binary. If we print 0.2 with a very large precision,
+// e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167".
+// On the other hand, if we set the precision too low, we lose
+// significant digits when printing numbers that actually need them.
+// It turns out there is no precision value that does the right thing
+// for all numbers.
+//
+// Our strategy is to first try printing with a precision that is never
+// over-precise, then parse the result with strtod() to see if it
+// matches. If not, we print again with a precision that will always
+// give a precise result, but may use more digits than necessary.
+//
+// An arguably better strategy would be to use the algorithm described
+// in "How to Print Floating-Point Numbers Accurately" by Steele &
+// White, e.g. as implemented by David M. Gay's dtoa(). It turns out,
+// however, that the following implementation is about as fast as
+// DMG's code. Furthermore, DMG's code locks mutexes, which means it
+// will not scale well on multi-core machines. DMG's code is slightly
+// more accurate (in that it will never use more digits than
+// necessary), but this is probably irrelevant for most users.
+//
+// Rob Pike and Ken Thompson also have an implementation of dtoa() in
+// third_party/fmt/fltfmt.cc. Their implementation is similar to this
+// one in that it makes guesses and then uses strtod() to check them.
+// Their implementation is faster because they use their own code to
+// generate the digits in the first place rather than use snprintf(),
+// thus avoiding format string parsing overhead. However, this makes
+// it considerably more complicated than the following implementation,
+// and it is embedded in a larger library. If speed turns out to be
+// an issue, we could re-implement this in terms of their
+// implementation.
+// ----------------------------------------------------------------------
+
+string SimpleDtoa(double value) {
+ char buffer[kDoubleToBufferSize];
+ return DoubleToBuffer(value, buffer);
+}
+
+string SimpleFtoa(float value) {
+ char buffer[kFloatToBufferSize];
+ return FloatToBuffer(value, buffer);
+}
+
+static inline bool IsValidFloatChar(char c) {
+ return ('0' <= c && c <= '9') ||
+ c == 'e' || c == 'E' ||
+ c == '+' || c == '-';
+}
+
+void DelocalizeRadix(char* buffer) {
+ // Fast check: if the buffer has a normal decimal point, assume no
+ // translation is needed.
+ if (strchr(buffer, '.') != NULL) return;
+
+ // Find the first unknown character.
+ while (IsValidFloatChar(*buffer)) ++buffer;
+
+ if (*buffer == '\0') {
+ // No radix character found.
+ return;
+ }
+
+ // We are now pointing at the locale-specific radix character. Replace it
+ // with '.'.
+ *buffer = '.';
+ ++buffer;
+
+ if (!IsValidFloatChar(*buffer) && *buffer != '\0') {
+ // It appears the radix was a multi-byte character. We need to remove the
+ // extra bytes.
+ char* target = buffer;
+ do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0');
+ memmove(target, buffer, strlen(buffer) + 1);
+ }
+}
+
+char* DoubleToBuffer(double value, char* buffer) {
+ // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all
+ // platforms these days. Just in case some system exists where DBL_DIG
+ // is significantly larger -- and risks overflowing our buffer -- we have
+ // this assert.
+ GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big);
+
+ if (value == numeric_limits<double>::infinity()) {
+ strcpy(buffer, "inf");
+ return buffer;
+ } else if (value == -numeric_limits<double>::infinity()) {
+ strcpy(buffer, "-inf");
+ return buffer;
+ } else if (IsNaN(value)) {
+ strcpy(buffer, "nan");
+ return buffer;
+ }
+
+ int snprintf_result =
+ snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value);
+
+ // The snprintf should never overflow because the buffer is significantly
+ // larger than the precision we asked for.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
+
+ // We need to make parsed_value volatile in order to force the compiler to
+ // write it out to the stack. Otherwise, it may keep the value in a
+ // register, and if it does that, it may keep it as a long double instead
+ // of a double. This long double may have extra bits that make it compare
+ // unequal to "value" even though it would be exactly equal if it were
+ // truncated to a double.
+ volatile double parsed_value = strtod(buffer, NULL);
+ if (parsed_value != value) {
+ int snprintf_result =
+ snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value);
+
+ // Should never overflow; see above.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
+ }
+
+ DelocalizeRadix(buffer);
+ return buffer;
+}
+
+bool safe_strtof(const char* str, float* value) {
+ char* endptr;
+ errno = 0; // errno only gets set on errors
+#if defined(_WIN32) || defined (__hpux) // has no strtof()
+ *value = strtod(str, &endptr);
+#else
+ *value = strtof(str, &endptr);
+#endif
+ return *str != 0 && *endptr == 0 && errno == 0;
+}
+
+char* FloatToBuffer(float value, char* buffer) {
+ // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all
+ // platforms these days. Just in case some system exists where FLT_DIG
+ // is significantly larger -- and risks overflowing our buffer -- we have
+ // this assert.
+ GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big);
+
+ if (value == numeric_limits<double>::infinity()) {
+ strcpy(buffer, "inf");
+ return buffer;
+ } else if (value == -numeric_limits<double>::infinity()) {
+ strcpy(buffer, "-inf");
+ return buffer;
+ } else if (IsNaN(value)) {
+ strcpy(buffer, "nan");
+ return buffer;
+ }
+
+ int snprintf_result =
+ snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value);
+
+ // The snprintf should never overflow because the buffer is significantly
+ // larger than the precision we asked for.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
+
+ float parsed_value;
+ if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
+ int snprintf_result =
+ snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value);
+
+ // Should never overflow; see above.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
+ }
+
+ DelocalizeRadix(buffer);
+ return buffer;
+}
+
+// ----------------------------------------------------------------------
+// NoLocaleStrtod()
+// This code will make you cry.
+// ----------------------------------------------------------------------
+
+// Returns a string identical to *input except that the character pointed to
+// by radix_pos (which should be '.') is replaced with the locale-specific
+// radix character.
+string LocalizeRadix(const char* input, const char* radix_pos) {
+ // Determine the locale-specific radix character by calling sprintf() to
+ // print the number 1.5, then stripping off the digits. As far as I can
+ // tell, this is the only portable, thread-safe way to get the C library
+ // to divuldge the locale's radix character. No, localeconv() is NOT
+ // thread-safe.
+ char temp[16];
+ int size = sprintf(temp, "%.1f", 1.5);
+ GOOGLE_CHECK_EQ(temp[0], '1');
+ GOOGLE_CHECK_EQ(temp[size-1], '5');
+ GOOGLE_CHECK_LE(size, 6);
+
+ // Now replace the '.' in the input with it.
+ string result;
+ result.reserve(strlen(input) + size - 3);
+ result.append(input, radix_pos);
+ result.append(temp + 1, size - 2);
+ result.append(radix_pos + 1);
+ return result;
+}
+
+double NoLocaleStrtod(const char* text, char** original_endptr) {
+ // We cannot simply set the locale to "C" temporarily with setlocale()
+ // as this is not thread-safe. Instead, we try to parse in the current
+ // locale first. If parsing stops at a '.' character, then this is a
+ // pretty good hint that we're actually in some other locale in which
+ // '.' is not the radix character.
+
+ char* temp_endptr;
+ double result = strtod(text, &temp_endptr);
+ if (original_endptr != NULL) *original_endptr = temp_endptr;
+ if (*temp_endptr != '.') return result;
+
+ // Parsing halted on a '.'. Perhaps we're in a different locale? Let's
+ // try to replace the '.' with a locale-specific radix character and
+ // try again.
+ string localized = LocalizeRadix(text, temp_endptr);
+ const char* localized_cstr = localized.c_str();
+ char* localized_endptr;
+ result = strtod(localized_cstr, &localized_endptr);
+ if ((localized_endptr - localized_cstr) >
+ (temp_endptr - text)) {
+ // This attempt got further, so replacing the decimal must have helped.
+ // Update original_endptr to point at the right location.
+ if (original_endptr != NULL) {
+ // size_diff is non-zero if the localized radix has multiple bytes.
+ int size_diff = localized.size() - strlen(text);
+ // const_cast is necessary to match the strtod() interface.
+ *original_endptr = const_cast<char*>(
+ text + (localized_endptr - localized_cstr - size_diff));
+ }
+ }
+
+ return result;
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/strutil.h b/src/third_party/protobuf/src/google/protobuf/stubs/strutil.h
new file mode 100644
index 0000000..4a79c22
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/strutil.h
@@ -0,0 +1,457 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/strings/strutil.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+
+#include <stdlib.h>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _MSC_VER
+#define strtoll _strtoi64
+#define strtoull _strtoui64
+#elif defined(__DECCXX) && defined(__osf__)
+// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit.
+#define strtoll strtol
+#define strtoull strtoul
+#endif
+
+// ----------------------------------------------------------------------
+// ascii_isalnum()
+// Check if an ASCII character is alphanumeric. We can't use ctype's
+// isalnum() because it is affected by locale. This function is applied
+// to identifiers in the protocol buffer language, not to natural-language
+// strings, so locale should not be taken into account.
+// ascii_isdigit()
+// Like above, but only accepts digits.
+// ----------------------------------------------------------------------
+
+inline bool ascii_isalnum(char c) {
+ return ('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ ('0' <= c && c <= '9');
+}
+
+inline bool ascii_isdigit(char c) {
+ return ('0' <= c && c <= '9');
+}
+
+// ----------------------------------------------------------------------
+// HasPrefixString()
+// Check if a string begins with a given prefix.
+// StripPrefixString()
+// Given a string and a putative prefix, returns the string minus the
+// prefix string if the prefix matches, otherwise the original
+// string.
+// ----------------------------------------------------------------------
+inline bool HasPrefixString(const string& str,
+ const string& prefix) {
+ return str.size() >= prefix.size() &&
+ str.compare(0, prefix.size(), prefix) == 0;
+}
+
+inline string StripPrefixString(const string& str, const string& prefix) {
+ if (HasPrefixString(str, prefix)) {
+ return str.substr(prefix.size());
+ } else {
+ return str;
+ }
+}
+
+// ----------------------------------------------------------------------
+// HasSuffixString()
+// Return true if str ends in suffix.
+// StripSuffixString()
+// Given a string and a putative suffix, returns the string minus the
+// suffix string if the suffix matches, otherwise the original
+// string.
+// ----------------------------------------------------------------------
+inline bool HasSuffixString(const string& str,
+ const string& suffix) {
+ return str.size() >= suffix.size() &&
+ str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+inline string StripSuffixString(const string& str, const string& suffix) {
+ if (HasSuffixString(str, suffix)) {
+ return str.substr(0, str.size() - suffix.size());
+ } else {
+ return str;
+ }
+}
+
+// ----------------------------------------------------------------------
+// StripString
+// Replaces any occurrence of the character 'remove' (or the characters
+// in 'remove') with the character 'replacewith'.
+// Good for keeping html characters or protocol characters (\t) out
+// of places where they might cause a problem.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove,
+ char replacewith);
+
+// ----------------------------------------------------------------------
+// LowerString()
+// UpperString()
+// Convert the characters in "s" to lowercase or uppercase. ASCII-only:
+// these functions intentionally ignore locale because they are applied to
+// identifiers used in the Protocol Buffer language, not to natural-language
+// strings.
+// ----------------------------------------------------------------------
+
+inline void LowerString(string * s) {
+ string::iterator end = s->end();
+ for (string::iterator i = s->begin(); i != end; ++i) {
+ // tolower() changes based on locale. We don't want this!
+ if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
+ }
+}
+
+inline void UpperString(string * s) {
+ string::iterator end = s->end();
+ for (string::iterator i = s->begin(); i != end; ++i) {
+ // toupper() changes based on locale. We don't want this!
+ if ('a' <= *i && *i <= 'z') *i += 'A' - 'a';
+ }
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+// Give me a string and two patterns "old" and "new", and I replace
+// the first instance of "old" in the string with "new", if it
+// exists. RETURN a new string, regardless of whether the replacement
+// happened or not.
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub,
+ const string& newsub, bool replace_all);
+
+// ----------------------------------------------------------------------
+// SplitStringUsing()
+// Split a string using a character delimiter. Append the components
+// to 'result'. If there are consecutive delimiters, this function skips
+// over all of them.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim,
+ vector<string>* res);
+
+// ----------------------------------------------------------------------
+// JoinStrings()
+// These methods concatenate a vector of strings into a C++ string, using
+// the C-string "delim" as a separator between components. There are two
+// flavors of the function, one flavor returns the concatenated string,
+// another takes a pointer to the target string. In the latter case the
+// target string is cleared and overwritten.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void JoinStrings(const vector<string>& components,
+ const char* delim, string* result);
+
+inline string JoinStrings(const vector<string>& components,
+ const char* delim) {
+ string result;
+ JoinStrings(components, delim, &result);
+ return result;
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeSequences()
+// Copies "source" to "dest", rewriting C-style escape sequences
+// -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII
+// equivalents. "dest" must be sufficiently large to hold all
+// the characters in the rewritten string (i.e. at least as large
+// as strlen(source) + 1 should be safe, since the replacements
+// are always shorter than the original escaped sequences). It's
+// safe for source and dest to be the same. RETURNS the length
+// of dest.
+//
+// It allows hex sequences \xhh, or generally \xhhhhh with an
+// arbitrary number of hex digits, but all of them together must
+// specify a value of a single byte (e.g. \x0045 is equivalent
+// to \x45, and \x1234 is erroneous).
+//
+// It also allows escape sequences of the form \uhhhh (exactly four
+// hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight
+// hex digits, upper or lower case) to specify a Unicode code
+// point. The dest array will contain the UTF8-encoded version of
+// that code-point (e.g., if source contains \u2019, then dest will
+// contain the three bytes 0xE2, 0x80, and 0x99).
+//
+// Errors: In the first form of the call, errors are reported with
+// LOG(ERROR). The same is true for the second form of the call if
+// the pointer to the string vector is NULL; otherwise, error
+// messages are stored in the vector. In either case, the effect on
+// the dest array is not defined, but rest of the source will be
+// processed.
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest);
+LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest,
+ vector<string> *errors);
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeString()
+// This does the same thing as UnescapeCEscapeSequences, but creates
+// a new string. The caller does not need to worry about allocating
+// a dest buffer. This should be used for non performance critical
+// tasks such as printing debug messages. It is safe for src and dest
+// to be the same.
+//
+// The second call stores its errors in a supplied string vector.
+// If the string vector pointer is NULL, it reports the errors with LOG().
+//
+// In the first and second calls, the length of dest is returned. In the
+// the third call, the new string is returned.
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest);
+LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest,
+ vector<string> *errors);
+LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src);
+
+// ----------------------------------------------------------------------
+// CEscapeString()
+// Copies 'src' to 'dest', escaping dangerous characters using
+// C-style escape sequences. This is very useful for preparing query
+// flags. 'src' and 'dest' should not overlap.
+// Returns the number of bytes written to 'dest' (not including the \0)
+// or -1 if there was insufficient space.
+//
+// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len,
+ char* dest, int dest_len);
+
+// ----------------------------------------------------------------------
+// CEscape()
+// More convenient form of CEscapeString: returns result as a "string".
+// This version is slower than CEscapeString() because it does more
+// allocation. However, it is much more convenient to use in
+// non-speed-critical code like logging messages etc.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string CEscape(const string& src);
+
+namespace strings {
+// Like CEscape() but does not escape bytes with the upper bit set.
+LIBPROTOBUF_EXPORT string Utf8SafeCEscape(const string& src);
+
+// Like CEscape() but uses hex (\x) escapes instead of octals.
+LIBPROTOBUF_EXPORT string CHexEscape(const string& src);
+} // namespace strings
+
+// ----------------------------------------------------------------------
+// strto32()
+// strtou32()
+// strto64()
+// strtou64()
+// Architecture-neutral plug compatible replacements for strtol() and
+// strtoul(). Long's have different lengths on ILP-32 and LP-64
+// platforms, so using these is safer, from the point of view of
+// overflow behavior, than using the standard libc functions.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr,
+ int base);
+LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr,
+ int base);
+
+inline int32 strto32(const char *nptr, char **endptr, int base) {
+ if (sizeof(int32) == sizeof(long))
+ return strtol(nptr, endptr, base);
+ else
+ return strto32_adaptor(nptr, endptr, base);
+}
+
+inline uint32 strtou32(const char *nptr, char **endptr, int base) {
+ if (sizeof(uint32) == sizeof(unsigned long))
+ return strtoul(nptr, endptr, base);
+ else
+ return strtou32_adaptor(nptr, endptr, base);
+}
+
+// For now, long long is 64-bit on all the platforms we care about, so these
+// functions can simply pass the call to strto[u]ll.
+inline int64 strto64(const char *nptr, char **endptr, int base) {
+ GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long),
+ sizeof_int64_is_not_sizeof_long_long);
+ return strtoll(nptr, endptr, base);
+}
+
+inline uint64 strtou64(const char *nptr, char **endptr, int base) {
+ GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long),
+ sizeof_uint64_is_not_sizeof_long_long);
+ return strtoull(nptr, endptr, base);
+}
+
+// ----------------------------------------------------------------------
+// FastIntToBuffer()
+// FastHexToBuffer()
+// FastHex64ToBuffer()
+// FastHex32ToBuffer()
+// FastTimeToBuffer()
+// These are intended for speed. FastIntToBuffer() assumes the
+// integer is non-negative. FastHexToBuffer() puts output in
+// hex rather than decimal. FastTimeToBuffer() puts the output
+// into RFC822 format.
+//
+// FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format,
+// padded to exactly 16 bytes (plus one byte for '\0')
+//
+// FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format,
+// padded to exactly 8 bytes (plus one byte for '\0')
+//
+// All functions take the output buffer as an arg.
+// They all return a pointer to the beginning of the output,
+// which may not be the beginning of the input buffer.
+// ----------------------------------------------------------------------
+
+// Suggested buffer size for FastToBuffer functions. Also works with
+// DoubleToBuffer() and FloatToBuffer().
+static const int kFastToBufferSize = 32;
+
+LIBPROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer);
+char* FastUInt32ToBuffer(uint32 i, char* buffer); // inline below
+char* FastUInt64ToBuffer(uint64 i, char* buffer); // inline below
+LIBPROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer);
+
+// at least 22 bytes long
+inline char* FastIntToBuffer(int i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastUIntToBuffer(unsigned int i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+inline char* FastLongToBuffer(long i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastULongToBuffer(unsigned long i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned). The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer);
+
+// Just define these in terms of the above.
+inline char* FastUInt32ToBuffer(uint32 i, char* buffer) {
+ FastUInt32ToBufferLeft(i, buffer);
+ return buffer;
+}
+inline char* FastUInt64ToBuffer(uint64 i, char* buffer) {
+ FastUInt64ToBufferLeft(i, buffer);
+ return buffer;
+}
+
+// ----------------------------------------------------------------------
+// SimpleItoa()
+// Description: converts an integer to a string.
+//
+// Return value: string
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string SimpleItoa(int i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i);
+LIBPROTOBUF_EXPORT string SimpleItoa(long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(long long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i);
+
+// ----------------------------------------------------------------------
+// SimpleDtoa()
+// SimpleFtoa()
+// DoubleToBuffer()
+// FloatToBuffer()
+// Description: converts a double or float to a string which, if
+// passed to NoLocaleStrtod(), will produce the exact same original double
+// (except in case of NaN; all NaNs are considered the same value).
+// We try to keep the string short but it's not guaranteed to be as
+// short as possible.
+//
+// DoubleToBuffer() and FloatToBuffer() write the text to the given
+// buffer and return it. The buffer must be at least
+// kDoubleToBufferSize bytes for doubles and kFloatToBufferSize
+// bytes for floats. kFastToBufferSize is also guaranteed to be large
+// enough to hold either.
+//
+// Return value: string
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string SimpleDtoa(double value);
+LIBPROTOBUF_EXPORT string SimpleFtoa(float value);
+
+LIBPROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer);
+LIBPROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer);
+
+// In practice, doubles should never need more than 24 bytes and floats
+// should never need more than 14 (including null terminators), but we
+// overestimate to be safe.
+static const int kDoubleToBufferSize = 32;
+static const int kFloatToBufferSize = 24;
+
+// ----------------------------------------------------------------------
+// NoLocaleStrtod()
+// Exactly like strtod(), except it always behaves as if in the "C"
+// locale (i.e. decimal points must be '.'s).
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT double NoLocaleStrtod(const char* text, char** endptr);
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+
+
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/strutil_unittest.cc b/src/third_party/protobuf/src/google/protobuf/stubs/strutil_unittest.cc
new file mode 100644
index 0000000..b9c9253
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/strutil_unittest.cc
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/strutil.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <locale.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+// TODO(kenton): Copy strutil tests from google3?
+
+TEST(StringUtilityTest, ImmuneToLocales) {
+ // Remember the old locale.
+ char* old_locale_cstr = setlocale(LC_NUMERIC, NULL);
+ ASSERT_TRUE(old_locale_cstr != NULL);
+ string old_locale = old_locale_cstr;
+
+ // Set the locale to "C".
+ ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != NULL);
+
+ EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL));
+ EXPECT_EQ("1.5", SimpleDtoa(1.5));
+ EXPECT_EQ("1.5", SimpleFtoa(1.5));
+
+ // Verify that the endptr is set correctly even if not all text was parsed.
+ const char* text = "1.5f";
+ char* endptr;
+ EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr));
+ EXPECT_EQ(3, endptr - text);
+
+ if (setlocale(LC_NUMERIC, "es_ES") == NULL &&
+ setlocale(LC_NUMERIC, "es_ES.utf8") == NULL) {
+ // Some systems may not have the desired locale available.
+ GOOGLE_LOG(WARNING)
+ << "Couldn't set locale to es_ES. Skipping this test.";
+ } else {
+ EXPECT_EQ(1.5, NoLocaleStrtod("1.5", NULL));
+ EXPECT_EQ("1.5", SimpleDtoa(1.5));
+ EXPECT_EQ("1.5", SimpleFtoa(1.5));
+ EXPECT_EQ(1.5, NoLocaleStrtod(text, &endptr));
+ EXPECT_EQ(3, endptr - text);
+ }
+
+ // Return to original locale.
+ setlocale(LC_NUMERIC, old_locale.c_str());
+}
+
+} // anonymous namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/substitute.cc b/src/third_party/protobuf/src/google/protobuf/stubs/substitute.cc
new file mode 100644
index 0000000..b542aaa
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/substitute.cc
@@ -0,0 +1,134 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace strings {
+
+using internal::SubstituteArg;
+
+// Returns the number of args in arg_array which were passed explicitly
+// to Substitute().
+static int CountSubstituteArgs(const SubstituteArg* const* args_array) {
+ int count = 0;
+ while (args_array[count] != NULL && args_array[count]->size() != -1) {
+ ++count;
+ }
+ return count;
+}
+
+string Substitute(
+ const char* format,
+ const SubstituteArg& arg0, const SubstituteArg& arg1,
+ const SubstituteArg& arg2, const SubstituteArg& arg3,
+ const SubstituteArg& arg4, const SubstituteArg& arg5,
+ const SubstituteArg& arg6, const SubstituteArg& arg7,
+ const SubstituteArg& arg8, const SubstituteArg& arg9) {
+ string result;
+ SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4,
+ arg5, arg6, arg7, arg8, arg9);
+ return result;
+}
+
+void SubstituteAndAppend(
+ string* output, const char* format,
+ const SubstituteArg& arg0, const SubstituteArg& arg1,
+ const SubstituteArg& arg2, const SubstituteArg& arg3,
+ const SubstituteArg& arg4, const SubstituteArg& arg5,
+ const SubstituteArg& arg6, const SubstituteArg& arg7,
+ const SubstituteArg& arg8, const SubstituteArg& arg9) {
+ const SubstituteArg* const args_array[] = {
+ &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, NULL
+ };
+
+ // Determine total size needed.
+ int size = 0;
+ for (int i = 0; format[i] != '\0'; i++) {
+ if (format[i] == '$') {
+ if (ascii_isdigit(format[i+1])) {
+ int index = format[i+1] - '0';
+ if (args_array[index]->size() == -1) {
+ GOOGLE_LOG(DFATAL)
+ << "strings::Substitute format string invalid: asked for \"$"
+ << index << "\", but only " << CountSubstituteArgs(args_array)
+ << " args were given. Full format string was: \""
+ << CEscape(format) << "\".";
+ return;
+ }
+ size += args_array[index]->size();
+ ++i; // Skip next char.
+ } else if (format[i+1] == '$') {
+ ++size;
+ ++i; // Skip next char.
+ } else {
+ GOOGLE_LOG(DFATAL)
+ << "Invalid strings::Substitute() format string: \""
+ << CEscape(format) << "\".";
+ return;
+ }
+ } else {
+ ++size;
+ }
+ }
+
+ if (size == 0) return;
+
+ // Build the string.
+ int original_size = output->size();
+ STLStringResizeUninitialized(output, original_size + size);
+ char* target = string_as_array(output) + original_size;
+ for (int i = 0; format[i] != '\0'; i++) {
+ if (format[i] == '$') {
+ if (ascii_isdigit(format[i+1])) {
+ const SubstituteArg* src = args_array[format[i+1] - '0'];
+ memcpy(target, src->data(), src->size());
+ target += src->size();
+ ++i; // Skip next char.
+ } else if (format[i+1] == '$') {
+ *target++ = '$';
+ ++i; // Skip next char.
+ }
+ } else {
+ *target++ = format[i];
+ }
+ }
+
+ GOOGLE_DCHECK_EQ(target - output->data(), output->size());
+}
+
+} // namespace strings
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/stubs/substitute.h b/src/third_party/protobuf/src/google/protobuf/stubs/substitute.h
new file mode 100644
index 0000000..2581793
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/stubs/substitute.h
@@ -0,0 +1,170 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// from google3/strings/substitute.h
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
+#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
+
+namespace google {
+namespace protobuf {
+namespace strings {
+
+// ----------------------------------------------------------------------
+// strings::Substitute()
+// strings::SubstituteAndAppend()
+// Kind of like StringPrintf, but different.
+//
+// Example:
+// string GetMessage(string first_name, string last_name, int age) {
+// return strings::Substitute("My name is $0 $1 and I am $2 years old.",
+// first_name, last_name, age);
+// }
+//
+// Differences from StringPrintf:
+// * The format string does not identify the types of arguments.
+// Instead, the magic of C++ deals with this for us. See below
+// for a list of accepted types.
+// * Substitutions in the format string are identified by a '$'
+// followed by a digit. So, you can use arguments out-of-order and
+// use the same argument multiple times.
+// * It's much faster than StringPrintf.
+//
+// Supported types:
+// * Strings (const char*, const string&)
+// * Note that this means you do not have to add .c_str() to all of
+// your strings. In fact, you shouldn't; it will be slower.
+// * int32, int64, uint32, uint64: Formatted using SimpleItoa().
+// * float, double: Formatted using SimpleFtoa() and SimpleDtoa().
+// * bool: Printed as "true" or "false".
+//
+// SubstituteAndAppend() is like Substitute() but appends the result to
+// *output. Example:
+//
+// string str;
+// strings::SubstituteAndAppend(&str,
+// "My name is $0 $1 and I am $2 years old.",
+// first_name, last_name, age);
+//
+// Substitute() is significantly faster than StringPrintf(). For very
+// large strings, it may be orders of magnitude faster.
+// ----------------------------------------------------------------------
+
+namespace internal { // Implementation details.
+
+class SubstituteArg {
+ public:
+ inline SubstituteArg(const char* value)
+ : text_(value), size_(strlen(text_)) {}
+ inline SubstituteArg(const string& value)
+ : text_(value.data()), size_(value.size()) {}
+
+ // Indicates that no argument was given.
+ inline explicit SubstituteArg()
+ : text_(NULL), size_(-1) {}
+
+ // Primitives
+ // We don't overload for signed and unsigned char because if people are
+ // explicitly declaring their chars as signed or unsigned then they are
+ // probably actually using them as 8-bit integers and would probably
+ // prefer an integer representation. But, we don't really know. So, we
+ // make the caller decide what to do.
+ inline SubstituteArg(char value)
+ : text_(scratch_), size_(1) { scratch_[0] = value; }
+ inline SubstituteArg(short value)
+ : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(unsigned short value)
+ : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(int value)
+ : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(unsigned int value)
+ : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(long value)
+ : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(unsigned long value)
+ : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(long long value)
+ : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(unsigned long long value)
+ : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(float value)
+ : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(double value)
+ : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(bool value)
+ : text_(value ? "true" : "false"), size_(strlen(text_)) {}
+
+ inline const char* data() const { return text_; }
+ inline int size() const { return size_; }
+
+ private:
+ const char* text_;
+ int size_;
+ char scratch_[kFastToBufferSize];
+};
+
+} // namespace internal
+
+LIBPROTOBUF_EXPORT string Substitute(
+ const char* format,
+ const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg9 = internal::SubstituteArg());
+
+LIBPROTOBUF_EXPORT void SubstituteAndAppend(
+ string* output, const char* format,
+ const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg9 = internal::SubstituteArg());
+
+} // namespace strings
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
diff --git a/src/third_party/protobuf/src/google/protobuf/test_util.cc b/src/third_party/protobuf/src/google/protobuf/test_util.cc
new file mode 100644
index 0000000..af8b390
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/test_util.cc
@@ -0,0 +1,2854 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifdef _WIN32
+// Verify that #including windows.h does not break anything (e.g. because
+// windows.h #defines GetMessage() as a macro).
+#include <windows.h>
+#endif
+
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+void TestUtil::SetAllFields(unittest::TestAllTypes* message) {
+ message->set_optional_int32 (101);
+ message->set_optional_int64 (102);
+ message->set_optional_uint32 (103);
+ message->set_optional_uint64 (104);
+ message->set_optional_sint32 (105);
+ message->set_optional_sint64 (106);
+ message->set_optional_fixed32 (107);
+ message->set_optional_fixed64 (108);
+ message->set_optional_sfixed32(109);
+ message->set_optional_sfixed64(110);
+ message->set_optional_float (111);
+ message->set_optional_double (112);
+ message->set_optional_bool (true);
+ message->set_optional_string ("115");
+ message->set_optional_bytes ("116");
+
+ message->mutable_optionalgroup ()->set_a(117);
+ message->mutable_optional_nested_message ()->set_bb(118);
+ message->mutable_optional_foreign_message()->set_c(119);
+ message->mutable_optional_import_message ()->set_d(120);
+
+ message->set_optional_nested_enum (unittest::TestAllTypes::BAZ);
+ message->set_optional_foreign_enum(unittest::FOREIGN_BAZ );
+ message->set_optional_import_enum (unittest_import::IMPORT_BAZ);
+
+ // StringPiece and Cord fields are only accessible via reflection in the
+ // open source release; see comments in compiler/cpp/string_field.cc.
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->SetString(
+ message,
+ message->GetDescriptor()->FindFieldByName("optional_string_piece"),
+ "124");
+ message->GetReflection()->SetString(
+ message,
+ message->GetDescriptor()->FindFieldByName("optional_cord"),
+ "125");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+ // -----------------------------------------------------------------
+
+ message->add_repeated_int32 (201);
+ message->add_repeated_int64 (202);
+ message->add_repeated_uint32 (203);
+ message->add_repeated_uint64 (204);
+ message->add_repeated_sint32 (205);
+ message->add_repeated_sint64 (206);
+ message->add_repeated_fixed32 (207);
+ message->add_repeated_fixed64 (208);
+ message->add_repeated_sfixed32(209);
+ message->add_repeated_sfixed64(210);
+ message->add_repeated_float (211);
+ message->add_repeated_double (212);
+ message->add_repeated_bool (true);
+ message->add_repeated_string ("215");
+ message->add_repeated_bytes ("216");
+
+ message->add_repeatedgroup ()->set_a(217);
+ message->add_repeated_nested_message ()->set_bb(218);
+ message->add_repeated_foreign_message()->set_c(219);
+ message->add_repeated_import_message ()->set_d(220);
+
+ message->add_repeated_nested_enum (unittest::TestAllTypes::BAR);
+ message->add_repeated_foreign_enum(unittest::FOREIGN_BAR );
+ message->add_repeated_import_enum (unittest_import::IMPORT_BAR);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->AddString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+ "224");
+ message->GetReflection()->AddString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_cord"),
+ "225");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+ // Add a second one of each field.
+ message->add_repeated_int32 (301);
+ message->add_repeated_int64 (302);
+ message->add_repeated_uint32 (303);
+ message->add_repeated_uint64 (304);
+ message->add_repeated_sint32 (305);
+ message->add_repeated_sint64 (306);
+ message->add_repeated_fixed32 (307);
+ message->add_repeated_fixed64 (308);
+ message->add_repeated_sfixed32(309);
+ message->add_repeated_sfixed64(310);
+ message->add_repeated_float (311);
+ message->add_repeated_double (312);
+ message->add_repeated_bool (false);
+ message->add_repeated_string ("315");
+ message->add_repeated_bytes ("316");
+
+ message->add_repeatedgroup ()->set_a(317);
+ message->add_repeated_nested_message ()->set_bb(318);
+ message->add_repeated_foreign_message()->set_c(319);
+ message->add_repeated_import_message ()->set_d(320);
+
+ message->add_repeated_nested_enum (unittest::TestAllTypes::BAZ);
+ message->add_repeated_foreign_enum(unittest::FOREIGN_BAZ );
+ message->add_repeated_import_enum (unittest_import::IMPORT_BAZ);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->AddString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+ "324");
+ message->GetReflection()->AddString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_cord"),
+ "325");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+ // -----------------------------------------------------------------
+
+ message->set_default_int32 (401);
+ message->set_default_int64 (402);
+ message->set_default_uint32 (403);
+ message->set_default_uint64 (404);
+ message->set_default_sint32 (405);
+ message->set_default_sint64 (406);
+ message->set_default_fixed32 (407);
+ message->set_default_fixed64 (408);
+ message->set_default_sfixed32(409);
+ message->set_default_sfixed64(410);
+ message->set_default_float (411);
+ message->set_default_double (412);
+ message->set_default_bool (false);
+ message->set_default_string ("415");
+ message->set_default_bytes ("416");
+
+ message->set_default_nested_enum (unittest::TestAllTypes::FOO);
+ message->set_default_foreign_enum(unittest::FOREIGN_FOO );
+ message->set_default_import_enum (unittest_import::IMPORT_FOO);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->SetString(
+ message,
+ message->GetDescriptor()->FindFieldByName("default_string_piece"),
+ "424");
+ message->GetReflection()->SetString(
+ message,
+ message->GetDescriptor()->FindFieldByName("default_cord"),
+ "425");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyRepeatedFields(unittest::TestAllTypes* message) {
+ message->set_repeated_int32 (1, 501);
+ message->set_repeated_int64 (1, 502);
+ message->set_repeated_uint32 (1, 503);
+ message->set_repeated_uint64 (1, 504);
+ message->set_repeated_sint32 (1, 505);
+ message->set_repeated_sint64 (1, 506);
+ message->set_repeated_fixed32 (1, 507);
+ message->set_repeated_fixed64 (1, 508);
+ message->set_repeated_sfixed32(1, 509);
+ message->set_repeated_sfixed64(1, 510);
+ message->set_repeated_float (1, 511);
+ message->set_repeated_double (1, 512);
+ message->set_repeated_bool (1, true);
+ message->set_repeated_string (1, "515");
+ message->set_repeated_bytes (1, "516");
+
+ message->mutable_repeatedgroup (1)->set_a(517);
+ message->mutable_repeated_nested_message (1)->set_bb(518);
+ message->mutable_repeated_foreign_message(1)->set_c(519);
+ message->mutable_repeated_import_message (1)->set_d(520);
+
+ message->set_repeated_nested_enum (1, unittest::TestAllTypes::FOO);
+ message->set_repeated_foreign_enum(1, unittest::FOREIGN_FOO );
+ message->set_repeated_import_enum (1, unittest_import::IMPORT_FOO);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ message->GetReflection()->SetRepeatedString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+ 1, "524");
+ message->GetReflection()->SetRepeatedString(
+ message,
+ message->GetDescriptor()->FindFieldByName("repeated_cord"),
+ 1, "525");
+#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectAllFieldsSet(const unittest::TestAllTypes& message) {
+ EXPECT_TRUE(message.has_optional_int32 ());
+ EXPECT_TRUE(message.has_optional_int64 ());
+ EXPECT_TRUE(message.has_optional_uint32 ());
+ EXPECT_TRUE(message.has_optional_uint64 ());
+ EXPECT_TRUE(message.has_optional_sint32 ());
+ EXPECT_TRUE(message.has_optional_sint64 ());
+ EXPECT_TRUE(message.has_optional_fixed32 ());
+ EXPECT_TRUE(message.has_optional_fixed64 ());
+ EXPECT_TRUE(message.has_optional_sfixed32());
+ EXPECT_TRUE(message.has_optional_sfixed64());
+ EXPECT_TRUE(message.has_optional_float ());
+ EXPECT_TRUE(message.has_optional_double ());
+ EXPECT_TRUE(message.has_optional_bool ());
+ EXPECT_TRUE(message.has_optional_string ());
+ EXPECT_TRUE(message.has_optional_bytes ());
+
+ EXPECT_TRUE(message.has_optionalgroup ());
+ EXPECT_TRUE(message.has_optional_nested_message ());
+ EXPECT_TRUE(message.has_optional_foreign_message());
+ EXPECT_TRUE(message.has_optional_import_message ());
+
+ EXPECT_TRUE(message.optionalgroup ().has_a());
+ EXPECT_TRUE(message.optional_nested_message ().has_bb());
+ EXPECT_TRUE(message.optional_foreign_message().has_c());
+ EXPECT_TRUE(message.optional_import_message ().has_d());
+
+ EXPECT_TRUE(message.has_optional_nested_enum ());
+ EXPECT_TRUE(message.has_optional_foreign_enum());
+ EXPECT_TRUE(message.has_optional_import_enum ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ EXPECT_TRUE(message.has_optional_string_piece());
+ EXPECT_TRUE(message.has_optional_cord());
+#endif
+
+ EXPECT_EQ(101 , message.optional_int32 ());
+ EXPECT_EQ(102 , message.optional_int64 ());
+ EXPECT_EQ(103 , message.optional_uint32 ());
+ EXPECT_EQ(104 , message.optional_uint64 ());
+ EXPECT_EQ(105 , message.optional_sint32 ());
+ EXPECT_EQ(106 , message.optional_sint64 ());
+ EXPECT_EQ(107 , message.optional_fixed32 ());
+ EXPECT_EQ(108 , message.optional_fixed64 ());
+ EXPECT_EQ(109 , message.optional_sfixed32());
+ EXPECT_EQ(110 , message.optional_sfixed64());
+ EXPECT_EQ(111 , message.optional_float ());
+ EXPECT_EQ(112 , message.optional_double ());
+ EXPECT_EQ(true , message.optional_bool ());
+ EXPECT_EQ("115", message.optional_string ());
+ EXPECT_EQ("116", message.optional_bytes ());
+
+ EXPECT_EQ(117, message.optionalgroup ().a());
+ EXPECT_EQ(118, message.optional_nested_message ().bb());
+ EXPECT_EQ(119, message.optional_foreign_message().c());
+ EXPECT_EQ(120, message.optional_import_message ().d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, message.optional_nested_enum ());
+ EXPECT_EQ(unittest::FOREIGN_BAZ , message.optional_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_BAZ, message.optional_import_enum ());
+
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, message.repeated_int32_size ());
+ ASSERT_EQ(2, message.repeated_int64_size ());
+ ASSERT_EQ(2, message.repeated_uint32_size ());
+ ASSERT_EQ(2, message.repeated_uint64_size ());
+ ASSERT_EQ(2, message.repeated_sint32_size ());
+ ASSERT_EQ(2, message.repeated_sint64_size ());
+ ASSERT_EQ(2, message.repeated_fixed32_size ());
+ ASSERT_EQ(2, message.repeated_fixed64_size ());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size ());
+ ASSERT_EQ(2, message.repeated_double_size ());
+ ASSERT_EQ(2, message.repeated_bool_size ());
+ ASSERT_EQ(2, message.repeated_string_size ());
+ ASSERT_EQ(2, message.repeated_bytes_size ());
+
+ ASSERT_EQ(2, message.repeatedgroup_size ());
+ ASSERT_EQ(2, message.repeated_nested_message_size ());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_nested_enum_size ());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size ());
+ ASSERT_EQ(2, message.repeated_import_enum_size ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ ASSERT_EQ(2, message.repeated_string_piece_size());
+ ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+ EXPECT_EQ(201 , message.repeated_int32 (0));
+ EXPECT_EQ(202 , message.repeated_int64 (0));
+ EXPECT_EQ(203 , message.repeated_uint32 (0));
+ EXPECT_EQ(204 , message.repeated_uint64 (0));
+ EXPECT_EQ(205 , message.repeated_sint32 (0));
+ EXPECT_EQ(206 , message.repeated_sint64 (0));
+ EXPECT_EQ(207 , message.repeated_fixed32 (0));
+ EXPECT_EQ(208 , message.repeated_fixed64 (0));
+ EXPECT_EQ(209 , message.repeated_sfixed32(0));
+ EXPECT_EQ(210 , message.repeated_sfixed64(0));
+ EXPECT_EQ(211 , message.repeated_float (0));
+ EXPECT_EQ(212 , message.repeated_double (0));
+ EXPECT_EQ(true , message.repeated_bool (0));
+ EXPECT_EQ("215", message.repeated_string (0));
+ EXPECT_EQ("216", message.repeated_bytes (0));
+
+ EXPECT_EQ(217, message.repeatedgroup (0).a());
+ EXPECT_EQ(218, message.repeated_nested_message (0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message (0).d());
+
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0));
+
+ EXPECT_EQ(301 , message.repeated_int32 (1));
+ EXPECT_EQ(302 , message.repeated_int64 (1));
+ EXPECT_EQ(303 , message.repeated_uint32 (1));
+ EXPECT_EQ(304 , message.repeated_uint64 (1));
+ EXPECT_EQ(305 , message.repeated_sint32 (1));
+ EXPECT_EQ(306 , message.repeated_sint64 (1));
+ EXPECT_EQ(307 , message.repeated_fixed32 (1));
+ EXPECT_EQ(308 , message.repeated_fixed64 (1));
+ EXPECT_EQ(309 , message.repeated_sfixed32(1));
+ EXPECT_EQ(310 , message.repeated_sfixed64(1));
+ EXPECT_EQ(311 , message.repeated_float (1));
+ EXPECT_EQ(312 , message.repeated_double (1));
+ EXPECT_EQ(false, message.repeated_bool (1));
+ EXPECT_EQ("315", message.repeated_string (1));
+ EXPECT_EQ("316", message.repeated_bytes (1));
+
+ EXPECT_EQ(317, message.repeatedgroup (1).a());
+ EXPECT_EQ(318, message.repeated_nested_message (1).bb());
+ EXPECT_EQ(319, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(320, message.repeated_import_message (1).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (1));
+ EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(1));
+ EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (1));
+
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(message.has_default_int32 ());
+ EXPECT_TRUE(message.has_default_int64 ());
+ EXPECT_TRUE(message.has_default_uint32 ());
+ EXPECT_TRUE(message.has_default_uint64 ());
+ EXPECT_TRUE(message.has_default_sint32 ());
+ EXPECT_TRUE(message.has_default_sint64 ());
+ EXPECT_TRUE(message.has_default_fixed32 ());
+ EXPECT_TRUE(message.has_default_fixed64 ());
+ EXPECT_TRUE(message.has_default_sfixed32());
+ EXPECT_TRUE(message.has_default_sfixed64());
+ EXPECT_TRUE(message.has_default_float ());
+ EXPECT_TRUE(message.has_default_double ());
+ EXPECT_TRUE(message.has_default_bool ());
+ EXPECT_TRUE(message.has_default_string ());
+ EXPECT_TRUE(message.has_default_bytes ());
+
+ EXPECT_TRUE(message.has_default_nested_enum ());
+ EXPECT_TRUE(message.has_default_foreign_enum());
+ EXPECT_TRUE(message.has_default_import_enum ());
+
+
+ EXPECT_EQ(401 , message.default_int32 ());
+ EXPECT_EQ(402 , message.default_int64 ());
+ EXPECT_EQ(403 , message.default_uint32 ());
+ EXPECT_EQ(404 , message.default_uint64 ());
+ EXPECT_EQ(405 , message.default_sint32 ());
+ EXPECT_EQ(406 , message.default_sint64 ());
+ EXPECT_EQ(407 , message.default_fixed32 ());
+ EXPECT_EQ(408 , message.default_fixed64 ());
+ EXPECT_EQ(409 , message.default_sfixed32());
+ EXPECT_EQ(410 , message.default_sfixed64());
+ EXPECT_EQ(411 , message.default_float ());
+ EXPECT_EQ(412 , message.default_double ());
+ EXPECT_EQ(false, message.default_bool ());
+ EXPECT_EQ("415", message.default_string ());
+ EXPECT_EQ("416", message.default_bytes ());
+
+ EXPECT_EQ(unittest::TestAllTypes::FOO, message.default_nested_enum ());
+ EXPECT_EQ(unittest::FOREIGN_FOO , message.default_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_FOO, message.default_import_enum ());
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectClear(const unittest::TestAllTypes& message) {
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(message.has_optional_int32 ());
+ EXPECT_FALSE(message.has_optional_int64 ());
+ EXPECT_FALSE(message.has_optional_uint32 ());
+ EXPECT_FALSE(message.has_optional_uint64 ());
+ EXPECT_FALSE(message.has_optional_sint32 ());
+ EXPECT_FALSE(message.has_optional_sint64 ());
+ EXPECT_FALSE(message.has_optional_fixed32 ());
+ EXPECT_FALSE(message.has_optional_fixed64 ());
+ EXPECT_FALSE(message.has_optional_sfixed32());
+ EXPECT_FALSE(message.has_optional_sfixed64());
+ EXPECT_FALSE(message.has_optional_float ());
+ EXPECT_FALSE(message.has_optional_double ());
+ EXPECT_FALSE(message.has_optional_bool ());
+ EXPECT_FALSE(message.has_optional_string ());
+ EXPECT_FALSE(message.has_optional_bytes ());
+
+ EXPECT_FALSE(message.has_optionalgroup ());
+ EXPECT_FALSE(message.has_optional_nested_message ());
+ EXPECT_FALSE(message.has_optional_foreign_message());
+ EXPECT_FALSE(message.has_optional_import_message ());
+
+ EXPECT_FALSE(message.has_optional_nested_enum ());
+ EXPECT_FALSE(message.has_optional_foreign_enum());
+ EXPECT_FALSE(message.has_optional_import_enum ());
+
+ EXPECT_FALSE(message.has_optional_string_piece());
+ EXPECT_FALSE(message.has_optional_cord());
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0 , message.optional_int32 ());
+ EXPECT_EQ(0 , message.optional_int64 ());
+ EXPECT_EQ(0 , message.optional_uint32 ());
+ EXPECT_EQ(0 , message.optional_uint64 ());
+ EXPECT_EQ(0 , message.optional_sint32 ());
+ EXPECT_EQ(0 , message.optional_sint64 ());
+ EXPECT_EQ(0 , message.optional_fixed32 ());
+ EXPECT_EQ(0 , message.optional_fixed64 ());
+ EXPECT_EQ(0 , message.optional_sfixed32());
+ EXPECT_EQ(0 , message.optional_sfixed64());
+ EXPECT_EQ(0 , message.optional_float ());
+ EXPECT_EQ(0 , message.optional_double ());
+ EXPECT_EQ(false, message.optional_bool ());
+ EXPECT_EQ("" , message.optional_string ());
+ EXPECT_EQ("" , message.optional_bytes ());
+
+ // Embedded messages should also be clear.
+ EXPECT_FALSE(message.optionalgroup ().has_a());
+ EXPECT_FALSE(message.optional_nested_message ().has_bb());
+ EXPECT_FALSE(message.optional_foreign_message().has_c());
+ EXPECT_FALSE(message.optional_import_message ().has_d());
+
+ EXPECT_EQ(0, message.optionalgroup ().a());
+ EXPECT_EQ(0, message.optional_nested_message ().bb());
+ EXPECT_EQ(0, message.optional_foreign_message().c());
+ EXPECT_EQ(0, message.optional_import_message ().d());
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(unittest::TestAllTypes::FOO, message.optional_nested_enum ());
+ EXPECT_EQ(unittest::FOREIGN_FOO , message.optional_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_FOO, message.optional_import_enum ());
+
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, message.repeated_int32_size ());
+ EXPECT_EQ(0, message.repeated_int64_size ());
+ EXPECT_EQ(0, message.repeated_uint32_size ());
+ EXPECT_EQ(0, message.repeated_uint64_size ());
+ EXPECT_EQ(0, message.repeated_sint32_size ());
+ EXPECT_EQ(0, message.repeated_sint64_size ());
+ EXPECT_EQ(0, message.repeated_fixed32_size ());
+ EXPECT_EQ(0, message.repeated_fixed64_size ());
+ EXPECT_EQ(0, message.repeated_sfixed32_size());
+ EXPECT_EQ(0, message.repeated_sfixed64_size());
+ EXPECT_EQ(0, message.repeated_float_size ());
+ EXPECT_EQ(0, message.repeated_double_size ());
+ EXPECT_EQ(0, message.repeated_bool_size ());
+ EXPECT_EQ(0, message.repeated_string_size ());
+ EXPECT_EQ(0, message.repeated_bytes_size ());
+
+ EXPECT_EQ(0, message.repeatedgroup_size ());
+ EXPECT_EQ(0, message.repeated_nested_message_size ());
+ EXPECT_EQ(0, message.repeated_foreign_message_size());
+ EXPECT_EQ(0, message.repeated_import_message_size ());
+ EXPECT_EQ(0, message.repeated_nested_enum_size ());
+ EXPECT_EQ(0, message.repeated_foreign_enum_size ());
+ EXPECT_EQ(0, message.repeated_import_enum_size ());
+
+ EXPECT_EQ(0, message.repeated_string_piece_size());
+ EXPECT_EQ(0, message.repeated_cord_size());
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(message.has_default_int32 ());
+ EXPECT_FALSE(message.has_default_int64 ());
+ EXPECT_FALSE(message.has_default_uint32 ());
+ EXPECT_FALSE(message.has_default_uint64 ());
+ EXPECT_FALSE(message.has_default_sint32 ());
+ EXPECT_FALSE(message.has_default_sint64 ());
+ EXPECT_FALSE(message.has_default_fixed32 ());
+ EXPECT_FALSE(message.has_default_fixed64 ());
+ EXPECT_FALSE(message.has_default_sfixed32());
+ EXPECT_FALSE(message.has_default_sfixed64());
+ EXPECT_FALSE(message.has_default_float ());
+ EXPECT_FALSE(message.has_default_double ());
+ EXPECT_FALSE(message.has_default_bool ());
+ EXPECT_FALSE(message.has_default_string ());
+ EXPECT_FALSE(message.has_default_bytes ());
+
+ EXPECT_FALSE(message.has_default_nested_enum ());
+ EXPECT_FALSE(message.has_default_foreign_enum());
+ EXPECT_FALSE(message.has_default_import_enum ());
+
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ( 41 , message.default_int32 ());
+ EXPECT_EQ( 42 , message.default_int64 ());
+ EXPECT_EQ( 43 , message.default_uint32 ());
+ EXPECT_EQ( 44 , message.default_uint64 ());
+ EXPECT_EQ(-45 , message.default_sint32 ());
+ EXPECT_EQ( 46 , message.default_sint64 ());
+ EXPECT_EQ( 47 , message.default_fixed32 ());
+ EXPECT_EQ( 48 , message.default_fixed64 ());
+ EXPECT_EQ( 49 , message.default_sfixed32());
+ EXPECT_EQ(-50 , message.default_sfixed64());
+ EXPECT_EQ( 51.5 , message.default_float ());
+ EXPECT_EQ( 52e3 , message.default_double ());
+ EXPECT_EQ(true , message.default_bool ());
+ EXPECT_EQ("hello", message.default_string ());
+ EXPECT_EQ("world", message.default_bytes ());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.default_nested_enum ());
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.default_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.default_import_enum ());
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectRepeatedFieldsModified(
+ const unittest::TestAllTypes& message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ ASSERT_EQ(2, message.repeated_int32_size ());
+ ASSERT_EQ(2, message.repeated_int64_size ());
+ ASSERT_EQ(2, message.repeated_uint32_size ());
+ ASSERT_EQ(2, message.repeated_uint64_size ());
+ ASSERT_EQ(2, message.repeated_sint32_size ());
+ ASSERT_EQ(2, message.repeated_sint64_size ());
+ ASSERT_EQ(2, message.repeated_fixed32_size ());
+ ASSERT_EQ(2, message.repeated_fixed64_size ());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size ());
+ ASSERT_EQ(2, message.repeated_double_size ());
+ ASSERT_EQ(2, message.repeated_bool_size ());
+ ASSERT_EQ(2, message.repeated_string_size ());
+ ASSERT_EQ(2, message.repeated_bytes_size ());
+
+ ASSERT_EQ(2, message.repeatedgroup_size ());
+ ASSERT_EQ(2, message.repeated_nested_message_size ());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_nested_enum_size ());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size ());
+ ASSERT_EQ(2, message.repeated_import_enum_size ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ ASSERT_EQ(2, message.repeated_string_piece_size());
+ ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+ EXPECT_EQ(201 , message.repeated_int32 (0));
+ EXPECT_EQ(202 , message.repeated_int64 (0));
+ EXPECT_EQ(203 , message.repeated_uint32 (0));
+ EXPECT_EQ(204 , message.repeated_uint64 (0));
+ EXPECT_EQ(205 , message.repeated_sint32 (0));
+ EXPECT_EQ(206 , message.repeated_sint64 (0));
+ EXPECT_EQ(207 , message.repeated_fixed32 (0));
+ EXPECT_EQ(208 , message.repeated_fixed64 (0));
+ EXPECT_EQ(209 , message.repeated_sfixed32(0));
+ EXPECT_EQ(210 , message.repeated_sfixed64(0));
+ EXPECT_EQ(211 , message.repeated_float (0));
+ EXPECT_EQ(212 , message.repeated_double (0));
+ EXPECT_EQ(true , message.repeated_bool (0));
+ EXPECT_EQ("215", message.repeated_string (0));
+ EXPECT_EQ("216", message.repeated_bytes (0));
+
+ EXPECT_EQ(217, message.repeatedgroup (0).a());
+ EXPECT_EQ(218, message.repeated_nested_message (0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message (0).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0));
+
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(501 , message.repeated_int32 (1));
+ EXPECT_EQ(502 , message.repeated_int64 (1));
+ EXPECT_EQ(503 , message.repeated_uint32 (1));
+ EXPECT_EQ(504 , message.repeated_uint64 (1));
+ EXPECT_EQ(505 , message.repeated_sint32 (1));
+ EXPECT_EQ(506 , message.repeated_sint64 (1));
+ EXPECT_EQ(507 , message.repeated_fixed32 (1));
+ EXPECT_EQ(508 , message.repeated_fixed64 (1));
+ EXPECT_EQ(509 , message.repeated_sfixed32(1));
+ EXPECT_EQ(510 , message.repeated_sfixed64(1));
+ EXPECT_EQ(511 , message.repeated_float (1));
+ EXPECT_EQ(512 , message.repeated_double (1));
+ EXPECT_EQ(true , message.repeated_bool (1));
+ EXPECT_EQ("515", message.repeated_string (1));
+ EXPECT_EQ("516", message.repeated_bytes (1));
+
+ EXPECT_EQ(517, message.repeatedgroup (1).a());
+ EXPECT_EQ(518, message.repeated_nested_message (1).bb());
+ EXPECT_EQ(519, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(520, message.repeated_import_message (1).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::FOO, message.repeated_nested_enum (1));
+ EXPECT_EQ(unittest::FOREIGN_FOO , message.repeated_foreign_enum(1));
+ EXPECT_EQ(unittest_import::IMPORT_FOO, message.repeated_import_enum (1));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::SetPackedFields(unittest::TestPackedTypes* message) {
+ message->add_packed_int32 (601);
+ message->add_packed_int64 (602);
+ message->add_packed_uint32 (603);
+ message->add_packed_uint64 (604);
+ message->add_packed_sint32 (605);
+ message->add_packed_sint64 (606);
+ message->add_packed_fixed32 (607);
+ message->add_packed_fixed64 (608);
+ message->add_packed_sfixed32(609);
+ message->add_packed_sfixed64(610);
+ message->add_packed_float (611);
+ message->add_packed_double (612);
+ message->add_packed_bool (true);
+ message->add_packed_enum (unittest::FOREIGN_BAR);
+ // add a second one of each field
+ message->add_packed_int32 (701);
+ message->add_packed_int64 (702);
+ message->add_packed_uint32 (703);
+ message->add_packed_uint64 (704);
+ message->add_packed_sint32 (705);
+ message->add_packed_sint64 (706);
+ message->add_packed_fixed32 (707);
+ message->add_packed_fixed64 (708);
+ message->add_packed_sfixed32(709);
+ message->add_packed_sfixed64(710);
+ message->add_packed_float (711);
+ message->add_packed_double (712);
+ message->add_packed_bool (false);
+ message->add_packed_enum (unittest::FOREIGN_BAZ);
+}
+
+void TestUtil::SetUnpackedFields(unittest::TestUnpackedTypes* message) {
+ // The values applied here must match those of SetPackedFields.
+
+ message->add_unpacked_int32 (601);
+ message->add_unpacked_int64 (602);
+ message->add_unpacked_uint32 (603);
+ message->add_unpacked_uint64 (604);
+ message->add_unpacked_sint32 (605);
+ message->add_unpacked_sint64 (606);
+ message->add_unpacked_fixed32 (607);
+ message->add_unpacked_fixed64 (608);
+ message->add_unpacked_sfixed32(609);
+ message->add_unpacked_sfixed64(610);
+ message->add_unpacked_float (611);
+ message->add_unpacked_double (612);
+ message->add_unpacked_bool (true);
+ message->add_unpacked_enum (unittest::FOREIGN_BAR);
+ // add a second one of each field
+ message->add_unpacked_int32 (701);
+ message->add_unpacked_int64 (702);
+ message->add_unpacked_uint32 (703);
+ message->add_unpacked_uint64 (704);
+ message->add_unpacked_sint32 (705);
+ message->add_unpacked_sint64 (706);
+ message->add_unpacked_fixed32 (707);
+ message->add_unpacked_fixed64 (708);
+ message->add_unpacked_sfixed32(709);
+ message->add_unpacked_sfixed64(710);
+ message->add_unpacked_float (711);
+ message->add_unpacked_double (712);
+ message->add_unpacked_bool (false);
+ message->add_unpacked_enum (unittest::FOREIGN_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyPackedFields(unittest::TestPackedTypes* message) {
+ message->set_packed_int32 (1, 801);
+ message->set_packed_int64 (1, 802);
+ message->set_packed_uint32 (1, 803);
+ message->set_packed_uint64 (1, 804);
+ message->set_packed_sint32 (1, 805);
+ message->set_packed_sint64 (1, 806);
+ message->set_packed_fixed32 (1, 807);
+ message->set_packed_fixed64 (1, 808);
+ message->set_packed_sfixed32(1, 809);
+ message->set_packed_sfixed64(1, 810);
+ message->set_packed_float (1, 811);
+ message->set_packed_double (1, 812);
+ message->set_packed_bool (1, true);
+ message->set_packed_enum (1, unittest::FOREIGN_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedFieldsSet(const unittest::TestPackedTypes& message) {
+ ASSERT_EQ(2, message.packed_int32_size ());
+ ASSERT_EQ(2, message.packed_int64_size ());
+ ASSERT_EQ(2, message.packed_uint32_size ());
+ ASSERT_EQ(2, message.packed_uint64_size ());
+ ASSERT_EQ(2, message.packed_sint32_size ());
+ ASSERT_EQ(2, message.packed_sint64_size ());
+ ASSERT_EQ(2, message.packed_fixed32_size ());
+ ASSERT_EQ(2, message.packed_fixed64_size ());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size ());
+ ASSERT_EQ(2, message.packed_double_size ());
+ ASSERT_EQ(2, message.packed_bool_size ());
+ ASSERT_EQ(2, message.packed_enum_size ());
+
+ EXPECT_EQ(601 , message.packed_int32 (0));
+ EXPECT_EQ(602 , message.packed_int64 (0));
+ EXPECT_EQ(603 , message.packed_uint32 (0));
+ EXPECT_EQ(604 , message.packed_uint64 (0));
+ EXPECT_EQ(605 , message.packed_sint32 (0));
+ EXPECT_EQ(606 , message.packed_sint64 (0));
+ EXPECT_EQ(607 , message.packed_fixed32 (0));
+ EXPECT_EQ(608 , message.packed_fixed64 (0));
+ EXPECT_EQ(609 , message.packed_sfixed32(0));
+ EXPECT_EQ(610 , message.packed_sfixed64(0));
+ EXPECT_EQ(611 , message.packed_float (0));
+ EXPECT_EQ(612 , message.packed_double (0));
+ EXPECT_EQ(true , message.packed_bool (0));
+ EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0));
+
+ EXPECT_EQ(701 , message.packed_int32 (1));
+ EXPECT_EQ(702 , message.packed_int64 (1));
+ EXPECT_EQ(703 , message.packed_uint32 (1));
+ EXPECT_EQ(704 , message.packed_uint64 (1));
+ EXPECT_EQ(705 , message.packed_sint32 (1));
+ EXPECT_EQ(706 , message.packed_sint64 (1));
+ EXPECT_EQ(707 , message.packed_fixed32 (1));
+ EXPECT_EQ(708 , message.packed_fixed64 (1));
+ EXPECT_EQ(709 , message.packed_sfixed32(1));
+ EXPECT_EQ(710 , message.packed_sfixed64(1));
+ EXPECT_EQ(711 , message.packed_float (1));
+ EXPECT_EQ(712 , message.packed_double (1));
+ EXPECT_EQ(false, message.packed_bool (1));
+ EXPECT_EQ(unittest::FOREIGN_BAZ, message.packed_enum(1));
+}
+
+void TestUtil::ExpectUnpackedFieldsSet(
+ const unittest::TestUnpackedTypes& message) {
+ // The values expected here must match those of ExpectPackedFieldsSet.
+
+ ASSERT_EQ(2, message.unpacked_int32_size ());
+ ASSERT_EQ(2, message.unpacked_int64_size ());
+ ASSERT_EQ(2, message.unpacked_uint32_size ());
+ ASSERT_EQ(2, message.unpacked_uint64_size ());
+ ASSERT_EQ(2, message.unpacked_sint32_size ());
+ ASSERT_EQ(2, message.unpacked_sint64_size ());
+ ASSERT_EQ(2, message.unpacked_fixed32_size ());
+ ASSERT_EQ(2, message.unpacked_fixed64_size ());
+ ASSERT_EQ(2, message.unpacked_sfixed32_size());
+ ASSERT_EQ(2, message.unpacked_sfixed64_size());
+ ASSERT_EQ(2, message.unpacked_float_size ());
+ ASSERT_EQ(2, message.unpacked_double_size ());
+ ASSERT_EQ(2, message.unpacked_bool_size ());
+ ASSERT_EQ(2, message.unpacked_enum_size ());
+
+ EXPECT_EQ(601 , message.unpacked_int32 (0));
+ EXPECT_EQ(602 , message.unpacked_int64 (0));
+ EXPECT_EQ(603 , message.unpacked_uint32 (0));
+ EXPECT_EQ(604 , message.unpacked_uint64 (0));
+ EXPECT_EQ(605 , message.unpacked_sint32 (0));
+ EXPECT_EQ(606 , message.unpacked_sint64 (0));
+ EXPECT_EQ(607 , message.unpacked_fixed32 (0));
+ EXPECT_EQ(608 , message.unpacked_fixed64 (0));
+ EXPECT_EQ(609 , message.unpacked_sfixed32(0));
+ EXPECT_EQ(610 , message.unpacked_sfixed64(0));
+ EXPECT_EQ(611 , message.unpacked_float (0));
+ EXPECT_EQ(612 , message.unpacked_double (0));
+ EXPECT_EQ(true , message.unpacked_bool (0));
+ EXPECT_EQ(unittest::FOREIGN_BAR, message.unpacked_enum(0));
+
+ EXPECT_EQ(701 , message.unpacked_int32 (1));
+ EXPECT_EQ(702 , message.unpacked_int64 (1));
+ EXPECT_EQ(703 , message.unpacked_uint32 (1));
+ EXPECT_EQ(704 , message.unpacked_uint64 (1));
+ EXPECT_EQ(705 , message.unpacked_sint32 (1));
+ EXPECT_EQ(706 , message.unpacked_sint64 (1));
+ EXPECT_EQ(707 , message.unpacked_fixed32 (1));
+ EXPECT_EQ(708 , message.unpacked_fixed64 (1));
+ EXPECT_EQ(709 , message.unpacked_sfixed32(1));
+ EXPECT_EQ(710 , message.unpacked_sfixed64(1));
+ EXPECT_EQ(711 , message.unpacked_float (1));
+ EXPECT_EQ(712 , message.unpacked_double (1));
+ EXPECT_EQ(false, message.unpacked_bool (1));
+ EXPECT_EQ(unittest::FOREIGN_BAZ, message.unpacked_enum(1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedClear(
+ const unittest::TestPackedTypes& message) {
+ // Packed repeated fields are empty.
+ EXPECT_EQ(0, message.packed_int32_size ());
+ EXPECT_EQ(0, message.packed_int64_size ());
+ EXPECT_EQ(0, message.packed_uint32_size ());
+ EXPECT_EQ(0, message.packed_uint64_size ());
+ EXPECT_EQ(0, message.packed_sint32_size ());
+ EXPECT_EQ(0, message.packed_sint64_size ());
+ EXPECT_EQ(0, message.packed_fixed32_size ());
+ EXPECT_EQ(0, message.packed_fixed64_size ());
+ EXPECT_EQ(0, message.packed_sfixed32_size());
+ EXPECT_EQ(0, message.packed_sfixed64_size());
+ EXPECT_EQ(0, message.packed_float_size ());
+ EXPECT_EQ(0, message.packed_double_size ());
+ EXPECT_EQ(0, message.packed_bool_size ());
+ EXPECT_EQ(0, message.packed_enum_size ());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedFieldsModified(
+ const unittest::TestPackedTypes& message) {
+ // Do the same for packed repeated fields.
+ ASSERT_EQ(2, message.packed_int32_size ());
+ ASSERT_EQ(2, message.packed_int64_size ());
+ ASSERT_EQ(2, message.packed_uint32_size ());
+ ASSERT_EQ(2, message.packed_uint64_size ());
+ ASSERT_EQ(2, message.packed_sint32_size ());
+ ASSERT_EQ(2, message.packed_sint64_size ());
+ ASSERT_EQ(2, message.packed_fixed32_size ());
+ ASSERT_EQ(2, message.packed_fixed64_size ());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size ());
+ ASSERT_EQ(2, message.packed_double_size ());
+ ASSERT_EQ(2, message.packed_bool_size ());
+ ASSERT_EQ(2, message.packed_enum_size ());
+
+ EXPECT_EQ(601 , message.packed_int32 (0));
+ EXPECT_EQ(602 , message.packed_int64 (0));
+ EXPECT_EQ(603 , message.packed_uint32 (0));
+ EXPECT_EQ(604 , message.packed_uint64 (0));
+ EXPECT_EQ(605 , message.packed_sint32 (0));
+ EXPECT_EQ(606 , message.packed_sint64 (0));
+ EXPECT_EQ(607 , message.packed_fixed32 (0));
+ EXPECT_EQ(608 , message.packed_fixed64 (0));
+ EXPECT_EQ(609 , message.packed_sfixed32(0));
+ EXPECT_EQ(610 , message.packed_sfixed64(0));
+ EXPECT_EQ(611 , message.packed_float (0));
+ EXPECT_EQ(612 , message.packed_double (0));
+ EXPECT_EQ(true , message.packed_bool (0));
+ EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0));
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(801 , message.packed_int32 (1));
+ EXPECT_EQ(802 , message.packed_int64 (1));
+ EXPECT_EQ(803 , message.packed_uint32 (1));
+ EXPECT_EQ(804 , message.packed_uint64 (1));
+ EXPECT_EQ(805 , message.packed_sint32 (1));
+ EXPECT_EQ(806 , message.packed_sint64 (1));
+ EXPECT_EQ(807 , message.packed_fixed32 (1));
+ EXPECT_EQ(808 , message.packed_fixed64 (1));
+ EXPECT_EQ(809 , message.packed_sfixed32(1));
+ EXPECT_EQ(810 , message.packed_sfixed64(1));
+ EXPECT_EQ(811 , message.packed_float (1));
+ EXPECT_EQ(812 , message.packed_double (1));
+ EXPECT_EQ(true , message.packed_bool (1));
+ EXPECT_EQ(unittest::FOREIGN_FOO, message.packed_enum(1));
+}
+
+// ===================================================================
+// Extensions
+//
+// All this code is exactly equivalent to the above code except that it's
+// manipulating extension fields instead of normal ones.
+//
+// I gave up on the 80-char limit here. Sorry.
+
+void TestUtil::SetAllExtensions(unittest::TestAllExtensions* message) {
+ message->SetExtension(unittest::optional_int32_extension , 101);
+ message->SetExtension(unittest::optional_int64_extension , 102);
+ message->SetExtension(unittest::optional_uint32_extension , 103);
+ message->SetExtension(unittest::optional_uint64_extension , 104);
+ message->SetExtension(unittest::optional_sint32_extension , 105);
+ message->SetExtension(unittest::optional_sint64_extension , 106);
+ message->SetExtension(unittest::optional_fixed32_extension , 107);
+ message->SetExtension(unittest::optional_fixed64_extension , 108);
+ message->SetExtension(unittest::optional_sfixed32_extension, 109);
+ message->SetExtension(unittest::optional_sfixed64_extension, 110);
+ message->SetExtension(unittest::optional_float_extension , 111);
+ message->SetExtension(unittest::optional_double_extension , 112);
+ message->SetExtension(unittest::optional_bool_extension , true);
+ message->SetExtension(unittest::optional_string_extension , "115");
+ message->SetExtension(unittest::optional_bytes_extension , "116");
+
+ message->MutableExtension(unittest::optionalgroup_extension )->set_a(117);
+ message->MutableExtension(unittest::optional_nested_message_extension )->set_bb(118);
+ message->MutableExtension(unittest::optional_foreign_message_extension)->set_c(119);
+ message->MutableExtension(unittest::optional_import_message_extension )->set_d(120);
+
+ message->SetExtension(unittest::optional_nested_enum_extension , unittest::TestAllTypes::BAZ);
+ message->SetExtension(unittest::optional_foreign_enum_extension, unittest::FOREIGN_BAZ );
+ message->SetExtension(unittest::optional_import_enum_extension , unittest_import::IMPORT_BAZ);
+
+ message->SetExtension(unittest::optional_string_piece_extension, "124");
+ message->SetExtension(unittest::optional_cord_extension, "125");
+
+ // -----------------------------------------------------------------
+
+ message->AddExtension(unittest::repeated_int32_extension , 201);
+ message->AddExtension(unittest::repeated_int64_extension , 202);
+ message->AddExtension(unittest::repeated_uint32_extension , 203);
+ message->AddExtension(unittest::repeated_uint64_extension , 204);
+ message->AddExtension(unittest::repeated_sint32_extension , 205);
+ message->AddExtension(unittest::repeated_sint64_extension , 206);
+ message->AddExtension(unittest::repeated_fixed32_extension , 207);
+ message->AddExtension(unittest::repeated_fixed64_extension , 208);
+ message->AddExtension(unittest::repeated_sfixed32_extension, 209);
+ message->AddExtension(unittest::repeated_sfixed64_extension, 210);
+ message->AddExtension(unittest::repeated_float_extension , 211);
+ message->AddExtension(unittest::repeated_double_extension , 212);
+ message->AddExtension(unittest::repeated_bool_extension , true);
+ message->AddExtension(unittest::repeated_string_extension , "215");
+ message->AddExtension(unittest::repeated_bytes_extension , "216");
+
+ message->AddExtension(unittest::repeatedgroup_extension )->set_a(217);
+ message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(218);
+ message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(219);
+ message->AddExtension(unittest::repeated_import_message_extension )->set_d(220);
+
+ message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAR);
+ message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAR );
+ message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAR);
+
+ message->AddExtension(unittest::repeated_string_piece_extension, "224");
+ message->AddExtension(unittest::repeated_cord_extension, "225");
+
+ // Add a second one of each field.
+ message->AddExtension(unittest::repeated_int32_extension , 301);
+ message->AddExtension(unittest::repeated_int64_extension , 302);
+ message->AddExtension(unittest::repeated_uint32_extension , 303);
+ message->AddExtension(unittest::repeated_uint64_extension , 304);
+ message->AddExtension(unittest::repeated_sint32_extension , 305);
+ message->AddExtension(unittest::repeated_sint64_extension , 306);
+ message->AddExtension(unittest::repeated_fixed32_extension , 307);
+ message->AddExtension(unittest::repeated_fixed64_extension , 308);
+ message->AddExtension(unittest::repeated_sfixed32_extension, 309);
+ message->AddExtension(unittest::repeated_sfixed64_extension, 310);
+ message->AddExtension(unittest::repeated_float_extension , 311);
+ message->AddExtension(unittest::repeated_double_extension , 312);
+ message->AddExtension(unittest::repeated_bool_extension , false);
+ message->AddExtension(unittest::repeated_string_extension , "315");
+ message->AddExtension(unittest::repeated_bytes_extension , "316");
+
+ message->AddExtension(unittest::repeatedgroup_extension )->set_a(317);
+ message->AddExtension(unittest::repeated_nested_message_extension )->set_bb(318);
+ message->AddExtension(unittest::repeated_foreign_message_extension)->set_c(319);
+ message->AddExtension(unittest::repeated_import_message_extension )->set_d(320);
+
+ message->AddExtension(unittest::repeated_nested_enum_extension , unittest::TestAllTypes::BAZ);
+ message->AddExtension(unittest::repeated_foreign_enum_extension, unittest::FOREIGN_BAZ );
+ message->AddExtension(unittest::repeated_import_enum_extension , unittest_import::IMPORT_BAZ);
+
+ message->AddExtension(unittest::repeated_string_piece_extension, "324");
+ message->AddExtension(unittest::repeated_cord_extension, "325");
+
+ // -----------------------------------------------------------------
+
+ message->SetExtension(unittest::default_int32_extension , 401);
+ message->SetExtension(unittest::default_int64_extension , 402);
+ message->SetExtension(unittest::default_uint32_extension , 403);
+ message->SetExtension(unittest::default_uint64_extension , 404);
+ message->SetExtension(unittest::default_sint32_extension , 405);
+ message->SetExtension(unittest::default_sint64_extension , 406);
+ message->SetExtension(unittest::default_fixed32_extension , 407);
+ message->SetExtension(unittest::default_fixed64_extension , 408);
+ message->SetExtension(unittest::default_sfixed32_extension, 409);
+ message->SetExtension(unittest::default_sfixed64_extension, 410);
+ message->SetExtension(unittest::default_float_extension , 411);
+ message->SetExtension(unittest::default_double_extension , 412);
+ message->SetExtension(unittest::default_bool_extension , false);
+ message->SetExtension(unittest::default_string_extension , "415");
+ message->SetExtension(unittest::default_bytes_extension , "416");
+
+ message->SetExtension(unittest::default_nested_enum_extension , unittest::TestAllTypes::FOO);
+ message->SetExtension(unittest::default_foreign_enum_extension, unittest::FOREIGN_FOO );
+ message->SetExtension(unittest::default_import_enum_extension , unittest_import::IMPORT_FOO);
+
+ message->SetExtension(unittest::default_string_piece_extension, "424");
+ message->SetExtension(unittest::default_cord_extension, "425");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::SetAllFieldsAndExtensions(
+ unittest::TestFieldOrderings* message) {
+ GOOGLE_CHECK(message);
+ message->set_my_int(1);
+ message->set_my_string("foo");
+ message->set_my_float(1.0);
+ message->SetExtension(unittest::my_extension_int, 23);
+ message->SetExtension(unittest::my_extension_string, "bar");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyRepeatedExtensions(unittest::TestAllExtensions* message) {
+ message->SetExtension(unittest::repeated_int32_extension , 1, 501);
+ message->SetExtension(unittest::repeated_int64_extension , 1, 502);
+ message->SetExtension(unittest::repeated_uint32_extension , 1, 503);
+ message->SetExtension(unittest::repeated_uint64_extension , 1, 504);
+ message->SetExtension(unittest::repeated_sint32_extension , 1, 505);
+ message->SetExtension(unittest::repeated_sint64_extension , 1, 506);
+ message->SetExtension(unittest::repeated_fixed32_extension , 1, 507);
+ message->SetExtension(unittest::repeated_fixed64_extension , 1, 508);
+ message->SetExtension(unittest::repeated_sfixed32_extension, 1, 509);
+ message->SetExtension(unittest::repeated_sfixed64_extension, 1, 510);
+ message->SetExtension(unittest::repeated_float_extension , 1, 511);
+ message->SetExtension(unittest::repeated_double_extension , 1, 512);
+ message->SetExtension(unittest::repeated_bool_extension , 1, true);
+ message->SetExtension(unittest::repeated_string_extension , 1, "515");
+ message->SetExtension(unittest::repeated_bytes_extension , 1, "516");
+
+ message->MutableExtension(unittest::repeatedgroup_extension , 1)->set_a(517);
+ message->MutableExtension(unittest::repeated_nested_message_extension , 1)->set_bb(518);
+ message->MutableExtension(unittest::repeated_foreign_message_extension, 1)->set_c(519);
+ message->MutableExtension(unittest::repeated_import_message_extension , 1)->set_d(520);
+
+ message->SetExtension(unittest::repeated_nested_enum_extension , 1, unittest::TestAllTypes::FOO);
+ message->SetExtension(unittest::repeated_foreign_enum_extension, 1, unittest::FOREIGN_FOO );
+ message->SetExtension(unittest::repeated_import_enum_extension , 1, unittest_import::IMPORT_FOO);
+
+ message->SetExtension(unittest::repeated_string_piece_extension, 1, "524");
+ message->SetExtension(unittest::repeated_cord_extension, 1, "525");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectAllExtensionsSet(
+ const unittest::TestAllExtensions& message) {
+ EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension ));
+
+ EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension ));
+
+ EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension ).has_a());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension).has_c());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension ).has_d());
+
+ EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension ));
+
+ EXPECT_TRUE(message.HasExtension(unittest::optional_string_piece_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_cord_extension));
+
+ EXPECT_EQ(101 , message.GetExtension(unittest::optional_int32_extension ));
+ EXPECT_EQ(102 , message.GetExtension(unittest::optional_int64_extension ));
+ EXPECT_EQ(103 , message.GetExtension(unittest::optional_uint32_extension ));
+ EXPECT_EQ(104 , message.GetExtension(unittest::optional_uint64_extension ));
+ EXPECT_EQ(105 , message.GetExtension(unittest::optional_sint32_extension ));
+ EXPECT_EQ(106 , message.GetExtension(unittest::optional_sint64_extension ));
+ EXPECT_EQ(107 , message.GetExtension(unittest::optional_fixed32_extension ));
+ EXPECT_EQ(108 , message.GetExtension(unittest::optional_fixed64_extension ));
+ EXPECT_EQ(109 , message.GetExtension(unittest::optional_sfixed32_extension));
+ EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension));
+ EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension ));
+ EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension ));
+ EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension ));
+ EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension ));
+ EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension ));
+
+ EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension ).a());
+ EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension ).bb());
+ EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension).c());
+ EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension ).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::optional_nested_enum_extension ));
+ EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension));
+ EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::optional_import_enum_extension ));
+
+ EXPECT_EQ("124", message.GetExtension(unittest::optional_string_piece_extension));
+ EXPECT_EQ("125", message.GetExtension(unittest::optional_cord_extension));
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension ));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension ));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension));
+
+ EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0));
+ EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0));
+ EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0));
+ EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0));
+ EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0));
+ EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0));
+ EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0));
+ EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0));
+ EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0));
+ EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
+ EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0));
+ EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0));
+ EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0));
+ EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0));
+
+ EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a());
+ EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
+ EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
+ EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0));
+
+ EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0));
+ EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0));
+
+ EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension , 1));
+ EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension , 1));
+ EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension , 1));
+ EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension , 1));
+ EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension , 1));
+ EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension , 1));
+ EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension , 1));
+ EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension , 1));
+ EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension, 1));
+ EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
+ EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 1));
+ EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 1));
+ EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension , 1));
+ EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 1));
+ EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 1));
+
+ EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension , 1).a());
+ EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
+ EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
+ EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
+ EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
+ EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 1));
+
+ EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 1));
+ EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 1));
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::default_float_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_double_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_string_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension ));
+
+ EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension ));
+
+ EXPECT_TRUE(message.HasExtension(unittest::default_string_piece_extension));
+ EXPECT_TRUE(message.HasExtension(unittest::default_cord_extension));
+
+ EXPECT_EQ(401 , message.GetExtension(unittest::default_int32_extension ));
+ EXPECT_EQ(402 , message.GetExtension(unittest::default_int64_extension ));
+ EXPECT_EQ(403 , message.GetExtension(unittest::default_uint32_extension ));
+ EXPECT_EQ(404 , message.GetExtension(unittest::default_uint64_extension ));
+ EXPECT_EQ(405 , message.GetExtension(unittest::default_sint32_extension ));
+ EXPECT_EQ(406 , message.GetExtension(unittest::default_sint64_extension ));
+ EXPECT_EQ(407 , message.GetExtension(unittest::default_fixed32_extension ));
+ EXPECT_EQ(408 , message.GetExtension(unittest::default_fixed64_extension ));
+ EXPECT_EQ(409 , message.GetExtension(unittest::default_sfixed32_extension));
+ EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension));
+ EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension ));
+ EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension ));
+ EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension ));
+ EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension ));
+ EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension ));
+
+ EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::default_nested_enum_extension ));
+ EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::default_foreign_enum_extension));
+ EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::default_import_enum_extension ));
+
+ EXPECT_EQ("424", message.GetExtension(unittest::default_string_piece_extension));
+ EXPECT_EQ("425", message.GetExtension(unittest::default_cord_extension));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectExtensionsClear(
+ const unittest::TestAllExtensions& message) {
+ string serialized;
+ ASSERT_TRUE(message.SerializeToString(&serialized));
+ EXPECT_EQ("", serialized);
+ EXPECT_EQ(0, message.ByteSize());
+
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::optional_string_piece_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_cord_extension));
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_int32_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_int64_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint32_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint64_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint32_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint64_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed32_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed64_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed32_extension));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension ));
+ EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension ));
+ EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension ));
+ EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension ));
+
+ // Embedded messages should also be clear.
+ EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension ).has_a());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension ).has_bb());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension).has_c());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension ).has_d());
+
+ EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension ).a());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension ).bb());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension).c());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension ).d());
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::optional_nested_enum_extension ));
+ EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::optional_foreign_enum_extension));
+ EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::optional_import_enum_extension ));
+
+ EXPECT_EQ("", message.GetExtension(unittest::optional_string_piece_extension));
+ EXPECT_EQ("", message.GetExtension(unittest::optional_cord_extension));
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension ));
+
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension ));
+
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_piece_extension));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_cord_extension));
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::default_float_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_double_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_string_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::default_string_piece_extension));
+ EXPECT_FALSE(message.HasExtension(unittest::default_cord_extension));
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ( 41 , message.GetExtension(unittest::default_int32_extension ));
+ EXPECT_EQ( 42 , message.GetExtension(unittest::default_int64_extension ));
+ EXPECT_EQ( 43 , message.GetExtension(unittest::default_uint32_extension ));
+ EXPECT_EQ( 44 , message.GetExtension(unittest::default_uint64_extension ));
+ EXPECT_EQ(-45 , message.GetExtension(unittest::default_sint32_extension ));
+ EXPECT_EQ( 46 , message.GetExtension(unittest::default_sint64_extension ));
+ EXPECT_EQ( 47 , message.GetExtension(unittest::default_fixed32_extension ));
+ EXPECT_EQ( 48 , message.GetExtension(unittest::default_fixed64_extension ));
+ EXPECT_EQ( 49 , message.GetExtension(unittest::default_sfixed32_extension));
+ EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension));
+ EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension ));
+ EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension ));
+ EXPECT_EQ(true , message.GetExtension(unittest::default_bool_extension ));
+ EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension ));
+ EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension ));
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::default_nested_enum_extension ));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::default_foreign_enum_extension));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::default_import_enum_extension ));
+
+ EXPECT_EQ("abc", message.GetExtension(unittest::default_string_piece_extension));
+ EXPECT_EQ("123", message.GetExtension(unittest::default_cord_extension));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectRepeatedExtensionsModified(
+ const unittest::TestAllExtensions& message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension ));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension ));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension));
+
+ EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0));
+ EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0));
+ EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0));
+ EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0));
+ EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0));
+ EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0));
+ EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0));
+ EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0));
+ EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0));
+ EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
+ EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0));
+ EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0));
+ EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0));
+ EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0));
+
+ EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a());
+ EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
+ EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
+ EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0));
+
+ EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0));
+ EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0));
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(501 , message.GetExtension(unittest::repeated_int32_extension , 1));
+ EXPECT_EQ(502 , message.GetExtension(unittest::repeated_int64_extension , 1));
+ EXPECT_EQ(503 , message.GetExtension(unittest::repeated_uint32_extension , 1));
+ EXPECT_EQ(504 , message.GetExtension(unittest::repeated_uint64_extension , 1));
+ EXPECT_EQ(505 , message.GetExtension(unittest::repeated_sint32_extension , 1));
+ EXPECT_EQ(506 , message.GetExtension(unittest::repeated_sint64_extension , 1));
+ EXPECT_EQ(507 , message.GetExtension(unittest::repeated_fixed32_extension , 1));
+ EXPECT_EQ(508 , message.GetExtension(unittest::repeated_fixed64_extension , 1));
+ EXPECT_EQ(509 , message.GetExtension(unittest::repeated_sfixed32_extension, 1));
+ EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
+ EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension , 1));
+ EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension , 1));
+ EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 1));
+ EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension , 1));
+ EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension , 1));
+
+ EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension , 1).a());
+ EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
+ EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
+ EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::FOO, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
+ EXPECT_EQ(unittest::FOREIGN_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
+ EXPECT_EQ(unittest_import::IMPORT_FOO, message.GetExtension(unittest::repeated_import_enum_extension , 1));
+
+ EXPECT_EQ("524", message.GetExtension(unittest::repeated_string_piece_extension, 1));
+ EXPECT_EQ("525", message.GetExtension(unittest::repeated_cord_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::SetPackedExtensions(unittest::TestPackedExtensions* message) {
+ message->AddExtension(unittest::packed_int32_extension , 601);
+ message->AddExtension(unittest::packed_int64_extension , 602);
+ message->AddExtension(unittest::packed_uint32_extension , 603);
+ message->AddExtension(unittest::packed_uint64_extension , 604);
+ message->AddExtension(unittest::packed_sint32_extension , 605);
+ message->AddExtension(unittest::packed_sint64_extension , 606);
+ message->AddExtension(unittest::packed_fixed32_extension , 607);
+ message->AddExtension(unittest::packed_fixed64_extension , 608);
+ message->AddExtension(unittest::packed_sfixed32_extension, 609);
+ message->AddExtension(unittest::packed_sfixed64_extension, 610);
+ message->AddExtension(unittest::packed_float_extension , 611);
+ message->AddExtension(unittest::packed_double_extension , 612);
+ message->AddExtension(unittest::packed_bool_extension , true);
+ message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAR);
+ // add a second one of each field
+ message->AddExtension(unittest::packed_int32_extension , 701);
+ message->AddExtension(unittest::packed_int64_extension , 702);
+ message->AddExtension(unittest::packed_uint32_extension , 703);
+ message->AddExtension(unittest::packed_uint64_extension , 704);
+ message->AddExtension(unittest::packed_sint32_extension , 705);
+ message->AddExtension(unittest::packed_sint64_extension , 706);
+ message->AddExtension(unittest::packed_fixed32_extension , 707);
+ message->AddExtension(unittest::packed_fixed64_extension , 708);
+ message->AddExtension(unittest::packed_sfixed32_extension, 709);
+ message->AddExtension(unittest::packed_sfixed64_extension, 710);
+ message->AddExtension(unittest::packed_float_extension , 711);
+ message->AddExtension(unittest::packed_double_extension , 712);
+ message->AddExtension(unittest::packed_bool_extension , false);
+ message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyPackedExtensions(unittest::TestPackedExtensions* message) {
+ message->SetExtension(unittest::packed_int32_extension , 1, 801);
+ message->SetExtension(unittest::packed_int64_extension , 1, 802);
+ message->SetExtension(unittest::packed_uint32_extension , 1, 803);
+ message->SetExtension(unittest::packed_uint64_extension , 1, 804);
+ message->SetExtension(unittest::packed_sint32_extension , 1, 805);
+ message->SetExtension(unittest::packed_sint64_extension , 1, 806);
+ message->SetExtension(unittest::packed_fixed32_extension , 1, 807);
+ message->SetExtension(unittest::packed_fixed64_extension , 1, 808);
+ message->SetExtension(unittest::packed_sfixed32_extension, 1, 809);
+ message->SetExtension(unittest::packed_sfixed64_extension, 1, 810);
+ message->SetExtension(unittest::packed_float_extension , 1, 811);
+ message->SetExtension(unittest::packed_double_extension , 1, 812);
+ message->SetExtension(unittest::packed_bool_extension , 1, true);
+ message->SetExtension(unittest::packed_enum_extension , 1,
+ unittest::FOREIGN_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsSet(
+ const unittest::TestPackedExtensions& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension ));
+
+ EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension , 0));
+ EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension , 0));
+ EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension , 0));
+ EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension , 0));
+ EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension , 0));
+ EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension , 0));
+ EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension , 0));
+ EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension , 0));
+ EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension, 0));
+ EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0));
+ EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0));
+ EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAR,
+ message.GetExtension(unittest::packed_enum_extension, 0));
+ EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension , 1));
+ EXPECT_EQ(702 , message.GetExtension(unittest::packed_int64_extension , 1));
+ EXPECT_EQ(703 , message.GetExtension(unittest::packed_uint32_extension , 1));
+ EXPECT_EQ(704 , message.GetExtension(unittest::packed_uint64_extension , 1));
+ EXPECT_EQ(705 , message.GetExtension(unittest::packed_sint32_extension , 1));
+ EXPECT_EQ(706 , message.GetExtension(unittest::packed_sint64_extension , 1));
+ EXPECT_EQ(707 , message.GetExtension(unittest::packed_fixed32_extension , 1));
+ EXPECT_EQ(708 , message.GetExtension(unittest::packed_fixed64_extension , 1));
+ EXPECT_EQ(709 , message.GetExtension(unittest::packed_sfixed32_extension, 1));
+ EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension, 1));
+ EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension , 1));
+ EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension , 1));
+ EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension , 1));
+ EXPECT_EQ(unittest::FOREIGN_BAZ,
+ message.GetExtension(unittest::packed_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsClear(
+ const unittest::TestPackedExtensions& message) {
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension ));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsModified(
+ const unittest::TestPackedExtensions& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension ));
+ EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension , 0));
+ EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension , 0));
+ EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension , 0));
+ EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension , 0));
+ EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension , 0));
+ EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension , 0));
+ EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension , 0));
+ EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension , 0));
+ EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension, 0));
+ EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension, 0));
+ EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension , 0));
+ EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAR,
+ message.GetExtension(unittest::packed_enum_extension, 0));
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(801 , message.GetExtension(unittest::packed_int32_extension , 1));
+ EXPECT_EQ(802 , message.GetExtension(unittest::packed_int64_extension , 1));
+ EXPECT_EQ(803 , message.GetExtension(unittest::packed_uint32_extension , 1));
+ EXPECT_EQ(804 , message.GetExtension(unittest::packed_uint64_extension , 1));
+ EXPECT_EQ(805 , message.GetExtension(unittest::packed_sint32_extension , 1));
+ EXPECT_EQ(806 , message.GetExtension(unittest::packed_sint64_extension , 1));
+ EXPECT_EQ(807 , message.GetExtension(unittest::packed_fixed32_extension , 1));
+ EXPECT_EQ(808 , message.GetExtension(unittest::packed_fixed64_extension , 1));
+ EXPECT_EQ(809 , message.GetExtension(unittest::packed_sfixed32_extension, 1));
+ EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension, 1));
+ EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension , 1));
+ EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension , 1));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension , 1));
+ EXPECT_EQ(unittest::FOREIGN_FOO,
+ message.GetExtension(unittest::packed_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectAllFieldsAndExtensionsInOrder(const string& serialized) {
+ // We set each field individually, serialize separately, and concatenate all
+ // the strings in canonical order to determine the expected serialization.
+ string expected;
+ unittest::TestFieldOrderings message;
+ message.set_my_int(1); // Field 1.
+ message.AppendToString(&expected);
+ message.Clear();
+ message.SetExtension(unittest::my_extension_int, 23); // Field 5.
+ message.AppendToString(&expected);
+ message.Clear();
+ message.set_my_string("foo"); // Field 11.
+ message.AppendToString(&expected);
+ message.Clear();
+ message.SetExtension(unittest::my_extension_string, "bar"); // Field 50.
+ message.AppendToString(&expected);
+ message.Clear();
+ message.set_my_float(1.0); // Field 101.
+ message.AppendToString(&expected);
+ message.Clear();
+
+ // We don't EXPECT_EQ() since we don't want to print raw bytes to stdout.
+ EXPECT_TRUE(serialized == expected);
+}
+
+void TestUtil::ExpectLastRepeatedsRemoved(
+ const unittest::TestAllTypes& message) {
+ ASSERT_EQ(1, message.repeated_int32_size ());
+ ASSERT_EQ(1, message.repeated_int64_size ());
+ ASSERT_EQ(1, message.repeated_uint32_size ());
+ ASSERT_EQ(1, message.repeated_uint64_size ());
+ ASSERT_EQ(1, message.repeated_sint32_size ());
+ ASSERT_EQ(1, message.repeated_sint64_size ());
+ ASSERT_EQ(1, message.repeated_fixed32_size ());
+ ASSERT_EQ(1, message.repeated_fixed64_size ());
+ ASSERT_EQ(1, message.repeated_sfixed32_size());
+ ASSERT_EQ(1, message.repeated_sfixed64_size());
+ ASSERT_EQ(1, message.repeated_float_size ());
+ ASSERT_EQ(1, message.repeated_double_size ());
+ ASSERT_EQ(1, message.repeated_bool_size ());
+ ASSERT_EQ(1, message.repeated_string_size ());
+ ASSERT_EQ(1, message.repeated_bytes_size ());
+
+ ASSERT_EQ(1, message.repeatedgroup_size ());
+ ASSERT_EQ(1, message.repeated_nested_message_size ());
+ ASSERT_EQ(1, message.repeated_foreign_message_size());
+ ASSERT_EQ(1, message.repeated_import_message_size ());
+ ASSERT_EQ(1, message.repeated_nested_enum_size ());
+ ASSERT_EQ(1, message.repeated_foreign_enum_size ());
+ ASSERT_EQ(1, message.repeated_import_enum_size ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ ASSERT_EQ(1, message.repeated_string_piece_size());
+ ASSERT_EQ(1, message.repeated_cord_size());
+#endif
+
+ // Test that the remaining element is the correct one.
+ EXPECT_EQ(201 , message.repeated_int32 (0));
+ EXPECT_EQ(202 , message.repeated_int64 (0));
+ EXPECT_EQ(203 , message.repeated_uint32 (0));
+ EXPECT_EQ(204 , message.repeated_uint64 (0));
+ EXPECT_EQ(205 , message.repeated_sint32 (0));
+ EXPECT_EQ(206 , message.repeated_sint64 (0));
+ EXPECT_EQ(207 , message.repeated_fixed32 (0));
+ EXPECT_EQ(208 , message.repeated_fixed64 (0));
+ EXPECT_EQ(209 , message.repeated_sfixed32(0));
+ EXPECT_EQ(210 , message.repeated_sfixed64(0));
+ EXPECT_EQ(211 , message.repeated_float (0));
+ EXPECT_EQ(212 , message.repeated_double (0));
+ EXPECT_EQ(true , message.repeated_bool (0));
+ EXPECT_EQ("215", message.repeated_string (0));
+ EXPECT_EQ("216", message.repeated_bytes (0));
+
+ EXPECT_EQ(217, message.repeatedgroup (0).a());
+ EXPECT_EQ(218, message.repeated_nested_message (0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message (0).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (0));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(0));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (0));
+}
+
+void TestUtil::ExpectLastRepeatedExtensionsRemoved(
+ const unittest::TestAllExtensions& message) {
+
+ // Test that one element was removed.
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_int32_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_int64_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_uint32_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_uint64_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sint32_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sint64_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_float_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_double_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_bool_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_bytes_extension ));
+
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeatedgroup_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_enum_extension ));
+
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_piece_extension));
+ ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_cord_extension));
+
+ // Test that the remaining element is the correct one.
+ EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 0));
+ EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 0));
+ EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 0));
+ EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 0));
+ EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 0));
+ EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 0));
+ EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 0));
+ EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 0));
+ EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 0));
+ EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
+ EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 0));
+ EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 0));
+ EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 0));
+ EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 0));
+
+ EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 0).a());
+ EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
+ EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
+ EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 0));
+
+ EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 0));
+ EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 0));
+}
+
+void TestUtil::ExpectRepeatedsSwapped(
+ const unittest::TestAllTypes& message) {
+ ASSERT_EQ(2, message.repeated_int32_size ());
+ ASSERT_EQ(2, message.repeated_int64_size ());
+ ASSERT_EQ(2, message.repeated_uint32_size ());
+ ASSERT_EQ(2, message.repeated_uint64_size ());
+ ASSERT_EQ(2, message.repeated_sint32_size ());
+ ASSERT_EQ(2, message.repeated_sint64_size ());
+ ASSERT_EQ(2, message.repeated_fixed32_size ());
+ ASSERT_EQ(2, message.repeated_fixed64_size ());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size ());
+ ASSERT_EQ(2, message.repeated_double_size ());
+ ASSERT_EQ(2, message.repeated_bool_size ());
+ ASSERT_EQ(2, message.repeated_string_size ());
+ ASSERT_EQ(2, message.repeated_bytes_size ());
+
+ ASSERT_EQ(2, message.repeatedgroup_size ());
+ ASSERT_EQ(2, message.repeated_nested_message_size ());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_nested_enum_size ());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size ());
+ ASSERT_EQ(2, message.repeated_import_enum_size ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+ ASSERT_EQ(2, message.repeated_string_piece_size());
+ ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+ // Test that the first element and second element are flipped.
+ EXPECT_EQ(201 , message.repeated_int32 (1));
+ EXPECT_EQ(202 , message.repeated_int64 (1));
+ EXPECT_EQ(203 , message.repeated_uint32 (1));
+ EXPECT_EQ(204 , message.repeated_uint64 (1));
+ EXPECT_EQ(205 , message.repeated_sint32 (1));
+ EXPECT_EQ(206 , message.repeated_sint64 (1));
+ EXPECT_EQ(207 , message.repeated_fixed32 (1));
+ EXPECT_EQ(208 , message.repeated_fixed64 (1));
+ EXPECT_EQ(209 , message.repeated_sfixed32(1));
+ EXPECT_EQ(210 , message.repeated_sfixed64(1));
+ EXPECT_EQ(211 , message.repeated_float (1));
+ EXPECT_EQ(212 , message.repeated_double (1));
+ EXPECT_EQ(true , message.repeated_bool (1));
+ EXPECT_EQ("215", message.repeated_string (1));
+ EXPECT_EQ("216", message.repeated_bytes (1));
+
+ EXPECT_EQ(217, message.repeatedgroup (1).a());
+ EXPECT_EQ(218, message.repeated_nested_message (1).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(220, message.repeated_import_message (1).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (1));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.repeated_foreign_enum(1));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (1));
+
+ EXPECT_EQ(301 , message.repeated_int32 (0));
+ EXPECT_EQ(302 , message.repeated_int64 (0));
+ EXPECT_EQ(303 , message.repeated_uint32 (0));
+ EXPECT_EQ(304 , message.repeated_uint64 (0));
+ EXPECT_EQ(305 , message.repeated_sint32 (0));
+ EXPECT_EQ(306 , message.repeated_sint64 (0));
+ EXPECT_EQ(307 , message.repeated_fixed32 (0));
+ EXPECT_EQ(308 , message.repeated_fixed64 (0));
+ EXPECT_EQ(309 , message.repeated_sfixed32(0));
+ EXPECT_EQ(310 , message.repeated_sfixed64(0));
+ EXPECT_EQ(311 , message.repeated_float (0));
+ EXPECT_EQ(312 , message.repeated_double (0));
+ EXPECT_EQ(false, message.repeated_bool (0));
+ EXPECT_EQ("315", message.repeated_string (0));
+ EXPECT_EQ("316", message.repeated_bytes (0));
+
+ EXPECT_EQ(317, message.repeatedgroup (0).a());
+ EXPECT_EQ(318, message.repeated_nested_message (0).bb());
+ EXPECT_EQ(319, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(320, message.repeated_import_message (0).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (0));
+ EXPECT_EQ(unittest::FOREIGN_BAZ , message.repeated_foreign_enum(0));
+ EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (0));
+}
+
+void TestUtil::ExpectRepeatedExtensionsSwapped(
+ const unittest::TestAllExtensions& message) {
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension ));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension ));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_piece_extension));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_cord_extension));
+
+ EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension , 1));
+ EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension , 1));
+ EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension , 1));
+ EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension , 1));
+ EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension , 1));
+ EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension , 1));
+ EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension , 1));
+ EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension , 1));
+ EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension, 1));
+ EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
+ EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension , 1));
+ EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension , 1));
+ EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension , 1));
+ EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension , 1));
+ EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension , 1));
+
+ EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension , 1).a());
+ EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
+ EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
+ EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
+ EXPECT_EQ(unittest::FOREIGN_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
+ EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 1));
+
+ EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 1));
+ EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 1));
+
+ EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension , 0));
+ EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension , 0));
+ EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension , 0));
+ EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension , 0));
+ EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension , 0));
+ EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension , 0));
+ EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension , 0));
+ EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension , 0));
+ EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension, 0));
+ EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
+ EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension , 0));
+ EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension , 0));
+ EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension , 0));
+ EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension , 0));
+ EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension , 0));
+
+ EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension , 0).a());
+ EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
+ EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
+ EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
+ EXPECT_EQ(unittest::FOREIGN_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
+ EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 0));
+
+ EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 0));
+ EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 0));
+}
+
+// ===================================================================
+
+TestUtil::ReflectionTester::ReflectionTester(
+ const Descriptor* base_descriptor)
+ : base_descriptor_(base_descriptor) {
+
+ const DescriptorPool* pool = base_descriptor->file()->pool();
+
+ nested_b_ =
+ pool->FindFieldByName("protobuf_unittest.TestAllTypes.NestedMessage.bb");
+ foreign_c_ =
+ pool->FindFieldByName("protobuf_unittest.ForeignMessage.c");
+ import_d_ =
+ pool->FindFieldByName("protobuf_unittest_import.ImportMessage.d");
+ nested_foo_ =
+ pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.FOO");
+ nested_bar_ =
+ pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAR");
+ nested_baz_ =
+ pool->FindEnumValueByName("protobuf_unittest.TestAllTypes.BAZ");
+ foreign_foo_ =
+ pool->FindEnumValueByName("protobuf_unittest.FOREIGN_FOO");
+ foreign_bar_ =
+ pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAR");
+ foreign_baz_ =
+ pool->FindEnumValueByName("protobuf_unittest.FOREIGN_BAZ");
+ import_foo_ =
+ pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_FOO");
+ import_bar_ =
+ pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAR");
+ import_baz_ =
+ pool->FindEnumValueByName("protobuf_unittest_import.IMPORT_BAZ");
+
+ if (base_descriptor_->name() == "TestAllExtensions") {
+ group_a_ =
+ pool->FindFieldByName("protobuf_unittest.OptionalGroup_extension.a");
+ repeated_group_a_ =
+ pool->FindFieldByName("protobuf_unittest.RepeatedGroup_extension.a");
+ } else {
+ group_a_ =
+ pool->FindFieldByName("protobuf_unittest.TestAllTypes.OptionalGroup.a");
+ repeated_group_a_ =
+ pool->FindFieldByName("protobuf_unittest.TestAllTypes.RepeatedGroup.a");
+ }
+
+ EXPECT_TRUE(group_a_ != NULL);
+ EXPECT_TRUE(repeated_group_a_ != NULL);
+ EXPECT_TRUE(nested_b_ != NULL);
+ EXPECT_TRUE(foreign_c_ != NULL);
+ EXPECT_TRUE(import_d_ != NULL);
+ EXPECT_TRUE(nested_foo_ != NULL);
+ EXPECT_TRUE(nested_bar_ != NULL);
+ EXPECT_TRUE(nested_baz_ != NULL);
+ EXPECT_TRUE(foreign_foo_ != NULL);
+ EXPECT_TRUE(foreign_bar_ != NULL);
+ EXPECT_TRUE(foreign_baz_ != NULL);
+ EXPECT_TRUE(import_foo_ != NULL);
+ EXPECT_TRUE(import_bar_ != NULL);
+ EXPECT_TRUE(import_baz_ != NULL);
+}
+
+// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+const FieldDescriptor* TestUtil::ReflectionTester::F(const string& name) {
+ const FieldDescriptor* result = NULL;
+ if (base_descriptor_->name() == "TestAllExtensions" ||
+ base_descriptor_->name() == "TestPackedExtensions") {
+ result = base_descriptor_->file()->FindExtensionByName(name + "_extension");
+ } else {
+ result = base_descriptor_->FindFieldByName(name);
+ }
+ GOOGLE_CHECK(result != NULL);
+ return result;
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ Message* sub_message;
+
+ reflection->SetInt32 (message, F("optional_int32" ), 101);
+ reflection->SetInt64 (message, F("optional_int64" ), 102);
+ reflection->SetUInt32(message, F("optional_uint32" ), 103);
+ reflection->SetUInt64(message, F("optional_uint64" ), 104);
+ reflection->SetInt32 (message, F("optional_sint32" ), 105);
+ reflection->SetInt64 (message, F("optional_sint64" ), 106);
+ reflection->SetUInt32(message, F("optional_fixed32" ), 107);
+ reflection->SetUInt64(message, F("optional_fixed64" ), 108);
+ reflection->SetInt32 (message, F("optional_sfixed32"), 109);
+ reflection->SetInt64 (message, F("optional_sfixed64"), 110);
+ reflection->SetFloat (message, F("optional_float" ), 111);
+ reflection->SetDouble(message, F("optional_double" ), 112);
+ reflection->SetBool (message, F("optional_bool" ), true);
+ reflection->SetString(message, F("optional_string" ), "115");
+ reflection->SetString(message, F("optional_bytes" ), "116");
+
+ sub_message = reflection->MutableMessage(message, F("optionalgroup"));
+ sub_message->GetReflection()->SetInt32(sub_message, group_a_, 117);
+ sub_message = reflection->MutableMessage(message, F("optional_nested_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 118);
+ sub_message = reflection->MutableMessage(message, F("optional_foreign_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 119);
+ sub_message = reflection->MutableMessage(message, F("optional_import_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, import_d_, 120);
+
+ reflection->SetEnum(message, F("optional_nested_enum" ), nested_baz_);
+ reflection->SetEnum(message, F("optional_foreign_enum"), foreign_baz_);
+ reflection->SetEnum(message, F("optional_import_enum" ), import_baz_);
+
+ reflection->SetString(message, F("optional_string_piece"), "124");
+ reflection->SetString(message, F("optional_cord"), "125");
+
+ // -----------------------------------------------------------------
+
+ reflection->AddInt32 (message, F("repeated_int32" ), 201);
+ reflection->AddInt64 (message, F("repeated_int64" ), 202);
+ reflection->AddUInt32(message, F("repeated_uint32" ), 203);
+ reflection->AddUInt64(message, F("repeated_uint64" ), 204);
+ reflection->AddInt32 (message, F("repeated_sint32" ), 205);
+ reflection->AddInt64 (message, F("repeated_sint64" ), 206);
+ reflection->AddUInt32(message, F("repeated_fixed32" ), 207);
+ reflection->AddUInt64(message, F("repeated_fixed64" ), 208);
+ reflection->AddInt32 (message, F("repeated_sfixed32"), 209);
+ reflection->AddInt64 (message, F("repeated_sfixed64"), 210);
+ reflection->AddFloat (message, F("repeated_float" ), 211);
+ reflection->AddDouble(message, F("repeated_double" ), 212);
+ reflection->AddBool (message, F("repeated_bool" ), true);
+ reflection->AddString(message, F("repeated_string" ), "215");
+ reflection->AddString(message, F("repeated_bytes" ), "216");
+
+ sub_message = reflection->AddMessage(message, F("repeatedgroup"));
+ sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 217);
+ sub_message = reflection->AddMessage(message, F("repeated_nested_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 218);
+ sub_message = reflection->AddMessage(message, F("repeated_foreign_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 219);
+ sub_message = reflection->AddMessage(message, F("repeated_import_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, import_d_, 220);
+
+ reflection->AddEnum(message, F("repeated_nested_enum" ), nested_bar_);
+ reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_bar_);
+ reflection->AddEnum(message, F("repeated_import_enum" ), import_bar_);
+
+ reflection->AddString(message, F("repeated_string_piece"), "224");
+ reflection->AddString(message, F("repeated_cord"), "225");
+
+ // Add a second one of each field.
+ reflection->AddInt32 (message, F("repeated_int32" ), 301);
+ reflection->AddInt64 (message, F("repeated_int64" ), 302);
+ reflection->AddUInt32(message, F("repeated_uint32" ), 303);
+ reflection->AddUInt64(message, F("repeated_uint64" ), 304);
+ reflection->AddInt32 (message, F("repeated_sint32" ), 305);
+ reflection->AddInt64 (message, F("repeated_sint64" ), 306);
+ reflection->AddUInt32(message, F("repeated_fixed32" ), 307);
+ reflection->AddUInt64(message, F("repeated_fixed64" ), 308);
+ reflection->AddInt32 (message, F("repeated_sfixed32"), 309);
+ reflection->AddInt64 (message, F("repeated_sfixed64"), 310);
+ reflection->AddFloat (message, F("repeated_float" ), 311);
+ reflection->AddDouble(message, F("repeated_double" ), 312);
+ reflection->AddBool (message, F("repeated_bool" ), false);
+ reflection->AddString(message, F("repeated_string" ), "315");
+ reflection->AddString(message, F("repeated_bytes" ), "316");
+
+ sub_message = reflection->AddMessage(message, F("repeatedgroup"));
+ sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 317);
+ sub_message = reflection->AddMessage(message, F("repeated_nested_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 318);
+ sub_message = reflection->AddMessage(message, F("repeated_foreign_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 319);
+ sub_message = reflection->AddMessage(message, F("repeated_import_message"));
+ sub_message->GetReflection()->SetInt32(sub_message, import_d_, 320);
+
+ reflection->AddEnum(message, F("repeated_nested_enum" ), nested_baz_);
+ reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_baz_);
+ reflection->AddEnum(message, F("repeated_import_enum" ), import_baz_);
+
+ reflection->AddString(message, F("repeated_string_piece"), "324");
+ reflection->AddString(message, F("repeated_cord"), "325");
+
+ // -----------------------------------------------------------------
+
+ reflection->SetInt32 (message, F("default_int32" ), 401);
+ reflection->SetInt64 (message, F("default_int64" ), 402);
+ reflection->SetUInt32(message, F("default_uint32" ), 403);
+ reflection->SetUInt64(message, F("default_uint64" ), 404);
+ reflection->SetInt32 (message, F("default_sint32" ), 405);
+ reflection->SetInt64 (message, F("default_sint64" ), 406);
+ reflection->SetUInt32(message, F("default_fixed32" ), 407);
+ reflection->SetUInt64(message, F("default_fixed64" ), 408);
+ reflection->SetInt32 (message, F("default_sfixed32"), 409);
+ reflection->SetInt64 (message, F("default_sfixed64"), 410);
+ reflection->SetFloat (message, F("default_float" ), 411);
+ reflection->SetDouble(message, F("default_double" ), 412);
+ reflection->SetBool (message, F("default_bool" ), false);
+ reflection->SetString(message, F("default_string" ), "415");
+ reflection->SetString(message, F("default_bytes" ), "416");
+
+ reflection->SetEnum(message, F("default_nested_enum" ), nested_foo_);
+ reflection->SetEnum(message, F("default_foreign_enum"), foreign_foo_);
+ reflection->SetEnum(message, F("default_import_enum" ), import_foo_);
+
+ reflection->SetString(message, F("default_string_piece"), "424");
+ reflection->SetString(message, F("default_cord"), "425");
+}
+
+void TestUtil::ReflectionTester::SetPackedFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ reflection->AddInt32 (message, F("packed_int32" ), 601);
+ reflection->AddInt64 (message, F("packed_int64" ), 602);
+ reflection->AddUInt32(message, F("packed_uint32" ), 603);
+ reflection->AddUInt64(message, F("packed_uint64" ), 604);
+ reflection->AddInt32 (message, F("packed_sint32" ), 605);
+ reflection->AddInt64 (message, F("packed_sint64" ), 606);
+ reflection->AddUInt32(message, F("packed_fixed32" ), 607);
+ reflection->AddUInt64(message, F("packed_fixed64" ), 608);
+ reflection->AddInt32 (message, F("packed_sfixed32"), 609);
+ reflection->AddInt64 (message, F("packed_sfixed64"), 610);
+ reflection->AddFloat (message, F("packed_float" ), 611);
+ reflection->AddDouble(message, F("packed_double" ), 612);
+ reflection->AddBool (message, F("packed_bool" ), true);
+ reflection->AddEnum (message, F("packed_enum" ), foreign_bar_);
+
+ reflection->AddInt32 (message, F("packed_int32" ), 701);
+ reflection->AddInt64 (message, F("packed_int64" ), 702);
+ reflection->AddUInt32(message, F("packed_uint32" ), 703);
+ reflection->AddUInt64(message, F("packed_uint64" ), 704);
+ reflection->AddInt32 (message, F("packed_sint32" ), 705);
+ reflection->AddInt64 (message, F("packed_sint64" ), 706);
+ reflection->AddUInt32(message, F("packed_fixed32" ), 707);
+ reflection->AddUInt64(message, F("packed_fixed64" ), 708);
+ reflection->AddInt32 (message, F("packed_sfixed32"), 709);
+ reflection->AddInt64 (message, F("packed_sfixed64"), 710);
+ reflection->AddFloat (message, F("packed_float" ), 711);
+ reflection->AddDouble(message, F("packed_double" ), 712);
+ reflection->AddBool (message, F("packed_bool" ), false);
+ reflection->AddEnum (message, F("packed_enum" ), foreign_baz_);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection(
+ const Message& message) {
+ // We have to split this into three function otherwise it creates a stack
+ // frame so large that it triggers a warning.
+ ExpectAllFieldsSetViaReflection1(message);
+ ExpectAllFieldsSetViaReflection2(message);
+ ExpectAllFieldsSetViaReflection3(message);
+}
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ string scratch;
+ const Message* sub_message;
+
+ EXPECT_TRUE(reflection->HasField(message, F("optional_int32" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_int64" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_uint32" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_uint64" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_sint32" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_sint64" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_fixed32" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_fixed64" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed32")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed64")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_float" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_double" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_bool" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_string" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_bytes" )));
+
+ EXPECT_TRUE(reflection->HasField(message, F("optionalgroup" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_import_message" )));
+
+ sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
+ sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+ sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
+ sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+ EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+
+ EXPECT_TRUE(reflection->HasField(message, F("optional_nested_enum" )));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_enum")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_import_enum" )));
+
+ EXPECT_TRUE(reflection->HasField(message, F("optional_string_piece")));
+ EXPECT_TRUE(reflection->HasField(message, F("optional_cord")));
+
+ EXPECT_EQ(101 , reflection->GetInt32 (message, F("optional_int32" )));
+ EXPECT_EQ(102 , reflection->GetInt64 (message, F("optional_int64" )));
+ EXPECT_EQ(103 , reflection->GetUInt32(message, F("optional_uint32" )));
+ EXPECT_EQ(104 , reflection->GetUInt64(message, F("optional_uint64" )));
+ EXPECT_EQ(105 , reflection->GetInt32 (message, F("optional_sint32" )));
+ EXPECT_EQ(106 , reflection->GetInt64 (message, F("optional_sint64" )));
+ EXPECT_EQ(107 , reflection->GetUInt32(message, F("optional_fixed32" )));
+ EXPECT_EQ(108 , reflection->GetUInt64(message, F("optional_fixed64" )));
+ EXPECT_EQ(109 , reflection->GetInt32 (message, F("optional_sfixed32")));
+ EXPECT_EQ(110 , reflection->GetInt64 (message, F("optional_sfixed64")));
+ EXPECT_EQ(111 , reflection->GetFloat (message, F("optional_float" )));
+ EXPECT_EQ(112 , reflection->GetDouble(message, F("optional_double" )));
+ EXPECT_EQ(true , reflection->GetBool (message, F("optional_bool" )));
+ EXPECT_EQ("115", reflection->GetString(message, F("optional_string" )));
+ EXPECT_EQ("116", reflection->GetString(message, F("optional_bytes" )));
+
+ EXPECT_EQ("115", reflection->GetStringReference(message, F("optional_string"), &scratch));
+ EXPECT_EQ("116", reflection->GetStringReference(message, F("optional_bytes" ), &scratch));
+
+ sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+ EXPECT_EQ(117, sub_message->GetReflection()->GetInt32(*sub_message, group_a_));
+ sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+ EXPECT_EQ(118, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+ EXPECT_EQ(119, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+ sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+ EXPECT_EQ(120, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+
+ EXPECT_EQ( nested_baz_, reflection->GetEnum(message, F("optional_nested_enum" )));
+ EXPECT_EQ(foreign_baz_, reflection->GetEnum(message, F("optional_foreign_enum")));
+ EXPECT_EQ( import_baz_, reflection->GetEnum(message, F("optional_import_enum" )));
+
+ EXPECT_EQ("124", reflection->GetString(message, F("optional_string_piece")));
+ EXPECT_EQ("124", reflection->GetStringReference(message, F("optional_string_piece"), &scratch));
+
+ EXPECT_EQ("125", reflection->GetString(message, F("optional_cord")));
+ EXPECT_EQ("125", reflection->GetStringReference(message, F("optional_cord"), &scratch));
+}
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ string scratch;
+ const Message* sub_message;
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_float" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_double" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bool" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bytes" )));
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeatedgroup" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_message" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_message")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_message" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_enum" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_enum" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_enum" )));
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string_piece")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_cord")));
+
+ EXPECT_EQ(201 , reflection->GetRepeatedInt32 (message, F("repeated_int32" ), 0));
+ EXPECT_EQ(202 , reflection->GetRepeatedInt64 (message, F("repeated_int64" ), 0));
+ EXPECT_EQ(203 , reflection->GetRepeatedUInt32(message, F("repeated_uint32" ), 0));
+ EXPECT_EQ(204 , reflection->GetRepeatedUInt64(message, F("repeated_uint64" ), 0));
+ EXPECT_EQ(205 , reflection->GetRepeatedInt32 (message, F("repeated_sint32" ), 0));
+ EXPECT_EQ(206 , reflection->GetRepeatedInt64 (message, F("repeated_sint64" ), 0));
+ EXPECT_EQ(207 , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 0));
+ EXPECT_EQ(208 , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 0));
+ EXPECT_EQ(209 , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 0));
+ EXPECT_EQ(210 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 0));
+ EXPECT_EQ(211 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 0));
+ EXPECT_EQ(212 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 0));
+ EXPECT_EQ(true , reflection->GetRepeatedBool (message, F("repeated_bool" ), 0));
+ EXPECT_EQ("215", reflection->GetRepeatedString(message, F("repeated_string" ), 0));
+ EXPECT_EQ("216", reflection->GetRepeatedString(message, F("repeated_bytes" ), 0));
+
+ EXPECT_EQ("215", reflection->GetRepeatedStringReference(message, F("repeated_string"), 0, &scratch));
+ EXPECT_EQ("216", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), 0, &scratch));
+
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 0);
+ EXPECT_EQ(217, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_));
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 0);
+ EXPECT_EQ(218, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 0);
+ EXPECT_EQ(219, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 0);
+ EXPECT_EQ(220, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+
+ EXPECT_EQ( nested_bar_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),0));
+ EXPECT_EQ(foreign_bar_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),0));
+ EXPECT_EQ( import_bar_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),0));
+
+ EXPECT_EQ("224", reflection->GetRepeatedString(message, F("repeated_string_piece"), 0));
+ EXPECT_EQ("224", reflection->GetRepeatedStringReference(
+ message, F("repeated_string_piece"), 0, &scratch));
+
+ EXPECT_EQ("225", reflection->GetRepeatedString(message, F("repeated_cord"), 0));
+ EXPECT_EQ("225", reflection->GetRepeatedStringReference(
+ message, F("repeated_cord"), 0, &scratch));
+
+ EXPECT_EQ(301 , reflection->GetRepeatedInt32 (message, F("repeated_int32" ), 1));
+ EXPECT_EQ(302 , reflection->GetRepeatedInt64 (message, F("repeated_int64" ), 1));
+ EXPECT_EQ(303 , reflection->GetRepeatedUInt32(message, F("repeated_uint32" ), 1));
+ EXPECT_EQ(304 , reflection->GetRepeatedUInt64(message, F("repeated_uint64" ), 1));
+ EXPECT_EQ(305 , reflection->GetRepeatedInt32 (message, F("repeated_sint32" ), 1));
+ EXPECT_EQ(306 , reflection->GetRepeatedInt64 (message, F("repeated_sint64" ), 1));
+ EXPECT_EQ(307 , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 1));
+ EXPECT_EQ(308 , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 1));
+ EXPECT_EQ(309 , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 1));
+ EXPECT_EQ(310 , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 1));
+ EXPECT_EQ(311 , reflection->GetRepeatedFloat (message, F("repeated_float" ), 1));
+ EXPECT_EQ(312 , reflection->GetRepeatedDouble(message, F("repeated_double" ), 1));
+ EXPECT_EQ(false, reflection->GetRepeatedBool (message, F("repeated_bool" ), 1));
+ EXPECT_EQ("315", reflection->GetRepeatedString(message, F("repeated_string" ), 1));
+ EXPECT_EQ("316", reflection->GetRepeatedString(message, F("repeated_bytes" ), 1));
+
+ EXPECT_EQ("315", reflection->GetRepeatedStringReference(message, F("repeated_string"),
+ 1, &scratch));
+ EXPECT_EQ("316", reflection->GetRepeatedStringReference(message, F("repeated_bytes"),
+ 1, &scratch));
+
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 1);
+ EXPECT_EQ(317, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_));
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 1);
+ EXPECT_EQ(318, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 1);
+ EXPECT_EQ(319, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+ sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 1);
+ EXPECT_EQ(320, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+
+ EXPECT_EQ( nested_baz_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),1));
+ EXPECT_EQ(foreign_baz_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),1));
+ EXPECT_EQ( import_baz_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),1));
+
+ EXPECT_EQ("324", reflection->GetRepeatedString(message, F("repeated_string_piece"), 1));
+ EXPECT_EQ("324", reflection->GetRepeatedStringReference(
+ message, F("repeated_string_piece"), 1, &scratch));
+
+ EXPECT_EQ("325", reflection->GetRepeatedString(message, F("repeated_cord"), 1));
+ EXPECT_EQ("325", reflection->GetRepeatedStringReference(
+ message, F("repeated_cord"), 1, &scratch));
+}
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection3(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ string scratch;
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(reflection->HasField(message, F("default_int32" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_int64" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_uint32" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_uint64" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_sint32" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_sint64" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_fixed32" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_fixed64" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_sfixed32")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_sfixed64")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_float" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_double" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_bool" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_string" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_bytes" )));
+
+ EXPECT_TRUE(reflection->HasField(message, F("default_nested_enum" )));
+ EXPECT_TRUE(reflection->HasField(message, F("default_foreign_enum")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_import_enum" )));
+
+ EXPECT_TRUE(reflection->HasField(message, F("default_string_piece")));
+ EXPECT_TRUE(reflection->HasField(message, F("default_cord")));
+
+ EXPECT_EQ(401 , reflection->GetInt32 (message, F("default_int32" )));
+ EXPECT_EQ(402 , reflection->GetInt64 (message, F("default_int64" )));
+ EXPECT_EQ(403 , reflection->GetUInt32(message, F("default_uint32" )));
+ EXPECT_EQ(404 , reflection->GetUInt64(message, F("default_uint64" )));
+ EXPECT_EQ(405 , reflection->GetInt32 (message, F("default_sint32" )));
+ EXPECT_EQ(406 , reflection->GetInt64 (message, F("default_sint64" )));
+ EXPECT_EQ(407 , reflection->GetUInt32(message, F("default_fixed32" )));
+ EXPECT_EQ(408 , reflection->GetUInt64(message, F("default_fixed64" )));
+ EXPECT_EQ(409 , reflection->GetInt32 (message, F("default_sfixed32")));
+ EXPECT_EQ(410 , reflection->GetInt64 (message, F("default_sfixed64")));
+ EXPECT_EQ(411 , reflection->GetFloat (message, F("default_float" )));
+ EXPECT_EQ(412 , reflection->GetDouble(message, F("default_double" )));
+ EXPECT_EQ(false, reflection->GetBool (message, F("default_bool" )));
+ EXPECT_EQ("415", reflection->GetString(message, F("default_string" )));
+ EXPECT_EQ("416", reflection->GetString(message, F("default_bytes" )));
+
+ EXPECT_EQ("415", reflection->GetStringReference(message, F("default_string"), &scratch));
+ EXPECT_EQ("416", reflection->GetStringReference(message, F("default_bytes" ), &scratch));
+
+ EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("default_nested_enum" )));
+ EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("default_foreign_enum")));
+ EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("default_import_enum" )));
+
+ EXPECT_EQ("424", reflection->GetString(message, F("default_string_piece")));
+ EXPECT_EQ("424", reflection->GetStringReference(message, F("default_string_piece"),
+ &scratch));
+
+ EXPECT_EQ("425", reflection->GetString(message, F("default_cord")));
+ EXPECT_EQ("425", reflection->GetStringReference(message, F("default_cord"), &scratch));
+}
+
+void TestUtil::ReflectionTester::ExpectPackedFieldsSetViaReflection(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed32" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed64" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_float" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_double" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_bool" )));
+ ASSERT_EQ(2, reflection->FieldSize(message, F("packed_enum" )));
+
+ EXPECT_EQ(601 , reflection->GetRepeatedInt32 (message, F("packed_int32" ), 0));
+ EXPECT_EQ(602 , reflection->GetRepeatedInt64 (message, F("packed_int64" ), 0));
+ EXPECT_EQ(603 , reflection->GetRepeatedUInt32(message, F("packed_uint32" ), 0));
+ EXPECT_EQ(604 , reflection->GetRepeatedUInt64(message, F("packed_uint64" ), 0));
+ EXPECT_EQ(605 , reflection->GetRepeatedInt32 (message, F("packed_sint32" ), 0));
+ EXPECT_EQ(606 , reflection->GetRepeatedInt64 (message, F("packed_sint64" ), 0));
+ EXPECT_EQ(607 , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 0));
+ EXPECT_EQ(608 , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 0));
+ EXPECT_EQ(609 , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 0));
+ EXPECT_EQ(610 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 0));
+ EXPECT_EQ(611 , reflection->GetRepeatedFloat (message, F("packed_float" ), 0));
+ EXPECT_EQ(612 , reflection->GetRepeatedDouble(message, F("packed_double" ), 0));
+ EXPECT_EQ(true , reflection->GetRepeatedBool (message, F("packed_bool" ), 0));
+ EXPECT_EQ(foreign_bar_,
+ reflection->GetRepeatedEnum(message, F("packed_enum"), 0));
+
+ EXPECT_EQ(701 , reflection->GetRepeatedInt32 (message, F("packed_int32" ), 1));
+ EXPECT_EQ(702 , reflection->GetRepeatedInt64 (message, F("packed_int64" ), 1));
+ EXPECT_EQ(703 , reflection->GetRepeatedUInt32(message, F("packed_uint32" ), 1));
+ EXPECT_EQ(704 , reflection->GetRepeatedUInt64(message, F("packed_uint64" ), 1));
+ EXPECT_EQ(705 , reflection->GetRepeatedInt32 (message, F("packed_sint32" ), 1));
+ EXPECT_EQ(706 , reflection->GetRepeatedInt64 (message, F("packed_sint64" ), 1));
+ EXPECT_EQ(707 , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 1));
+ EXPECT_EQ(708 , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 1));
+ EXPECT_EQ(709 , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 1));
+ EXPECT_EQ(710 , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 1));
+ EXPECT_EQ(711 , reflection->GetRepeatedFloat (message, F("packed_float" ), 1));
+ EXPECT_EQ(712 , reflection->GetRepeatedDouble(message, F("packed_double" ), 1));
+ EXPECT_EQ(false, reflection->GetRepeatedBool (message, F("packed_bool" ), 1));
+ EXPECT_EQ(foreign_baz_,
+ reflection->GetRepeatedEnum(message, F("packed_enum"), 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::ExpectClearViaReflection(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+ string scratch;
+ const Message* sub_message;
+
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(reflection->HasField(message, F("optional_int32" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_int64" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_uint32" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_uint64" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_sint32" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_sint64" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_fixed32" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_fixed64" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed32")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed64")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_float" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_double" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_bool" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_string" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_bytes" )));
+
+ EXPECT_FALSE(reflection->HasField(message, F("optionalgroup" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_nested_message" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_message")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_import_message" )));
+
+ EXPECT_FALSE(reflection->HasField(message, F("optional_nested_enum" )));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_enum")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_import_enum" )));
+
+ EXPECT_FALSE(reflection->HasField(message, F("optional_string_piece")));
+ EXPECT_FALSE(reflection->HasField(message, F("optional_cord")));
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_int32" )));
+ EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_int64" )));
+ EXPECT_EQ(0 , reflection->GetUInt32(message, F("optional_uint32" )));
+ EXPECT_EQ(0 , reflection->GetUInt64(message, F("optional_uint64" )));
+ EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_sint32" )));
+ EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sint64" )));
+ EXPECT_EQ(0 , reflection->GetUInt32(message, F("optional_fixed32" )));
+ EXPECT_EQ(0 , reflection->GetUInt64(message, F("optional_fixed64" )));
+ EXPECT_EQ(0 , reflection->GetInt32 (message, F("optional_sfixed32")));
+ EXPECT_EQ(0 , reflection->GetInt64 (message, F("optional_sfixed64")));
+ EXPECT_EQ(0 , reflection->GetFloat (message, F("optional_float" )));
+ EXPECT_EQ(0 , reflection->GetDouble(message, F("optional_double" )));
+ EXPECT_EQ(false, reflection->GetBool (message, F("optional_bool" )));
+ EXPECT_EQ("" , reflection->GetString(message, F("optional_string" )));
+ EXPECT_EQ("" , reflection->GetString(message, F("optional_bytes" )));
+
+ EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string"), &scratch));
+ EXPECT_EQ("", reflection->GetStringReference(message, F("optional_bytes" ), &scratch));
+
+ // Embedded messages should also be clear.
+ sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, group_a_));
+ sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+ sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+ sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+ EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+ EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("optional_nested_enum" )));
+ EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("optional_foreign_enum")));
+ EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("optional_import_enum" )));
+
+ EXPECT_EQ("", reflection->GetString(message, F("optional_string_piece")));
+ EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string_piece"), &scratch));
+
+ EXPECT_EQ("", reflection->GetString(message, F("optional_cord")));
+ EXPECT_EQ("", reflection->GetStringReference(message, F("optional_cord"), &scratch));
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_float" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_double" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bool" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bytes" )));
+
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeatedgroup" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_message" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_message")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_message" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_enum" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_enum" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_enum" )));
+
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string_piece")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_cord")));
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(reflection->HasField(message, F("default_int32" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_int64" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_uint32" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_uint64" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_sint32" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_sint64" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_fixed32" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_fixed64" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_sfixed32")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_sfixed64")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_float" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_double" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_bool" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_string" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_bytes" )));
+
+ EXPECT_FALSE(reflection->HasField(message, F("default_nested_enum" )));
+ EXPECT_FALSE(reflection->HasField(message, F("default_foreign_enum")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_import_enum" )));
+
+ EXPECT_FALSE(reflection->HasField(message, F("default_string_piece")));
+ EXPECT_FALSE(reflection->HasField(message, F("default_cord")));
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ( 41 , reflection->GetInt32 (message, F("default_int32" )));
+ EXPECT_EQ( 42 , reflection->GetInt64 (message, F("default_int64" )));
+ EXPECT_EQ( 43 , reflection->GetUInt32(message, F("default_uint32" )));
+ EXPECT_EQ( 44 , reflection->GetUInt64(message, F("default_uint64" )));
+ EXPECT_EQ(-45 , reflection->GetInt32 (message, F("default_sint32" )));
+ EXPECT_EQ( 46 , reflection->GetInt64 (message, F("default_sint64" )));
+ EXPECT_EQ( 47 , reflection->GetUInt32(message, F("default_fixed32" )));
+ EXPECT_EQ( 48 , reflection->GetUInt64(message, F("default_fixed64" )));
+ EXPECT_EQ( 49 , reflection->GetInt32 (message, F("default_sfixed32")));
+ EXPECT_EQ(-50 , reflection->GetInt64 (message, F("default_sfixed64")));
+ EXPECT_EQ( 51.5 , reflection->GetFloat (message, F("default_float" )));
+ EXPECT_EQ( 52e3 , reflection->GetDouble(message, F("default_double" )));
+ EXPECT_EQ(true , reflection->GetBool (message, F("default_bool" )));
+ EXPECT_EQ("hello", reflection->GetString(message, F("default_string" )));
+ EXPECT_EQ("world", reflection->GetString(message, F("default_bytes" )));
+
+ EXPECT_EQ("hello", reflection->GetStringReference(message, F("default_string"), &scratch));
+ EXPECT_EQ("world", reflection->GetStringReference(message, F("default_bytes" ), &scratch));
+
+ EXPECT_EQ( nested_bar_, reflection->GetEnum(message, F("default_nested_enum" )));
+ EXPECT_EQ(foreign_bar_, reflection->GetEnum(message, F("default_foreign_enum")));
+ EXPECT_EQ( import_bar_, reflection->GetEnum(message, F("default_import_enum" )));
+
+ EXPECT_EQ("abc", reflection->GetString(message, F("default_string_piece")));
+ EXPECT_EQ("abc", reflection->GetStringReference(message, F("default_string_piece"), &scratch));
+
+ EXPECT_EQ("123", reflection->GetString(message, F("default_cord")));
+ EXPECT_EQ("123", reflection->GetStringReference(message, F("default_cord"), &scratch));
+}
+
+void TestUtil::ReflectionTester::ExpectPackedClearViaReflection(
+ const Message& message) {
+ const Reflection* reflection = message.GetReflection();
+
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed32" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed64" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed32")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed64")));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_float" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_double" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_bool" )));
+ EXPECT_EQ(0, reflection->FieldSize(message, F("packed_enum" )));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ Message* sub_message;
+
+ reflection->SetRepeatedInt32 (message, F("repeated_int32" ), 1, 501);
+ reflection->SetRepeatedInt64 (message, F("repeated_int64" ), 1, 502);
+ reflection->SetRepeatedUInt32(message, F("repeated_uint32" ), 1, 503);
+ reflection->SetRepeatedUInt64(message, F("repeated_uint64" ), 1, 504);
+ reflection->SetRepeatedInt32 (message, F("repeated_sint32" ), 1, 505);
+ reflection->SetRepeatedInt64 (message, F("repeated_sint64" ), 1, 506);
+ reflection->SetRepeatedUInt32(message, F("repeated_fixed32" ), 1, 507);
+ reflection->SetRepeatedUInt64(message, F("repeated_fixed64" ), 1, 508);
+ reflection->SetRepeatedInt32 (message, F("repeated_sfixed32"), 1, 509);
+ reflection->SetRepeatedInt64 (message, F("repeated_sfixed64"), 1, 510);
+ reflection->SetRepeatedFloat (message, F("repeated_float" ), 1, 511);
+ reflection->SetRepeatedDouble(message, F("repeated_double" ), 1, 512);
+ reflection->SetRepeatedBool (message, F("repeated_bool" ), 1, true);
+ reflection->SetRepeatedString(message, F("repeated_string" ), 1, "515");
+ reflection->SetRepeatedString(message, F("repeated_bytes" ), 1, "516");
+
+ sub_message = reflection->MutableRepeatedMessage(message, F("repeatedgroup"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 517);
+ sub_message = reflection->MutableRepeatedMessage(message, F("repeated_nested_message"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 518);
+ sub_message = reflection->MutableRepeatedMessage(message, F("repeated_foreign_message"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 519);
+ sub_message = reflection->MutableRepeatedMessage(message, F("repeated_import_message"), 1);
+ sub_message->GetReflection()->SetInt32(sub_message, import_d_, 520);
+
+ reflection->SetRepeatedEnum(message, F("repeated_nested_enum" ), 1, nested_foo_);
+ reflection->SetRepeatedEnum(message, F("repeated_foreign_enum"), 1, foreign_foo_);
+ reflection->SetRepeatedEnum(message, F("repeated_import_enum" ), 1, import_foo_);
+
+ reflection->SetRepeatedString(message, F("repeated_string_piece"), 1, "524");
+ reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525");
+}
+
+void TestUtil::ReflectionTester::ModifyPackedFieldsViaReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ reflection->SetRepeatedInt32 (message, F("packed_int32" ), 1, 801);
+ reflection->SetRepeatedInt64 (message, F("packed_int64" ), 1, 802);
+ reflection->SetRepeatedUInt32(message, F("packed_uint32" ), 1, 803);
+ reflection->SetRepeatedUInt64(message, F("packed_uint64" ), 1, 804);
+ reflection->SetRepeatedInt32 (message, F("packed_sint32" ), 1, 805);
+ reflection->SetRepeatedInt64 (message, F("packed_sint64" ), 1, 806);
+ reflection->SetRepeatedUInt32(message, F("packed_fixed32" ), 1, 807);
+ reflection->SetRepeatedUInt64(message, F("packed_fixed64" ), 1, 808);
+ reflection->SetRepeatedInt32 (message, F("packed_sfixed32"), 1, 809);
+ reflection->SetRepeatedInt64 (message, F("packed_sfixed64"), 1, 810);
+ reflection->SetRepeatedFloat (message, F("packed_float" ), 1, 811);
+ reflection->SetRepeatedDouble(message, F("packed_double" ), 1, 812);
+ reflection->SetRepeatedBool (message, F("packed_bool" ), 1, true);
+ reflection->SetRepeatedEnum (message, F("packed_enum" ), 1, foreign_foo_);
+}
+
+void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i=0; i<output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+
+ reflection->RemoveLast(message, field);
+ }
+}
+
+void TestUtil::ReflectionTester::SwapRepeatedsViaReflection(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ vector<const FieldDescriptor*> output;
+ reflection->ListFields(*message, &output);
+ for (int i=0; i<output.size(); ++i) {
+ const FieldDescriptor* field = output[i];
+ if (!field->is_repeated()) continue;
+
+ reflection->SwapElements(message, field, 0, 1);
+ }
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/test_util.h b/src/third_party/protobuf/src/google/protobuf/test_util.h
new file mode 100644
index 0000000..25165f3
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/test_util.h
@@ -0,0 +1,174 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_TEST_UTIL_H__
+#define GOOGLE_PROTOBUF_TEST_UTIL_H__
+
+#include <stack>
+#include <string>
+#include <google/protobuf/message.h>
+#include <google/protobuf/unittest.pb.h>
+
+namespace google {
+namespace protobuf {
+
+namespace unittest = protobuf_unittest;
+namespace unittest_import = protobuf_unittest_import;
+
+class TestUtil {
+ public:
+ // Set every field in the message to a unique value.
+ static void SetAllFields(unittest::TestAllTypes* message);
+ static void SetAllExtensions(unittest::TestAllExtensions* message);
+ static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message);
+ static void SetPackedFields(unittest::TestPackedTypes* message);
+ static void SetPackedExtensions(unittest::TestPackedExtensions* message);
+ static void SetUnpackedFields(unittest::TestUnpackedTypes* message);
+
+ // Use the repeated versions of the set_*() accessors to modify all the
+ // repeated fields of the messsage (which should already have been
+ // initialized with Set*Fields()). Set*Fields() itself only tests
+ // the add_*() accessors.
+ static void ModifyRepeatedFields(unittest::TestAllTypes* message);
+ static void ModifyRepeatedExtensions(unittest::TestAllExtensions* message);
+ static void ModifyPackedFields(unittest::TestPackedTypes* message);
+ static void ModifyPackedExtensions(unittest::TestPackedExtensions* message);
+
+ // Check that all fields have the values that they should have after
+ // Set*Fields() is called.
+ static void ExpectAllFieldsSet(const unittest::TestAllTypes& message);
+ static void ExpectAllExtensionsSet(
+ const unittest::TestAllExtensions& message);
+ static void ExpectPackedFieldsSet(const unittest::TestPackedTypes& message);
+ static void ExpectPackedExtensionsSet(
+ const unittest::TestPackedExtensions& message);
+ static void ExpectUnpackedFieldsSet(
+ const unittest::TestUnpackedTypes& message);
+
+ // Expect that the message is modified as would be expected from
+ // Modify*Fields().
+ static void ExpectRepeatedFieldsModified(
+ const unittest::TestAllTypes& message);
+ static void ExpectRepeatedExtensionsModified(
+ const unittest::TestAllExtensions& message);
+ static void ExpectPackedFieldsModified(
+ const unittest::TestPackedTypes& message);
+ static void ExpectPackedExtensionsModified(
+ const unittest::TestPackedExtensions& message);
+
+ // Check that all fields have their default values.
+ static void ExpectClear(const unittest::TestAllTypes& message);
+ static void ExpectExtensionsClear(const unittest::TestAllExtensions& message);
+ static void ExpectPackedClear(const unittest::TestPackedTypes& message);
+ static void ExpectPackedExtensionsClear(
+ const unittest::TestPackedExtensions& message);
+
+ // Check that the passed-in serialization is the canonical serialization we
+ // expect for a TestFieldOrderings message filled in by
+ // SetAllFieldsAndExtensions().
+ static void ExpectAllFieldsAndExtensionsInOrder(const string& serialized);
+
+ // Check that all repeated fields have had their last elements removed.
+ static void ExpectLastRepeatedsRemoved(
+ const unittest::TestAllTypes& message);
+ static void ExpectLastRepeatedExtensionsRemoved(
+ const unittest::TestAllExtensions& message);
+
+ // Check that all repeated fields have had their first and last elements
+ // swapped.
+ static void ExpectRepeatedsSwapped(const unittest::TestAllTypes& message);
+ static void ExpectRepeatedExtensionsSwapped(
+ const unittest::TestAllExtensions& message);
+
+ // Like above, but use the reflection interface.
+ class ReflectionTester {
+ public:
+ // base_descriptor must be a descriptor for TestAllTypes or
+ // TestAllExtensions. In the former case, ReflectionTester fetches from
+ // it the FieldDescriptors needed to use the reflection interface. In
+ // the latter case, ReflectionTester searches for extension fields in
+ // its file.
+ explicit ReflectionTester(const Descriptor* base_descriptor);
+
+ void SetAllFieldsViaReflection(Message* message);
+ void ModifyRepeatedFieldsViaReflection(Message* message);
+ void ExpectAllFieldsSetViaReflection(const Message& message);
+ void ExpectClearViaReflection(const Message& message);
+
+ void SetPackedFieldsViaReflection(Message* message);
+ void ModifyPackedFieldsViaReflection(Message* message);
+ void ExpectPackedFieldsSetViaReflection(const Message& message);
+ void ExpectPackedClearViaReflection(const Message& message);
+
+ void RemoveLastRepeatedsViaReflection(Message* message);
+ void SwapRepeatedsViaReflection(Message* message);
+
+ private:
+ const FieldDescriptor* F(const string& name);
+
+ const Descriptor* base_descriptor_;
+
+ const FieldDescriptor* group_a_;
+ const FieldDescriptor* repeated_group_a_;
+ const FieldDescriptor* nested_b_;
+ const FieldDescriptor* foreign_c_;
+ const FieldDescriptor* import_d_;
+
+ const EnumValueDescriptor* nested_foo_;
+ const EnumValueDescriptor* nested_bar_;
+ const EnumValueDescriptor* nested_baz_;
+ const EnumValueDescriptor* foreign_foo_;
+ const EnumValueDescriptor* foreign_bar_;
+ const EnumValueDescriptor* foreign_baz_;
+ const EnumValueDescriptor* import_foo_;
+ const EnumValueDescriptor* import_bar_;
+ const EnumValueDescriptor* import_baz_;
+
+ // We have to split this into three function otherwise it creates a stack
+ // frame so large that it triggers a warning.
+ void ExpectAllFieldsSetViaReflection1(const Message& message);
+ void ExpectAllFieldsSetViaReflection2(const Message& message);
+ void ExpectAllFieldsSetViaReflection3(const Message& message);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionTester);
+ };
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtil);
+};
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_TEST_UTIL_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/test_util_lite.cc b/src/third_party/protobuf/src/google/protobuf/test_util_lite.cc
new file mode 100644
index 0000000..d7140e0
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/test_util_lite.cc
@@ -0,0 +1,1502 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/test_util_lite.h>
+#include <google/protobuf/stubs/common.h>
+
+
+#define EXPECT_TRUE GOOGLE_CHECK
+#define ASSERT_TRUE GOOGLE_CHECK
+#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND))
+#define EXPECT_EQ GOOGLE_CHECK_EQ
+#define ASSERT_EQ GOOGLE_CHECK_EQ
+
+namespace google {
+namespace protobuf {
+
+void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* message) {
+ message->set_optional_int32 (101);
+ message->set_optional_int64 (102);
+ message->set_optional_uint32 (103);
+ message->set_optional_uint64 (104);
+ message->set_optional_sint32 (105);
+ message->set_optional_sint64 (106);
+ message->set_optional_fixed32 (107);
+ message->set_optional_fixed64 (108);
+ message->set_optional_sfixed32(109);
+ message->set_optional_sfixed64(110);
+ message->set_optional_float (111);
+ message->set_optional_double (112);
+ message->set_optional_bool (true);
+ message->set_optional_string ("115");
+ message->set_optional_bytes ("116");
+
+ message->mutable_optionalgroup ()->set_a(117);
+ message->mutable_optional_nested_message ()->set_bb(118);
+ message->mutable_optional_foreign_message()->set_c(119);
+ message->mutable_optional_import_message ()->set_d(120);
+
+ message->set_optional_nested_enum (unittest::TestAllTypesLite::BAZ );
+ message->set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ );
+ message->set_optional_import_enum (unittest_import::IMPORT_LITE_BAZ);
+
+
+ // -----------------------------------------------------------------
+
+ message->add_repeated_int32 (201);
+ message->add_repeated_int64 (202);
+ message->add_repeated_uint32 (203);
+ message->add_repeated_uint64 (204);
+ message->add_repeated_sint32 (205);
+ message->add_repeated_sint64 (206);
+ message->add_repeated_fixed32 (207);
+ message->add_repeated_fixed64 (208);
+ message->add_repeated_sfixed32(209);
+ message->add_repeated_sfixed64(210);
+ message->add_repeated_float (211);
+ message->add_repeated_double (212);
+ message->add_repeated_bool (true);
+ message->add_repeated_string ("215");
+ message->add_repeated_bytes ("216");
+
+ message->add_repeatedgroup ()->set_a(217);
+ message->add_repeated_nested_message ()->set_bb(218);
+ message->add_repeated_foreign_message()->set_c(219);
+ message->add_repeated_import_message ()->set_d(220);
+
+ message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAR );
+ message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAR );
+ message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAR);
+
+
+ // Add a second one of each field.
+ message->add_repeated_int32 (301);
+ message->add_repeated_int64 (302);
+ message->add_repeated_uint32 (303);
+ message->add_repeated_uint64 (304);
+ message->add_repeated_sint32 (305);
+ message->add_repeated_sint64 (306);
+ message->add_repeated_fixed32 (307);
+ message->add_repeated_fixed64 (308);
+ message->add_repeated_sfixed32(309);
+ message->add_repeated_sfixed64(310);
+ message->add_repeated_float (311);
+ message->add_repeated_double (312);
+ message->add_repeated_bool (false);
+ message->add_repeated_string ("315");
+ message->add_repeated_bytes ("316");
+
+ message->add_repeatedgroup ()->set_a(317);
+ message->add_repeated_nested_message ()->set_bb(318);
+ message->add_repeated_foreign_message()->set_c(319);
+ message->add_repeated_import_message ()->set_d(320);
+
+ message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAZ );
+ message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAZ );
+ message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAZ);
+
+
+ // -----------------------------------------------------------------
+
+ message->set_default_int32 (401);
+ message->set_default_int64 (402);
+ message->set_default_uint32 (403);
+ message->set_default_uint64 (404);
+ message->set_default_sint32 (405);
+ message->set_default_sint64 (406);
+ message->set_default_fixed32 (407);
+ message->set_default_fixed64 (408);
+ message->set_default_sfixed32(409);
+ message->set_default_sfixed64(410);
+ message->set_default_float (411);
+ message->set_default_double (412);
+ message->set_default_bool (false);
+ message->set_default_string ("415");
+ message->set_default_bytes ("416");
+
+ message->set_default_nested_enum (unittest::TestAllTypesLite::FOO );
+ message->set_default_foreign_enum(unittest::FOREIGN_LITE_FOO );
+ message->set_default_import_enum (unittest_import::IMPORT_LITE_FOO);
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyRepeatedFields(unittest::TestAllTypesLite* message) {
+ message->set_repeated_int32 (1, 501);
+ message->set_repeated_int64 (1, 502);
+ message->set_repeated_uint32 (1, 503);
+ message->set_repeated_uint64 (1, 504);
+ message->set_repeated_sint32 (1, 505);
+ message->set_repeated_sint64 (1, 506);
+ message->set_repeated_fixed32 (1, 507);
+ message->set_repeated_fixed64 (1, 508);
+ message->set_repeated_sfixed32(1, 509);
+ message->set_repeated_sfixed64(1, 510);
+ message->set_repeated_float (1, 511);
+ message->set_repeated_double (1, 512);
+ message->set_repeated_bool (1, true);
+ message->set_repeated_string (1, "515");
+ message->set_repeated_bytes (1, "516");
+
+ message->mutable_repeatedgroup (1)->set_a(517);
+ message->mutable_repeated_nested_message (1)->set_bb(518);
+ message->mutable_repeated_foreign_message(1)->set_c(519);
+ message->mutable_repeated_import_message (1)->set_d(520);
+
+ message->set_repeated_nested_enum (1, unittest::TestAllTypesLite::FOO );
+ message->set_repeated_foreign_enum(1, unittest::FOREIGN_LITE_FOO );
+ message->set_repeated_import_enum (1, unittest_import::IMPORT_LITE_FOO);
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectAllFieldsSet(
+ const unittest::TestAllTypesLite& message) {
+ EXPECT_TRUE(message.has_optional_int32 ());
+ EXPECT_TRUE(message.has_optional_int64 ());
+ EXPECT_TRUE(message.has_optional_uint32 ());
+ EXPECT_TRUE(message.has_optional_uint64 ());
+ EXPECT_TRUE(message.has_optional_sint32 ());
+ EXPECT_TRUE(message.has_optional_sint64 ());
+ EXPECT_TRUE(message.has_optional_fixed32 ());
+ EXPECT_TRUE(message.has_optional_fixed64 ());
+ EXPECT_TRUE(message.has_optional_sfixed32());
+ EXPECT_TRUE(message.has_optional_sfixed64());
+ EXPECT_TRUE(message.has_optional_float ());
+ EXPECT_TRUE(message.has_optional_double ());
+ EXPECT_TRUE(message.has_optional_bool ());
+ EXPECT_TRUE(message.has_optional_string ());
+ EXPECT_TRUE(message.has_optional_bytes ());
+
+ EXPECT_TRUE(message.has_optionalgroup ());
+ EXPECT_TRUE(message.has_optional_nested_message ());
+ EXPECT_TRUE(message.has_optional_foreign_message());
+ EXPECT_TRUE(message.has_optional_import_message ());
+
+ EXPECT_TRUE(message.optionalgroup ().has_a());
+ EXPECT_TRUE(message.optional_nested_message ().has_bb());
+ EXPECT_TRUE(message.optional_foreign_message().has_c());
+ EXPECT_TRUE(message.optional_import_message ().has_d());
+
+ EXPECT_TRUE(message.has_optional_nested_enum ());
+ EXPECT_TRUE(message.has_optional_foreign_enum());
+ EXPECT_TRUE(message.has_optional_import_enum ());
+
+
+ EXPECT_EQ(101 , message.optional_int32 ());
+ EXPECT_EQ(102 , message.optional_int64 ());
+ EXPECT_EQ(103 , message.optional_uint32 ());
+ EXPECT_EQ(104 , message.optional_uint64 ());
+ EXPECT_EQ(105 , message.optional_sint32 ());
+ EXPECT_EQ(106 , message.optional_sint64 ());
+ EXPECT_EQ(107 , message.optional_fixed32 ());
+ EXPECT_EQ(108 , message.optional_fixed64 ());
+ EXPECT_EQ(109 , message.optional_sfixed32());
+ EXPECT_EQ(110 , message.optional_sfixed64());
+ EXPECT_EQ(111 , message.optional_float ());
+ EXPECT_EQ(112 , message.optional_double ());
+ EXPECT_EQ(true , message.optional_bool ());
+ EXPECT_EQ("115", message.optional_string ());
+ EXPECT_EQ("116", message.optional_bytes ());
+
+ EXPECT_EQ(117, message.optionalgroup ().a());
+ EXPECT_EQ(118, message.optional_nested_message ().bb());
+ EXPECT_EQ(119, message.optional_foreign_message().c());
+ EXPECT_EQ(120, message.optional_import_message ().d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.optional_nested_enum ());
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.optional_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.optional_import_enum ());
+
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, message.repeated_int32_size ());
+ ASSERT_EQ(2, message.repeated_int64_size ());
+ ASSERT_EQ(2, message.repeated_uint32_size ());
+ ASSERT_EQ(2, message.repeated_uint64_size ());
+ ASSERT_EQ(2, message.repeated_sint32_size ());
+ ASSERT_EQ(2, message.repeated_sint64_size ());
+ ASSERT_EQ(2, message.repeated_fixed32_size ());
+ ASSERT_EQ(2, message.repeated_fixed64_size ());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size ());
+ ASSERT_EQ(2, message.repeated_double_size ());
+ ASSERT_EQ(2, message.repeated_bool_size ());
+ ASSERT_EQ(2, message.repeated_string_size ());
+ ASSERT_EQ(2, message.repeated_bytes_size ());
+
+ ASSERT_EQ(2, message.repeatedgroup_size ());
+ ASSERT_EQ(2, message.repeated_nested_message_size ());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_nested_enum_size ());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size ());
+ ASSERT_EQ(2, message.repeated_import_enum_size ());
+
+
+ EXPECT_EQ(201 , message.repeated_int32 (0));
+ EXPECT_EQ(202 , message.repeated_int64 (0));
+ EXPECT_EQ(203 , message.repeated_uint32 (0));
+ EXPECT_EQ(204 , message.repeated_uint64 (0));
+ EXPECT_EQ(205 , message.repeated_sint32 (0));
+ EXPECT_EQ(206 , message.repeated_sint64 (0));
+ EXPECT_EQ(207 , message.repeated_fixed32 (0));
+ EXPECT_EQ(208 , message.repeated_fixed64 (0));
+ EXPECT_EQ(209 , message.repeated_sfixed32(0));
+ EXPECT_EQ(210 , message.repeated_sfixed64(0));
+ EXPECT_EQ(211 , message.repeated_float (0));
+ EXPECT_EQ(212 , message.repeated_double (0));
+ EXPECT_EQ(true , message.repeated_bool (0));
+ EXPECT_EQ("215", message.repeated_string (0));
+ EXPECT_EQ("216", message.repeated_bytes (0));
+
+ EXPECT_EQ(217, message.repeatedgroup (0).a());
+ EXPECT_EQ(218, message.repeated_nested_message (0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message (0).d());
+
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum (0));
+
+ EXPECT_EQ(301 , message.repeated_int32 (1));
+ EXPECT_EQ(302 , message.repeated_int64 (1));
+ EXPECT_EQ(303 , message.repeated_uint32 (1));
+ EXPECT_EQ(304 , message.repeated_uint64 (1));
+ EXPECT_EQ(305 , message.repeated_sint32 (1));
+ EXPECT_EQ(306 , message.repeated_sint64 (1));
+ EXPECT_EQ(307 , message.repeated_fixed32 (1));
+ EXPECT_EQ(308 , message.repeated_fixed64 (1));
+ EXPECT_EQ(309 , message.repeated_sfixed32(1));
+ EXPECT_EQ(310 , message.repeated_sfixed64(1));
+ EXPECT_EQ(311 , message.repeated_float (1));
+ EXPECT_EQ(312 , message.repeated_double (1));
+ EXPECT_EQ(false, message.repeated_bool (1));
+ EXPECT_EQ("315", message.repeated_string (1));
+ EXPECT_EQ("316", message.repeated_bytes (1));
+
+ EXPECT_EQ(317, message.repeatedgroup (1).a());
+ EXPECT_EQ(318, message.repeated_nested_message (1).bb());
+ EXPECT_EQ(319, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(320, message.repeated_import_message (1).d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.repeated_nested_enum (1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.repeated_foreign_enum(1));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.repeated_import_enum (1));
+
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(message.has_default_int32 ());
+ EXPECT_TRUE(message.has_default_int64 ());
+ EXPECT_TRUE(message.has_default_uint32 ());
+ EXPECT_TRUE(message.has_default_uint64 ());
+ EXPECT_TRUE(message.has_default_sint32 ());
+ EXPECT_TRUE(message.has_default_sint64 ());
+ EXPECT_TRUE(message.has_default_fixed32 ());
+ EXPECT_TRUE(message.has_default_fixed64 ());
+ EXPECT_TRUE(message.has_default_sfixed32());
+ EXPECT_TRUE(message.has_default_sfixed64());
+ EXPECT_TRUE(message.has_default_float ());
+ EXPECT_TRUE(message.has_default_double ());
+ EXPECT_TRUE(message.has_default_bool ());
+ EXPECT_TRUE(message.has_default_string ());
+ EXPECT_TRUE(message.has_default_bytes ());
+
+ EXPECT_TRUE(message.has_default_nested_enum ());
+ EXPECT_TRUE(message.has_default_foreign_enum());
+ EXPECT_TRUE(message.has_default_import_enum ());
+
+
+ EXPECT_EQ(401 , message.default_int32 ());
+ EXPECT_EQ(402 , message.default_int64 ());
+ EXPECT_EQ(403 , message.default_uint32 ());
+ EXPECT_EQ(404 , message.default_uint64 ());
+ EXPECT_EQ(405 , message.default_sint32 ());
+ EXPECT_EQ(406 , message.default_sint64 ());
+ EXPECT_EQ(407 , message.default_fixed32 ());
+ EXPECT_EQ(408 , message.default_fixed64 ());
+ EXPECT_EQ(409 , message.default_sfixed32());
+ EXPECT_EQ(410 , message.default_sfixed64());
+ EXPECT_EQ(411 , message.default_float ());
+ EXPECT_EQ(412 , message.default_double ());
+ EXPECT_EQ(false, message.default_bool ());
+ EXPECT_EQ("415", message.default_string ());
+ EXPECT_EQ("416", message.default_bytes ());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.default_nested_enum ());
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.default_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.default_import_enum ());
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& message) {
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(message.has_optional_int32 ());
+ EXPECT_FALSE(message.has_optional_int64 ());
+ EXPECT_FALSE(message.has_optional_uint32 ());
+ EXPECT_FALSE(message.has_optional_uint64 ());
+ EXPECT_FALSE(message.has_optional_sint32 ());
+ EXPECT_FALSE(message.has_optional_sint64 ());
+ EXPECT_FALSE(message.has_optional_fixed32 ());
+ EXPECT_FALSE(message.has_optional_fixed64 ());
+ EXPECT_FALSE(message.has_optional_sfixed32());
+ EXPECT_FALSE(message.has_optional_sfixed64());
+ EXPECT_FALSE(message.has_optional_float ());
+ EXPECT_FALSE(message.has_optional_double ());
+ EXPECT_FALSE(message.has_optional_bool ());
+ EXPECT_FALSE(message.has_optional_string ());
+ EXPECT_FALSE(message.has_optional_bytes ());
+
+ EXPECT_FALSE(message.has_optionalgroup ());
+ EXPECT_FALSE(message.has_optional_nested_message ());
+ EXPECT_FALSE(message.has_optional_foreign_message());
+ EXPECT_FALSE(message.has_optional_import_message ());
+
+ EXPECT_FALSE(message.has_optional_nested_enum ());
+ EXPECT_FALSE(message.has_optional_foreign_enum());
+ EXPECT_FALSE(message.has_optional_import_enum ());
+
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0 , message.optional_int32 ());
+ EXPECT_EQ(0 , message.optional_int64 ());
+ EXPECT_EQ(0 , message.optional_uint32 ());
+ EXPECT_EQ(0 , message.optional_uint64 ());
+ EXPECT_EQ(0 , message.optional_sint32 ());
+ EXPECT_EQ(0 , message.optional_sint64 ());
+ EXPECT_EQ(0 , message.optional_fixed32 ());
+ EXPECT_EQ(0 , message.optional_fixed64 ());
+ EXPECT_EQ(0 , message.optional_sfixed32());
+ EXPECT_EQ(0 , message.optional_sfixed64());
+ EXPECT_EQ(0 , message.optional_float ());
+ EXPECT_EQ(0 , message.optional_double ());
+ EXPECT_EQ(false, message.optional_bool ());
+ EXPECT_EQ("" , message.optional_string ());
+ EXPECT_EQ("" , message.optional_bytes ());
+
+ // Embedded messages should also be clear.
+ EXPECT_FALSE(message.optionalgroup ().has_a());
+ EXPECT_FALSE(message.optional_nested_message ().has_bb());
+ EXPECT_FALSE(message.optional_foreign_message().has_c());
+ EXPECT_FALSE(message.optional_import_message ().has_d());
+
+ EXPECT_EQ(0, message.optionalgroup ().a());
+ EXPECT_EQ(0, message.optional_nested_message ().bb());
+ EXPECT_EQ(0, message.optional_foreign_message().c());
+ EXPECT_EQ(0, message.optional_import_message ().d());
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.optional_nested_enum ());
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.optional_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.optional_import_enum ());
+
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, message.repeated_int32_size ());
+ EXPECT_EQ(0, message.repeated_int64_size ());
+ EXPECT_EQ(0, message.repeated_uint32_size ());
+ EXPECT_EQ(0, message.repeated_uint64_size ());
+ EXPECT_EQ(0, message.repeated_sint32_size ());
+ EXPECT_EQ(0, message.repeated_sint64_size ());
+ EXPECT_EQ(0, message.repeated_fixed32_size ());
+ EXPECT_EQ(0, message.repeated_fixed64_size ());
+ EXPECT_EQ(0, message.repeated_sfixed32_size());
+ EXPECT_EQ(0, message.repeated_sfixed64_size());
+ EXPECT_EQ(0, message.repeated_float_size ());
+ EXPECT_EQ(0, message.repeated_double_size ());
+ EXPECT_EQ(0, message.repeated_bool_size ());
+ EXPECT_EQ(0, message.repeated_string_size ());
+ EXPECT_EQ(0, message.repeated_bytes_size ());
+
+ EXPECT_EQ(0, message.repeatedgroup_size ());
+ EXPECT_EQ(0, message.repeated_nested_message_size ());
+ EXPECT_EQ(0, message.repeated_foreign_message_size());
+ EXPECT_EQ(0, message.repeated_import_message_size ());
+ EXPECT_EQ(0, message.repeated_nested_enum_size ());
+ EXPECT_EQ(0, message.repeated_foreign_enum_size ());
+ EXPECT_EQ(0, message.repeated_import_enum_size ());
+
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(message.has_default_int32 ());
+ EXPECT_FALSE(message.has_default_int64 ());
+ EXPECT_FALSE(message.has_default_uint32 ());
+ EXPECT_FALSE(message.has_default_uint64 ());
+ EXPECT_FALSE(message.has_default_sint32 ());
+ EXPECT_FALSE(message.has_default_sint64 ());
+ EXPECT_FALSE(message.has_default_fixed32 ());
+ EXPECT_FALSE(message.has_default_fixed64 ());
+ EXPECT_FALSE(message.has_default_sfixed32());
+ EXPECT_FALSE(message.has_default_sfixed64());
+ EXPECT_FALSE(message.has_default_float ());
+ EXPECT_FALSE(message.has_default_double ());
+ EXPECT_FALSE(message.has_default_bool ());
+ EXPECT_FALSE(message.has_default_string ());
+ EXPECT_FALSE(message.has_default_bytes ());
+
+ EXPECT_FALSE(message.has_default_nested_enum ());
+ EXPECT_FALSE(message.has_default_foreign_enum());
+ EXPECT_FALSE(message.has_default_import_enum ());
+
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ( 41 , message.default_int32 ());
+ EXPECT_EQ( 42 , message.default_int64 ());
+ EXPECT_EQ( 43 , message.default_uint32 ());
+ EXPECT_EQ( 44 , message.default_uint64 ());
+ EXPECT_EQ(-45 , message.default_sint32 ());
+ EXPECT_EQ( 46 , message.default_sint64 ());
+ EXPECT_EQ( 47 , message.default_fixed32 ());
+ EXPECT_EQ( 48 , message.default_fixed64 ());
+ EXPECT_EQ( 49 , message.default_sfixed32());
+ EXPECT_EQ(-50 , message.default_sfixed64());
+ EXPECT_EQ( 51.5 , message.default_float ());
+ EXPECT_EQ( 52e3 , message.default_double ());
+ EXPECT_EQ(true , message.default_bool ());
+ EXPECT_EQ("hello", message.default_string ());
+ EXPECT_EQ("world", message.default_bytes ());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.default_nested_enum ());
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.default_foreign_enum());
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.default_import_enum ());
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectRepeatedFieldsModified(
+ const unittest::TestAllTypesLite& message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ ASSERT_EQ(2, message.repeated_int32_size ());
+ ASSERT_EQ(2, message.repeated_int64_size ());
+ ASSERT_EQ(2, message.repeated_uint32_size ());
+ ASSERT_EQ(2, message.repeated_uint64_size ());
+ ASSERT_EQ(2, message.repeated_sint32_size ());
+ ASSERT_EQ(2, message.repeated_sint64_size ());
+ ASSERT_EQ(2, message.repeated_fixed32_size ());
+ ASSERT_EQ(2, message.repeated_fixed64_size ());
+ ASSERT_EQ(2, message.repeated_sfixed32_size());
+ ASSERT_EQ(2, message.repeated_sfixed64_size());
+ ASSERT_EQ(2, message.repeated_float_size ());
+ ASSERT_EQ(2, message.repeated_double_size ());
+ ASSERT_EQ(2, message.repeated_bool_size ());
+ ASSERT_EQ(2, message.repeated_string_size ());
+ ASSERT_EQ(2, message.repeated_bytes_size ());
+
+ ASSERT_EQ(2, message.repeatedgroup_size ());
+ ASSERT_EQ(2, message.repeated_nested_message_size ());
+ ASSERT_EQ(2, message.repeated_foreign_message_size());
+ ASSERT_EQ(2, message.repeated_import_message_size ());
+ ASSERT_EQ(2, message.repeated_nested_enum_size ());
+ ASSERT_EQ(2, message.repeated_foreign_enum_size ());
+ ASSERT_EQ(2, message.repeated_import_enum_size ());
+
+
+ EXPECT_EQ(201 , message.repeated_int32 (0));
+ EXPECT_EQ(202 , message.repeated_int64 (0));
+ EXPECT_EQ(203 , message.repeated_uint32 (0));
+ EXPECT_EQ(204 , message.repeated_uint64 (0));
+ EXPECT_EQ(205 , message.repeated_sint32 (0));
+ EXPECT_EQ(206 , message.repeated_sint64 (0));
+ EXPECT_EQ(207 , message.repeated_fixed32 (0));
+ EXPECT_EQ(208 , message.repeated_fixed64 (0));
+ EXPECT_EQ(209 , message.repeated_sfixed32(0));
+ EXPECT_EQ(210 , message.repeated_sfixed64(0));
+ EXPECT_EQ(211 , message.repeated_float (0));
+ EXPECT_EQ(212 , message.repeated_double (0));
+ EXPECT_EQ(true , message.repeated_bool (0));
+ EXPECT_EQ("215", message.repeated_string (0));
+ EXPECT_EQ("216", message.repeated_bytes (0));
+
+ EXPECT_EQ(217, message.repeatedgroup (0).a());
+ EXPECT_EQ(218, message.repeated_nested_message (0).bb());
+ EXPECT_EQ(219, message.repeated_foreign_message(0).c());
+ EXPECT_EQ(220, message.repeated_import_message (0).d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.repeated_foreign_enum(0));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.repeated_import_enum (0));
+
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(501 , message.repeated_int32 (1));
+ EXPECT_EQ(502 , message.repeated_int64 (1));
+ EXPECT_EQ(503 , message.repeated_uint32 (1));
+ EXPECT_EQ(504 , message.repeated_uint64 (1));
+ EXPECT_EQ(505 , message.repeated_sint32 (1));
+ EXPECT_EQ(506 , message.repeated_sint64 (1));
+ EXPECT_EQ(507 , message.repeated_fixed32 (1));
+ EXPECT_EQ(508 , message.repeated_fixed64 (1));
+ EXPECT_EQ(509 , message.repeated_sfixed32(1));
+ EXPECT_EQ(510 , message.repeated_sfixed64(1));
+ EXPECT_EQ(511 , message.repeated_float (1));
+ EXPECT_EQ(512 , message.repeated_double (1));
+ EXPECT_EQ(true , message.repeated_bool (1));
+ EXPECT_EQ("515", message.repeated_string (1));
+ EXPECT_EQ("516", message.repeated_bytes (1));
+
+ EXPECT_EQ(517, message.repeatedgroup (1).a());
+ EXPECT_EQ(518, message.repeated_nested_message (1).bb());
+ EXPECT_EQ(519, message.repeated_foreign_message(1).c());
+ EXPECT_EQ(520, message.repeated_import_message (1).d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.repeated_nested_enum (1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.repeated_foreign_enum(1));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.repeated_import_enum (1));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::SetPackedFields(unittest::TestPackedTypesLite* message) {
+ message->add_packed_int32 (601);
+ message->add_packed_int64 (602);
+ message->add_packed_uint32 (603);
+ message->add_packed_uint64 (604);
+ message->add_packed_sint32 (605);
+ message->add_packed_sint64 (606);
+ message->add_packed_fixed32 (607);
+ message->add_packed_fixed64 (608);
+ message->add_packed_sfixed32(609);
+ message->add_packed_sfixed64(610);
+ message->add_packed_float (611);
+ message->add_packed_double (612);
+ message->add_packed_bool (true);
+ message->add_packed_enum (unittest::FOREIGN_LITE_BAR);
+ // add a second one of each field
+ message->add_packed_int32 (701);
+ message->add_packed_int64 (702);
+ message->add_packed_uint32 (703);
+ message->add_packed_uint64 (704);
+ message->add_packed_sint32 (705);
+ message->add_packed_sint64 (706);
+ message->add_packed_fixed32 (707);
+ message->add_packed_fixed64 (708);
+ message->add_packed_sfixed32(709);
+ message->add_packed_sfixed64(710);
+ message->add_packed_float (711);
+ message->add_packed_double (712);
+ message->add_packed_bool (false);
+ message->add_packed_enum (unittest::FOREIGN_LITE_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyPackedFields(unittest::TestPackedTypesLite* message) {
+ message->set_packed_int32 (1, 801);
+ message->set_packed_int64 (1, 802);
+ message->set_packed_uint32 (1, 803);
+ message->set_packed_uint64 (1, 804);
+ message->set_packed_sint32 (1, 805);
+ message->set_packed_sint64 (1, 806);
+ message->set_packed_fixed32 (1, 807);
+ message->set_packed_fixed64 (1, 808);
+ message->set_packed_sfixed32(1, 809);
+ message->set_packed_sfixed64(1, 810);
+ message->set_packed_float (1, 811);
+ message->set_packed_double (1, 812);
+ message->set_packed_bool (1, true);
+ message->set_packed_enum (1, unittest::FOREIGN_LITE_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedFieldsSet(
+ const unittest::TestPackedTypesLite& message) {
+ ASSERT_EQ(2, message.packed_int32_size ());
+ ASSERT_EQ(2, message.packed_int64_size ());
+ ASSERT_EQ(2, message.packed_uint32_size ());
+ ASSERT_EQ(2, message.packed_uint64_size ());
+ ASSERT_EQ(2, message.packed_sint32_size ());
+ ASSERT_EQ(2, message.packed_sint64_size ());
+ ASSERT_EQ(2, message.packed_fixed32_size ());
+ ASSERT_EQ(2, message.packed_fixed64_size ());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size ());
+ ASSERT_EQ(2, message.packed_double_size ());
+ ASSERT_EQ(2, message.packed_bool_size ());
+ ASSERT_EQ(2, message.packed_enum_size ());
+
+ EXPECT_EQ(601 , message.packed_int32 (0));
+ EXPECT_EQ(602 , message.packed_int64 (0));
+ EXPECT_EQ(603 , message.packed_uint32 (0));
+ EXPECT_EQ(604 , message.packed_uint64 (0));
+ EXPECT_EQ(605 , message.packed_sint32 (0));
+ EXPECT_EQ(606 , message.packed_sint64 (0));
+ EXPECT_EQ(607 , message.packed_fixed32 (0));
+ EXPECT_EQ(608 , message.packed_fixed64 (0));
+ EXPECT_EQ(609 , message.packed_sfixed32(0));
+ EXPECT_EQ(610 , message.packed_sfixed64(0));
+ EXPECT_EQ(611 , message.packed_float (0));
+ EXPECT_EQ(612 , message.packed_double (0));
+ EXPECT_EQ(true , message.packed_bool (0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0));
+
+ EXPECT_EQ(701 , message.packed_int32 (1));
+ EXPECT_EQ(702 , message.packed_int64 (1));
+ EXPECT_EQ(703 , message.packed_uint32 (1));
+ EXPECT_EQ(704 , message.packed_uint64 (1));
+ EXPECT_EQ(705 , message.packed_sint32 (1));
+ EXPECT_EQ(706 , message.packed_sint64 (1));
+ EXPECT_EQ(707 , message.packed_fixed32 (1));
+ EXPECT_EQ(708 , message.packed_fixed64 (1));
+ EXPECT_EQ(709 , message.packed_sfixed32(1));
+ EXPECT_EQ(710 , message.packed_sfixed64(1));
+ EXPECT_EQ(711 , message.packed_float (1));
+ EXPECT_EQ(712 , message.packed_double (1));
+ EXPECT_EQ(false, message.packed_bool (1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, message.packed_enum(1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedClear(
+ const unittest::TestPackedTypesLite& message) {
+ // Packed repeated fields are empty.
+ EXPECT_EQ(0, message.packed_int32_size ());
+ EXPECT_EQ(0, message.packed_int64_size ());
+ EXPECT_EQ(0, message.packed_uint32_size ());
+ EXPECT_EQ(0, message.packed_uint64_size ());
+ EXPECT_EQ(0, message.packed_sint32_size ());
+ EXPECT_EQ(0, message.packed_sint64_size ());
+ EXPECT_EQ(0, message.packed_fixed32_size ());
+ EXPECT_EQ(0, message.packed_fixed64_size ());
+ EXPECT_EQ(0, message.packed_sfixed32_size());
+ EXPECT_EQ(0, message.packed_sfixed64_size());
+ EXPECT_EQ(0, message.packed_float_size ());
+ EXPECT_EQ(0, message.packed_double_size ());
+ EXPECT_EQ(0, message.packed_bool_size ());
+ EXPECT_EQ(0, message.packed_enum_size ());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedFieldsModified(
+ const unittest::TestPackedTypesLite& message) {
+ // Do the same for packed repeated fields.
+ ASSERT_EQ(2, message.packed_int32_size ());
+ ASSERT_EQ(2, message.packed_int64_size ());
+ ASSERT_EQ(2, message.packed_uint32_size ());
+ ASSERT_EQ(2, message.packed_uint64_size ());
+ ASSERT_EQ(2, message.packed_sint32_size ());
+ ASSERT_EQ(2, message.packed_sint64_size ());
+ ASSERT_EQ(2, message.packed_fixed32_size ());
+ ASSERT_EQ(2, message.packed_fixed64_size ());
+ ASSERT_EQ(2, message.packed_sfixed32_size());
+ ASSERT_EQ(2, message.packed_sfixed64_size());
+ ASSERT_EQ(2, message.packed_float_size ());
+ ASSERT_EQ(2, message.packed_double_size ());
+ ASSERT_EQ(2, message.packed_bool_size ());
+ ASSERT_EQ(2, message.packed_enum_size ());
+
+ EXPECT_EQ(601 , message.packed_int32 (0));
+ EXPECT_EQ(602 , message.packed_int64 (0));
+ EXPECT_EQ(603 , message.packed_uint32 (0));
+ EXPECT_EQ(604 , message.packed_uint64 (0));
+ EXPECT_EQ(605 , message.packed_sint32 (0));
+ EXPECT_EQ(606 , message.packed_sint64 (0));
+ EXPECT_EQ(607 , message.packed_fixed32 (0));
+ EXPECT_EQ(608 , message.packed_fixed64 (0));
+ EXPECT_EQ(609 , message.packed_sfixed32(0));
+ EXPECT_EQ(610 , message.packed_sfixed64(0));
+ EXPECT_EQ(611 , message.packed_float (0));
+ EXPECT_EQ(612 , message.packed_double (0));
+ EXPECT_EQ(true , message.packed_bool (0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0));
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(801 , message.packed_int32 (1));
+ EXPECT_EQ(802 , message.packed_int64 (1));
+ EXPECT_EQ(803 , message.packed_uint32 (1));
+ EXPECT_EQ(804 , message.packed_uint64 (1));
+ EXPECT_EQ(805 , message.packed_sint32 (1));
+ EXPECT_EQ(806 , message.packed_sint64 (1));
+ EXPECT_EQ(807 , message.packed_fixed32 (1));
+ EXPECT_EQ(808 , message.packed_fixed64 (1));
+ EXPECT_EQ(809 , message.packed_sfixed32(1));
+ EXPECT_EQ(810 , message.packed_sfixed64(1));
+ EXPECT_EQ(811 , message.packed_float (1));
+ EXPECT_EQ(812 , message.packed_double (1));
+ EXPECT_EQ(true , message.packed_bool (1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.packed_enum(1));
+}
+
+// ===================================================================
+// Extensions
+//
+// All this code is exactly equivalent to the above code except that it's
+// manipulating extension fields instead of normal ones.
+//
+// I gave up on the 80-char limit here. Sorry.
+
+void TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) {
+ message->SetExtension(unittest::optional_int32_extension_lite , 101);
+ message->SetExtension(unittest::optional_int64_extension_lite , 102);
+ message->SetExtension(unittest::optional_uint32_extension_lite , 103);
+ message->SetExtension(unittest::optional_uint64_extension_lite , 104);
+ message->SetExtension(unittest::optional_sint32_extension_lite , 105);
+ message->SetExtension(unittest::optional_sint64_extension_lite , 106);
+ message->SetExtension(unittest::optional_fixed32_extension_lite , 107);
+ message->SetExtension(unittest::optional_fixed64_extension_lite , 108);
+ message->SetExtension(unittest::optional_sfixed32_extension_lite, 109);
+ message->SetExtension(unittest::optional_sfixed64_extension_lite, 110);
+ message->SetExtension(unittest::optional_float_extension_lite , 111);
+ message->SetExtension(unittest::optional_double_extension_lite , 112);
+ message->SetExtension(unittest::optional_bool_extension_lite , true);
+ message->SetExtension(unittest::optional_string_extension_lite , "115");
+ message->SetExtension(unittest::optional_bytes_extension_lite , "116");
+
+ message->MutableExtension(unittest::optionalgroup_extension_lite )->set_a(117);
+ message->MutableExtension(unittest::optional_nested_message_extension_lite )->set_bb(118);
+ message->MutableExtension(unittest::optional_foreign_message_extension_lite)->set_c(119);
+ message->MutableExtension(unittest::optional_import_message_extension_lite )->set_d(120);
+
+ message->SetExtension(unittest::optional_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ );
+ message->SetExtension(unittest::optional_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ );
+ message->SetExtension(unittest::optional_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ);
+
+
+ // -----------------------------------------------------------------
+
+ message->AddExtension(unittest::repeated_int32_extension_lite , 201);
+ message->AddExtension(unittest::repeated_int64_extension_lite , 202);
+ message->AddExtension(unittest::repeated_uint32_extension_lite , 203);
+ message->AddExtension(unittest::repeated_uint64_extension_lite , 204);
+ message->AddExtension(unittest::repeated_sint32_extension_lite , 205);
+ message->AddExtension(unittest::repeated_sint64_extension_lite , 206);
+ message->AddExtension(unittest::repeated_fixed32_extension_lite , 207);
+ message->AddExtension(unittest::repeated_fixed64_extension_lite , 208);
+ message->AddExtension(unittest::repeated_sfixed32_extension_lite, 209);
+ message->AddExtension(unittest::repeated_sfixed64_extension_lite, 210);
+ message->AddExtension(unittest::repeated_float_extension_lite , 211);
+ message->AddExtension(unittest::repeated_double_extension_lite , 212);
+ message->AddExtension(unittest::repeated_bool_extension_lite , true);
+ message->AddExtension(unittest::repeated_string_extension_lite , "215");
+ message->AddExtension(unittest::repeated_bytes_extension_lite , "216");
+
+ message->AddExtension(unittest::repeatedgroup_extension_lite )->set_a(217);
+ message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(218);
+ message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(219);
+ message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(220);
+
+ message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAR );
+ message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAR );
+ message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAR);
+
+
+ // Add a second one of each field.
+ message->AddExtension(unittest::repeated_int32_extension_lite , 301);
+ message->AddExtension(unittest::repeated_int64_extension_lite , 302);
+ message->AddExtension(unittest::repeated_uint32_extension_lite , 303);
+ message->AddExtension(unittest::repeated_uint64_extension_lite , 304);
+ message->AddExtension(unittest::repeated_sint32_extension_lite , 305);
+ message->AddExtension(unittest::repeated_sint64_extension_lite , 306);
+ message->AddExtension(unittest::repeated_fixed32_extension_lite , 307);
+ message->AddExtension(unittest::repeated_fixed64_extension_lite , 308);
+ message->AddExtension(unittest::repeated_sfixed32_extension_lite, 309);
+ message->AddExtension(unittest::repeated_sfixed64_extension_lite, 310);
+ message->AddExtension(unittest::repeated_float_extension_lite , 311);
+ message->AddExtension(unittest::repeated_double_extension_lite , 312);
+ message->AddExtension(unittest::repeated_bool_extension_lite , false);
+ message->AddExtension(unittest::repeated_string_extension_lite , "315");
+ message->AddExtension(unittest::repeated_bytes_extension_lite , "316");
+
+ message->AddExtension(unittest::repeatedgroup_extension_lite )->set_a(317);
+ message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(318);
+ message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(319);
+ message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(320);
+
+ message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ );
+ message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ );
+ message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ);
+
+
+ // -----------------------------------------------------------------
+
+ message->SetExtension(unittest::default_int32_extension_lite , 401);
+ message->SetExtension(unittest::default_int64_extension_lite , 402);
+ message->SetExtension(unittest::default_uint32_extension_lite , 403);
+ message->SetExtension(unittest::default_uint64_extension_lite , 404);
+ message->SetExtension(unittest::default_sint32_extension_lite , 405);
+ message->SetExtension(unittest::default_sint64_extension_lite , 406);
+ message->SetExtension(unittest::default_fixed32_extension_lite , 407);
+ message->SetExtension(unittest::default_fixed64_extension_lite , 408);
+ message->SetExtension(unittest::default_sfixed32_extension_lite, 409);
+ message->SetExtension(unittest::default_sfixed64_extension_lite, 410);
+ message->SetExtension(unittest::default_float_extension_lite , 411);
+ message->SetExtension(unittest::default_double_extension_lite , 412);
+ message->SetExtension(unittest::default_bool_extension_lite , false);
+ message->SetExtension(unittest::default_string_extension_lite , "415");
+ message->SetExtension(unittest::default_bytes_extension_lite , "416");
+
+ message->SetExtension(unittest::default_nested_enum_extension_lite , unittest::TestAllTypesLite::FOO );
+ message->SetExtension(unittest::default_foreign_enum_extension_lite, unittest::FOREIGN_LITE_FOO );
+ message->SetExtension(unittest::default_import_enum_extension_lite , unittest_import::IMPORT_LITE_FOO);
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyRepeatedExtensions(
+ unittest::TestAllExtensionsLite* message) {
+ message->SetExtension(unittest::repeated_int32_extension_lite , 1, 501);
+ message->SetExtension(unittest::repeated_int64_extension_lite , 1, 502);
+ message->SetExtension(unittest::repeated_uint32_extension_lite , 1, 503);
+ message->SetExtension(unittest::repeated_uint64_extension_lite , 1, 504);
+ message->SetExtension(unittest::repeated_sint32_extension_lite , 1, 505);
+ message->SetExtension(unittest::repeated_sint64_extension_lite , 1, 506);
+ message->SetExtension(unittest::repeated_fixed32_extension_lite , 1, 507);
+ message->SetExtension(unittest::repeated_fixed64_extension_lite , 1, 508);
+ message->SetExtension(unittest::repeated_sfixed32_extension_lite, 1, 509);
+ message->SetExtension(unittest::repeated_sfixed64_extension_lite, 1, 510);
+ message->SetExtension(unittest::repeated_float_extension_lite , 1, 511);
+ message->SetExtension(unittest::repeated_double_extension_lite , 1, 512);
+ message->SetExtension(unittest::repeated_bool_extension_lite , 1, true);
+ message->SetExtension(unittest::repeated_string_extension_lite , 1, "515");
+ message->SetExtension(unittest::repeated_bytes_extension_lite , 1, "516");
+
+ message->MutableExtension(unittest::repeatedgroup_extension_lite , 1)->set_a(517);
+ message->MutableExtension(unittest::repeated_nested_message_extension_lite , 1)->set_bb(518);
+ message->MutableExtension(unittest::repeated_foreign_message_extension_lite, 1)->set_c(519);
+ message->MutableExtension(unittest::repeated_import_message_extension_lite , 1)->set_d(520);
+
+ message->SetExtension(unittest::repeated_nested_enum_extension_lite , 1, unittest::TestAllTypesLite::FOO );
+ message->SetExtension(unittest::repeated_foreign_enum_extension_lite, 1, unittest::FOREIGN_LITE_FOO );
+ message->SetExtension(unittest::repeated_import_enum_extension_lite , 1, unittest_import::IMPORT_LITE_FOO);
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectAllExtensionsSet(
+ const unittest::TestAllExtensionsLite& message) {
+ EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension_lite ));
+
+ EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension_lite ));
+
+ EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension_lite).has_c());
+ EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d());
+
+ EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension_lite ));
+
+
+ EXPECT_EQ(101 , message.GetExtension(unittest::optional_int32_extension_lite ));
+ EXPECT_EQ(102 , message.GetExtension(unittest::optional_int64_extension_lite ));
+ EXPECT_EQ(103 , message.GetExtension(unittest::optional_uint32_extension_lite ));
+ EXPECT_EQ(104 , message.GetExtension(unittest::optional_uint64_extension_lite ));
+ EXPECT_EQ(105 , message.GetExtension(unittest::optional_sint32_extension_lite ));
+ EXPECT_EQ(106 , message.GetExtension(unittest::optional_sint64_extension_lite ));
+ EXPECT_EQ(107 , message.GetExtension(unittest::optional_fixed32_extension_lite ));
+ EXPECT_EQ(108 , message.GetExtension(unittest::optional_fixed64_extension_lite ));
+ EXPECT_EQ(109 , message.GetExtension(unittest::optional_sfixed32_extension_lite));
+ EXPECT_EQ(110 , message.GetExtension(unittest::optional_sfixed64_extension_lite));
+ EXPECT_EQ(111 , message.GetExtension(unittest::optional_float_extension_lite ));
+ EXPECT_EQ(112 , message.GetExtension(unittest::optional_double_extension_lite ));
+ EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension_lite ));
+ EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension_lite ));
+ EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension_lite ));
+
+ EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension_lite ).a());
+ EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb());
+ EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension_lite).c());
+ EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension_lite ).d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::optional_nested_enum_extension_lite ));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::optional_foreign_enum_extension_lite));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::optional_import_enum_extension_lite ));
+
+
+ // -----------------------------------------------------------------
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite ));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite ));
+
+
+ EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension_lite , 0));
+ EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension_lite , 0));
+ EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension_lite , 0));
+ EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension_lite , 0));
+ EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension_lite , 0));
+ EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension_lite , 0));
+ EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0));
+ EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0));
+ EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0));
+ EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0));
+ EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension_lite , 0));
+ EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension_lite , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 0));
+ EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite , 0));
+ EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite , 0));
+
+ EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite , 0).a());
+ EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb());
+ EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c());
+ EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0));
+
+
+ EXPECT_EQ(301 , message.GetExtension(unittest::repeated_int32_extension_lite , 1));
+ EXPECT_EQ(302 , message.GetExtension(unittest::repeated_int64_extension_lite , 1));
+ EXPECT_EQ(303 , message.GetExtension(unittest::repeated_uint32_extension_lite , 1));
+ EXPECT_EQ(304 , message.GetExtension(unittest::repeated_uint64_extension_lite , 1));
+ EXPECT_EQ(305 , message.GetExtension(unittest::repeated_sint32_extension_lite , 1));
+ EXPECT_EQ(306 , message.GetExtension(unittest::repeated_sint64_extension_lite , 1));
+ EXPECT_EQ(307 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1));
+ EXPECT_EQ(308 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1));
+ EXPECT_EQ(309 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1));
+ EXPECT_EQ(310 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1));
+ EXPECT_EQ(311 , message.GetExtension(unittest::repeated_float_extension_lite , 1));
+ EXPECT_EQ(312 , message.GetExtension(unittest::repeated_double_extension_lite , 1));
+ EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension_lite , 1));
+ EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension_lite , 1));
+ EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension_lite , 1));
+
+ EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension_lite , 1).a());
+ EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb());
+ EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c());
+ EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1));
+
+
+ // -----------------------------------------------------------------
+
+ EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_float_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_double_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_string_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension_lite ));
+
+ EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension_lite ));
+ EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension_lite));
+ EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension_lite ));
+
+
+ EXPECT_EQ(401 , message.GetExtension(unittest::default_int32_extension_lite ));
+ EXPECT_EQ(402 , message.GetExtension(unittest::default_int64_extension_lite ));
+ EXPECT_EQ(403 , message.GetExtension(unittest::default_uint32_extension_lite ));
+ EXPECT_EQ(404 , message.GetExtension(unittest::default_uint64_extension_lite ));
+ EXPECT_EQ(405 , message.GetExtension(unittest::default_sint32_extension_lite ));
+ EXPECT_EQ(406 , message.GetExtension(unittest::default_sint64_extension_lite ));
+ EXPECT_EQ(407 , message.GetExtension(unittest::default_fixed32_extension_lite ));
+ EXPECT_EQ(408 , message.GetExtension(unittest::default_fixed64_extension_lite ));
+ EXPECT_EQ(409 , message.GetExtension(unittest::default_sfixed32_extension_lite));
+ EXPECT_EQ(410 , message.GetExtension(unittest::default_sfixed64_extension_lite));
+ EXPECT_EQ(411 , message.GetExtension(unittest::default_float_extension_lite ));
+ EXPECT_EQ(412 , message.GetExtension(unittest::default_double_extension_lite ));
+ EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension_lite ));
+ EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension_lite ));
+ EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension_lite ));
+
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::default_nested_enum_extension_lite ));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::default_foreign_enum_extension_lite));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::default_import_enum_extension_lite ));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectExtensionsClear(
+ const unittest::TestAllExtensionsLite& message) {
+ string serialized;
+ ASSERT_TRUE(message.SerializeToString(&serialized));
+ EXPECT_EQ("", serialized);
+ EXPECT_EQ(0, message.ByteSize());
+
+ // has_blah() should initially be false for all optional fields.
+ EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension_lite ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension_lite ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension_lite ));
+
+
+ // Optional fields without defaults are set to zero or something like it.
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_int32_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_int64_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint32_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_uint64_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint32_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_sint64_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed32_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_fixed64_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed32_extension_lite));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_sfixed64_extension_lite));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_float_extension_lite ));
+ EXPECT_EQ(0 , message.GetExtension(unittest::optional_double_extension_lite ));
+ EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension_lite ));
+ EXPECT_EQ("" , message.GetExtension(unittest::optional_string_extension_lite ));
+ EXPECT_EQ("" , message.GetExtension(unittest::optional_bytes_extension_lite ));
+
+ // Embedded messages should also be clear.
+ EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension_lite ).has_a());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension_lite ).has_bb());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension_lite).has_c());
+ EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension_lite ).has_d());
+
+ EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension_lite ).a());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension_lite ).bb());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension_lite).c());
+ EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension_lite ).d());
+
+ // Enums without defaults are set to the first value in the enum.
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::optional_nested_enum_extension_lite ));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::optional_foreign_enum_extension_lite));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::optional_import_enum_extension_lite ));
+
+
+ // Repeated fields are empty.
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension_lite ));
+
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension_lite ));
+
+
+ // has_blah() should also be false for all default fields.
+ EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_float_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_double_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_string_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension_lite ));
+
+ EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension_lite ));
+ EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension_lite));
+ EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension_lite ));
+
+
+ // Fields with defaults have their default values (duh).
+ EXPECT_EQ( 41 , message.GetExtension(unittest::default_int32_extension_lite ));
+ EXPECT_EQ( 42 , message.GetExtension(unittest::default_int64_extension_lite ));
+ EXPECT_EQ( 43 , message.GetExtension(unittest::default_uint32_extension_lite ));
+ EXPECT_EQ( 44 , message.GetExtension(unittest::default_uint64_extension_lite ));
+ EXPECT_EQ(-45 , message.GetExtension(unittest::default_sint32_extension_lite ));
+ EXPECT_EQ( 46 , message.GetExtension(unittest::default_sint64_extension_lite ));
+ EXPECT_EQ( 47 , message.GetExtension(unittest::default_fixed32_extension_lite ));
+ EXPECT_EQ( 48 , message.GetExtension(unittest::default_fixed64_extension_lite ));
+ EXPECT_EQ( 49 , message.GetExtension(unittest::default_sfixed32_extension_lite));
+ EXPECT_EQ(-50 , message.GetExtension(unittest::default_sfixed64_extension_lite));
+ EXPECT_EQ( 51.5 , message.GetExtension(unittest::default_float_extension_lite ));
+ EXPECT_EQ( 52e3 , message.GetExtension(unittest::default_double_extension_lite ));
+ EXPECT_EQ(true , message.GetExtension(unittest::default_bool_extension_lite ));
+ EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension_lite ));
+ EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension_lite ));
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::default_nested_enum_extension_lite ));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::default_foreign_enum_extension_lite));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::default_import_enum_extension_lite ));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectRepeatedExtensionsModified(
+ const unittest::TestAllExtensionsLite& message) {
+ // ModifyRepeatedFields only sets the second repeated element of each
+ // field. In addition to verifying this, we also verify that the first
+ // element and size were *not* modified.
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite ));
+
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite ));
+
+
+ EXPECT_EQ(201 , message.GetExtension(unittest::repeated_int32_extension_lite , 0));
+ EXPECT_EQ(202 , message.GetExtension(unittest::repeated_int64_extension_lite , 0));
+ EXPECT_EQ(203 , message.GetExtension(unittest::repeated_uint32_extension_lite , 0));
+ EXPECT_EQ(204 , message.GetExtension(unittest::repeated_uint64_extension_lite , 0));
+ EXPECT_EQ(205 , message.GetExtension(unittest::repeated_sint32_extension_lite , 0));
+ EXPECT_EQ(206 , message.GetExtension(unittest::repeated_sint64_extension_lite , 0));
+ EXPECT_EQ(207 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0));
+ EXPECT_EQ(208 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0));
+ EXPECT_EQ(209 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0));
+ EXPECT_EQ(210 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0));
+ EXPECT_EQ(211 , message.GetExtension(unittest::repeated_float_extension_lite , 0));
+ EXPECT_EQ(212 , message.GetExtension(unittest::repeated_double_extension_lite , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 0));
+ EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite , 0));
+ EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite , 0));
+
+ EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite , 0).a());
+ EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb());
+ EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c());
+ EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0));
+
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(501 , message.GetExtension(unittest::repeated_int32_extension_lite , 1));
+ EXPECT_EQ(502 , message.GetExtension(unittest::repeated_int64_extension_lite , 1));
+ EXPECT_EQ(503 , message.GetExtension(unittest::repeated_uint32_extension_lite , 1));
+ EXPECT_EQ(504 , message.GetExtension(unittest::repeated_uint64_extension_lite , 1));
+ EXPECT_EQ(505 , message.GetExtension(unittest::repeated_sint32_extension_lite , 1));
+ EXPECT_EQ(506 , message.GetExtension(unittest::repeated_sint64_extension_lite , 1));
+ EXPECT_EQ(507 , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1));
+ EXPECT_EQ(508 , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1));
+ EXPECT_EQ(509 , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1));
+ EXPECT_EQ(510 , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1));
+ EXPECT_EQ(511 , message.GetExtension(unittest::repeated_float_extension_lite , 1));
+ EXPECT_EQ(512 , message.GetExtension(unittest::repeated_double_extension_lite , 1));
+ EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite , 1));
+ EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension_lite , 1));
+ EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension_lite , 1));
+
+ EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension_lite , 1).a());
+ EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb());
+ EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c());
+ EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d());
+
+ EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1));
+ EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::SetPackedExtensions(
+ unittest::TestPackedExtensionsLite* message) {
+ message->AddExtension(unittest::packed_int32_extension_lite , 601);
+ message->AddExtension(unittest::packed_int64_extension_lite , 602);
+ message->AddExtension(unittest::packed_uint32_extension_lite , 603);
+ message->AddExtension(unittest::packed_uint64_extension_lite , 604);
+ message->AddExtension(unittest::packed_sint32_extension_lite , 605);
+ message->AddExtension(unittest::packed_sint64_extension_lite , 606);
+ message->AddExtension(unittest::packed_fixed32_extension_lite , 607);
+ message->AddExtension(unittest::packed_fixed64_extension_lite , 608);
+ message->AddExtension(unittest::packed_sfixed32_extension_lite, 609);
+ message->AddExtension(unittest::packed_sfixed64_extension_lite, 610);
+ message->AddExtension(unittest::packed_float_extension_lite , 611);
+ message->AddExtension(unittest::packed_double_extension_lite , 612);
+ message->AddExtension(unittest::packed_bool_extension_lite , true);
+ message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAR);
+ // add a second one of each field
+ message->AddExtension(unittest::packed_int32_extension_lite , 701);
+ message->AddExtension(unittest::packed_int64_extension_lite , 702);
+ message->AddExtension(unittest::packed_uint32_extension_lite , 703);
+ message->AddExtension(unittest::packed_uint64_extension_lite , 704);
+ message->AddExtension(unittest::packed_sint32_extension_lite , 705);
+ message->AddExtension(unittest::packed_sint64_extension_lite , 706);
+ message->AddExtension(unittest::packed_fixed32_extension_lite , 707);
+ message->AddExtension(unittest::packed_fixed64_extension_lite , 708);
+ message->AddExtension(unittest::packed_sfixed32_extension_lite, 709);
+ message->AddExtension(unittest::packed_sfixed64_extension_lite, 710);
+ message->AddExtension(unittest::packed_float_extension_lite , 711);
+ message->AddExtension(unittest::packed_double_extension_lite , 712);
+ message->AddExtension(unittest::packed_bool_extension_lite , false);
+ message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyPackedExtensions(
+ unittest::TestPackedExtensionsLite* message) {
+ message->SetExtension(unittest::packed_int32_extension_lite , 1, 801);
+ message->SetExtension(unittest::packed_int64_extension_lite , 1, 802);
+ message->SetExtension(unittest::packed_uint32_extension_lite , 1, 803);
+ message->SetExtension(unittest::packed_uint64_extension_lite , 1, 804);
+ message->SetExtension(unittest::packed_sint32_extension_lite , 1, 805);
+ message->SetExtension(unittest::packed_sint64_extension_lite , 1, 806);
+ message->SetExtension(unittest::packed_fixed32_extension_lite , 1, 807);
+ message->SetExtension(unittest::packed_fixed64_extension_lite , 1, 808);
+ message->SetExtension(unittest::packed_sfixed32_extension_lite, 1, 809);
+ message->SetExtension(unittest::packed_sfixed64_extension_lite, 1, 810);
+ message->SetExtension(unittest::packed_float_extension_lite , 1, 811);
+ message->SetExtension(unittest::packed_double_extension_lite , 1, 812);
+ message->SetExtension(unittest::packed_bool_extension_lite , 1, true);
+ message->SetExtension(unittest::packed_enum_extension_lite , 1,
+ unittest::FOREIGN_LITE_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsSet(
+ const unittest::TestPackedExtensionsLite& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite ));
+
+ EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension_lite , 0));
+ EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension_lite , 0));
+ EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension_lite , 0));
+ EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension_lite , 0));
+ EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension_lite , 0));
+ EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension_lite , 0));
+ EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension_lite , 0));
+ EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension_lite , 0));
+ EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0));
+ EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0));
+ EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension_lite , 0));
+ EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension_lite , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR,
+ message.GetExtension(unittest::packed_enum_extension_lite, 0));
+ EXPECT_EQ(701 , message.GetExtension(unittest::packed_int32_extension_lite , 1));
+ EXPECT_EQ(702 , message.GetExtension(unittest::packed_int64_extension_lite , 1));
+ EXPECT_EQ(703 , message.GetExtension(unittest::packed_uint32_extension_lite , 1));
+ EXPECT_EQ(704 , message.GetExtension(unittest::packed_uint64_extension_lite , 1));
+ EXPECT_EQ(705 , message.GetExtension(unittest::packed_sint32_extension_lite , 1));
+ EXPECT_EQ(706 , message.GetExtension(unittest::packed_sint64_extension_lite , 1));
+ EXPECT_EQ(707 , message.GetExtension(unittest::packed_fixed32_extension_lite , 1));
+ EXPECT_EQ(708 , message.GetExtension(unittest::packed_fixed64_extension_lite , 1));
+ EXPECT_EQ(709 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1));
+ EXPECT_EQ(710 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1));
+ EXPECT_EQ(711 , message.GetExtension(unittest::packed_float_extension_lite , 1));
+ EXPECT_EQ(712 , message.GetExtension(unittest::packed_double_extension_lite , 1));
+ EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension_lite , 1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAZ,
+ message.GetExtension(unittest::packed_enum_extension_lite, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsClear(
+ const unittest::TestPackedExtensionsLite& message) {
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension_lite ));
+ EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension_lite ));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsModified(
+ const unittest::TestPackedExtensionsLite& message) {
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite ));
+ ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite ));
+ EXPECT_EQ(601 , message.GetExtension(unittest::packed_int32_extension_lite , 0));
+ EXPECT_EQ(602 , message.GetExtension(unittest::packed_int64_extension_lite , 0));
+ EXPECT_EQ(603 , message.GetExtension(unittest::packed_uint32_extension_lite , 0));
+ EXPECT_EQ(604 , message.GetExtension(unittest::packed_uint64_extension_lite , 0));
+ EXPECT_EQ(605 , message.GetExtension(unittest::packed_sint32_extension_lite , 0));
+ EXPECT_EQ(606 , message.GetExtension(unittest::packed_sint64_extension_lite , 0));
+ EXPECT_EQ(607 , message.GetExtension(unittest::packed_fixed32_extension_lite , 0));
+ EXPECT_EQ(608 , message.GetExtension(unittest::packed_fixed64_extension_lite , 0));
+ EXPECT_EQ(609 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0));
+ EXPECT_EQ(610 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0));
+ EXPECT_EQ(611 , message.GetExtension(unittest::packed_float_extension_lite , 0));
+ EXPECT_EQ(612 , message.GetExtension(unittest::packed_double_extension_lite , 0));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 0));
+ EXPECT_EQ(unittest::FOREIGN_LITE_BAR,
+ message.GetExtension(unittest::packed_enum_extension_lite, 0));
+
+ // Actually verify the second (modified) elements now.
+ EXPECT_EQ(801 , message.GetExtension(unittest::packed_int32_extension_lite , 1));
+ EXPECT_EQ(802 , message.GetExtension(unittest::packed_int64_extension_lite , 1));
+ EXPECT_EQ(803 , message.GetExtension(unittest::packed_uint32_extension_lite , 1));
+ EXPECT_EQ(804 , message.GetExtension(unittest::packed_uint64_extension_lite , 1));
+ EXPECT_EQ(805 , message.GetExtension(unittest::packed_sint32_extension_lite , 1));
+ EXPECT_EQ(806 , message.GetExtension(unittest::packed_sint64_extension_lite , 1));
+ EXPECT_EQ(807 , message.GetExtension(unittest::packed_fixed32_extension_lite , 1));
+ EXPECT_EQ(808 , message.GetExtension(unittest::packed_fixed64_extension_lite , 1));
+ EXPECT_EQ(809 , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1));
+ EXPECT_EQ(810 , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1));
+ EXPECT_EQ(811 , message.GetExtension(unittest::packed_float_extension_lite , 1));
+ EXPECT_EQ(812 , message.GetExtension(unittest::packed_double_extension_lite , 1));
+ EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite , 1));
+ EXPECT_EQ(unittest::FOREIGN_LITE_FOO,
+ message.GetExtension(unittest::packed_enum_extension_lite, 1));
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/test_util_lite.h b/src/third_party/protobuf/src/google/protobuf/test_util_lite.h
new file mode 100644
index 0000000..ca35aaa
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/test_util_lite.h
@@ -0,0 +1,101 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
+#define GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
+
+#include <google/protobuf/unittest_lite.pb.h>
+
+namespace google {
+namespace protobuf {
+
+namespace unittest = protobuf_unittest;
+namespace unittest_import = protobuf_unittest_import;
+
+class TestUtilLite {
+ public:
+ // Set every field in the message to a unique value.
+ static void SetAllFields(unittest::TestAllTypesLite* message);
+ static void SetAllExtensions(unittest::TestAllExtensionsLite* message);
+ static void SetPackedFields(unittest::TestPackedTypesLite* message);
+ static void SetPackedExtensions(unittest::TestPackedExtensionsLite* message);
+
+ // Use the repeated versions of the set_*() accessors to modify all the
+ // repeated fields of the messsage (which should already have been
+ // initialized with Set*Fields()). Set*Fields() itself only tests
+ // the add_*() accessors.
+ static void ModifyRepeatedFields(unittest::TestAllTypesLite* message);
+ static void ModifyRepeatedExtensions(
+ unittest::TestAllExtensionsLite* message);
+ static void ModifyPackedFields(unittest::TestPackedTypesLite* message);
+ static void ModifyPackedExtensions(
+ unittest::TestPackedExtensionsLite* message);
+
+ // Check that all fields have the values that they should have after
+ // Set*Fields() is called.
+ static void ExpectAllFieldsSet(const unittest::TestAllTypesLite& message);
+ static void ExpectAllExtensionsSet(
+ const unittest::TestAllExtensionsLite& message);
+ static void ExpectPackedFieldsSet(
+ const unittest::TestPackedTypesLite& message);
+ static void ExpectPackedExtensionsSet(
+ const unittest::TestPackedExtensionsLite& message);
+
+ // Expect that the message is modified as would be expected from
+ // Modify*Fields().
+ static void ExpectRepeatedFieldsModified(
+ const unittest::TestAllTypesLite& message);
+ static void ExpectRepeatedExtensionsModified(
+ const unittest::TestAllExtensionsLite& message);
+ static void ExpectPackedFieldsModified(
+ const unittest::TestPackedTypesLite& message);
+ static void ExpectPackedExtensionsModified(
+ const unittest::TestPackedExtensionsLite& message);
+
+ // Check that all fields have their default values.
+ static void ExpectClear(const unittest::TestAllTypesLite& message);
+ static void ExpectExtensionsClear(
+ const unittest::TestAllExtensionsLite& message);
+ static void ExpectPackedClear(const unittest::TestPackedTypesLite& message);
+ static void ExpectPackedExtensionsClear(
+ const unittest::TestPackedExtensionsLite& message);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtilLite);
+};
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/testdata/golden_message b/src/third_party/protobuf/src/google/protobuf/testdata/golden_message
new file mode 100644
index 0000000..94898e4
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testdata/golden_message
Binary files differ
diff --git a/src/third_party/protobuf/src/google/protobuf/testdata/golden_packed_fields_message b/src/third_party/protobuf/src/google/protobuf/testdata/golden_packed_fields_message
new file mode 100644
index 0000000..ee28d38
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testdata/golden_packed_fields_message
Binary files differ
diff --git a/src/third_party/protobuf/src/google/protobuf/testdata/text_format_unittest_data.txt b/src/third_party/protobuf/src/google/protobuf/testdata/text_format_unittest_data.txt
new file mode 100644
index 0000000..feea8f7
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testdata/text_format_unittest_data.txt
@@ -0,0 +1,116 @@
+optional_int32: 101
+optional_int64: 102
+optional_uint32: 103
+optional_uint64: 104
+optional_sint32: 105
+optional_sint64: 106
+optional_fixed32: 107
+optional_fixed64: 108
+optional_sfixed32: 109
+optional_sfixed64: 110
+optional_float: 111
+optional_double: 112
+optional_bool: true
+optional_string: "115"
+optional_bytes: "116"
+OptionalGroup {
+ a: 117
+}
+optional_nested_message {
+ bb: 118
+}
+optional_foreign_message {
+ c: 119
+}
+optional_import_message {
+ d: 120
+}
+optional_nested_enum: BAZ
+optional_foreign_enum: FOREIGN_BAZ
+optional_import_enum: IMPORT_BAZ
+optional_string_piece: "124"
+optional_cord: "125"
+repeated_int32: 201
+repeated_int32: 301
+repeated_int64: 202
+repeated_int64: 302
+repeated_uint32: 203
+repeated_uint32: 303
+repeated_uint64: 204
+repeated_uint64: 304
+repeated_sint32: 205
+repeated_sint32: 305
+repeated_sint64: 206
+repeated_sint64: 306
+repeated_fixed32: 207
+repeated_fixed32: 307
+repeated_fixed64: 208
+repeated_fixed64: 308
+repeated_sfixed32: 209
+repeated_sfixed32: 309
+repeated_sfixed64: 210
+repeated_sfixed64: 310
+repeated_float: 211
+repeated_float: 311
+repeated_double: 212
+repeated_double: 312
+repeated_bool: true
+repeated_bool: false
+repeated_string: "215"
+repeated_string: "315"
+repeated_bytes: "216"
+repeated_bytes: "316"
+RepeatedGroup {
+ a: 217
+}
+RepeatedGroup {
+ a: 317
+}
+repeated_nested_message {
+ bb: 218
+}
+repeated_nested_message {
+ bb: 318
+}
+repeated_foreign_message {
+ c: 219
+}
+repeated_foreign_message {
+ c: 319
+}
+repeated_import_message {
+ d: 220
+}
+repeated_import_message {
+ d: 320
+}
+repeated_nested_enum: BAR
+repeated_nested_enum: BAZ
+repeated_foreign_enum: FOREIGN_BAR
+repeated_foreign_enum: FOREIGN_BAZ
+repeated_import_enum: IMPORT_BAR
+repeated_import_enum: IMPORT_BAZ
+repeated_string_piece: "224"
+repeated_string_piece: "324"
+repeated_cord: "225"
+repeated_cord: "325"
+default_int32: 401
+default_int64: 402
+default_uint32: 403
+default_uint64: 404
+default_sint32: 405
+default_sint64: 406
+default_fixed32: 407
+default_fixed64: 408
+default_sfixed32: 409
+default_sfixed64: 410
+default_float: 411
+default_double: 412
+default_bool: false
+default_string: "415"
+default_bytes: "416"
+default_nested_enum: FOO
+default_foreign_enum: FOREIGN_FOO
+default_import_enum: IMPORT_FOO
+default_string_piece: "424"
+default_cord: "425"
diff --git a/src/third_party/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt b/src/third_party/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
new file mode 100644
index 0000000..057beae
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
@@ -0,0 +1,116 @@
+[protobuf_unittest.optional_int32_extension]: 101
+[protobuf_unittest.optional_int64_extension]: 102
+[protobuf_unittest.optional_uint32_extension]: 103
+[protobuf_unittest.optional_uint64_extension]: 104
+[protobuf_unittest.optional_sint32_extension]: 105
+[protobuf_unittest.optional_sint64_extension]: 106
+[protobuf_unittest.optional_fixed32_extension]: 107
+[protobuf_unittest.optional_fixed64_extension]: 108
+[protobuf_unittest.optional_sfixed32_extension]: 109
+[protobuf_unittest.optional_sfixed64_extension]: 110
+[protobuf_unittest.optional_float_extension]: 111
+[protobuf_unittest.optional_double_extension]: 112
+[protobuf_unittest.optional_bool_extension]: true
+[protobuf_unittest.optional_string_extension]: "115"
+[protobuf_unittest.optional_bytes_extension]: "116"
+[protobuf_unittest.optionalgroup_extension] {
+ a: 117
+}
+[protobuf_unittest.optional_nested_message_extension] {
+ bb: 118
+}
+[protobuf_unittest.optional_foreign_message_extension] {
+ c: 119
+}
+[protobuf_unittest.optional_import_message_extension] {
+ d: 120
+}
+[protobuf_unittest.optional_nested_enum_extension]: BAZ
+[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.optional_string_piece_extension]: "124"
+[protobuf_unittest.optional_cord_extension]: "125"
+[protobuf_unittest.repeated_int32_extension]: 201
+[protobuf_unittest.repeated_int32_extension]: 301
+[protobuf_unittest.repeated_int64_extension]: 202
+[protobuf_unittest.repeated_int64_extension]: 302
+[protobuf_unittest.repeated_uint32_extension]: 203
+[protobuf_unittest.repeated_uint32_extension]: 303
+[protobuf_unittest.repeated_uint64_extension]: 204
+[protobuf_unittest.repeated_uint64_extension]: 304
+[protobuf_unittest.repeated_sint32_extension]: 205
+[protobuf_unittest.repeated_sint32_extension]: 305
+[protobuf_unittest.repeated_sint64_extension]: 206
+[protobuf_unittest.repeated_sint64_extension]: 306
+[protobuf_unittest.repeated_fixed32_extension]: 207
+[protobuf_unittest.repeated_fixed32_extension]: 307
+[protobuf_unittest.repeated_fixed64_extension]: 208
+[protobuf_unittest.repeated_fixed64_extension]: 308
+[protobuf_unittest.repeated_sfixed32_extension]: 209
+[protobuf_unittest.repeated_sfixed32_extension]: 309
+[protobuf_unittest.repeated_sfixed64_extension]: 210
+[protobuf_unittest.repeated_sfixed64_extension]: 310
+[protobuf_unittest.repeated_float_extension]: 211
+[protobuf_unittest.repeated_float_extension]: 311
+[protobuf_unittest.repeated_double_extension]: 212
+[protobuf_unittest.repeated_double_extension]: 312
+[protobuf_unittest.repeated_bool_extension]: true
+[protobuf_unittest.repeated_bool_extension]: false
+[protobuf_unittest.repeated_string_extension]: "215"
+[protobuf_unittest.repeated_string_extension]: "315"
+[protobuf_unittest.repeated_bytes_extension]: "216"
+[protobuf_unittest.repeated_bytes_extension]: "316"
+[protobuf_unittest.repeatedgroup_extension] {
+ a: 217
+}
+[protobuf_unittest.repeatedgroup_extension] {
+ a: 317
+}
+[protobuf_unittest.repeated_nested_message_extension] {
+ bb: 218
+}
+[protobuf_unittest.repeated_nested_message_extension] {
+ bb: 318
+}
+[protobuf_unittest.repeated_foreign_message_extension] {
+ c: 219
+}
+[protobuf_unittest.repeated_foreign_message_extension] {
+ c: 319
+}
+[protobuf_unittest.repeated_import_message_extension] {
+ d: 220
+}
+[protobuf_unittest.repeated_import_message_extension] {
+ d: 320
+}
+[protobuf_unittest.repeated_nested_enum_extension]: BAR
+[protobuf_unittest.repeated_nested_enum_extension]: BAZ
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR
+[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR
+[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ
+[protobuf_unittest.repeated_string_piece_extension]: "224"
+[protobuf_unittest.repeated_string_piece_extension]: "324"
+[protobuf_unittest.repeated_cord_extension]: "225"
+[protobuf_unittest.repeated_cord_extension]: "325"
+[protobuf_unittest.default_int32_extension]: 401
+[protobuf_unittest.default_int64_extension]: 402
+[protobuf_unittest.default_uint32_extension]: 403
+[protobuf_unittest.default_uint64_extension]: 404
+[protobuf_unittest.default_sint32_extension]: 405
+[protobuf_unittest.default_sint64_extension]: 406
+[protobuf_unittest.default_fixed32_extension]: 407
+[protobuf_unittest.default_fixed64_extension]: 408
+[protobuf_unittest.default_sfixed32_extension]: 409
+[protobuf_unittest.default_sfixed64_extension]: 410
+[protobuf_unittest.default_float_extension]: 411
+[protobuf_unittest.default_double_extension]: 412
+[protobuf_unittest.default_bool_extension]: false
+[protobuf_unittest.default_string_extension]: "415"
+[protobuf_unittest.default_bytes_extension]: "416"
+[protobuf_unittest.default_nested_enum_extension]: FOO
+[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO
+[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO
+[protobuf_unittest.default_string_piece_extension]: "424"
+[protobuf_unittest.default_cord_extension]: "425"
diff --git a/src/third_party/protobuf/src/google/protobuf/testing/file.cc b/src/third_party/protobuf/src/google/protobuf/testing/file.cc
new file mode 100644
index 0000000..e224781
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testing/file.cc
@@ -0,0 +1,176 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/file/base/file.cc
+
+#include <google/protobuf/testing/file.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifdef _MSC_VER
+#define WIN32_LEAN_AND_MEAN // yeah, right
+#include <windows.h> // Find*File(). :(
+#include <io.h>
+#include <direct.h>
+#else
+#include <dirent.h>
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _WIN32
+#define mkdir(name, mode) mkdir(name)
+// Windows doesn't have symbolic links.
+#define lstat stat
+#ifndef F_OK
+#define F_OK 00 // not defined by MSVC for whatever reason
+#endif
+#endif
+
+bool File::Exists(const string& name) {
+ return access(name.c_str(), F_OK) == 0;
+}
+
+bool File::ReadFileToString(const string& name, string* output) {
+ char buffer[1024];
+ FILE* file = fopen(name.c_str(), "rb");
+ if (file == NULL) return false;
+
+ while (true) {
+ size_t n = fread(buffer, 1, sizeof(buffer), file);
+ if (n <= 0) break;
+ output->append(buffer, n);
+ }
+
+ int error = ferror(file);
+ if (fclose(file) != 0) return false;
+ return error == 0;
+}
+
+void File::ReadFileToStringOrDie(const string& name, string* output) {
+ GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name;
+}
+
+void File::WriteStringToFileOrDie(const string& contents, const string& name) {
+ FILE* file = fopen(name.c_str(), "wb");
+ GOOGLE_CHECK(file != NULL)
+ << "fopen(" << name << ", \"wb\"): " << strerror(errno);
+ GOOGLE_CHECK_EQ(fwrite(contents.data(), 1, contents.size(), file),
+ contents.size())
+ << "fwrite(" << name << "): " << strerror(errno);
+ GOOGLE_CHECK(fclose(file) == 0)
+ << "fclose(" << name << "): " << strerror(errno);
+}
+
+bool File::CreateDir(const string& name, int mode) {
+ return mkdir(name.c_str(), mode) == 0;
+}
+
+bool File::RecursivelyCreateDir(const string& path, int mode) {
+ if (CreateDir(path, mode)) return true;
+
+ if (Exists(path)) return false;
+
+ // Try creating the parent.
+ string::size_type slashpos = path.find_last_of('/');
+ if (slashpos == string::npos) {
+ // No parent given.
+ return false;
+ }
+
+ return RecursivelyCreateDir(path.substr(0, slashpos), mode) &&
+ CreateDir(path, mode);
+}
+
+void File::DeleteRecursively(const string& name,
+ void* dummy1, void* dummy2) {
+ // We don't care too much about error checking here since this is only used
+ // in tests to delete temporary directories that are under /tmp anyway.
+
+#ifdef _MSC_VER
+ // This interface is so weird.
+ WIN32_FIND_DATA find_data;
+ HANDLE find_handle = FindFirstFile((name + "/*").c_str(), &find_data);
+ if (find_handle == INVALID_HANDLE_VALUE) {
+ // Just delete it, whatever it is.
+ DeleteFile(name.c_str());
+ RemoveDirectory(name.c_str());
+ return;
+ }
+
+ do {
+ string entry_name = find_data.cFileName;
+ if (entry_name != "." && entry_name != "..") {
+ string path = name + "/" + entry_name;
+ if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ DeleteRecursively(path, NULL, NULL);
+ RemoveDirectory(path.c_str());
+ } else {
+ DeleteFile(path.c_str());
+ }
+ }
+ } while(FindNextFile(find_handle, &find_data));
+ FindClose(find_handle);
+
+ RemoveDirectory(name.c_str());
+#else
+ // Use opendir()! Yay!
+ // lstat = Don't follow symbolic links.
+ struct stat stats;
+ if (lstat(name.c_str(), &stats) != 0) return;
+
+ if (S_ISDIR(stats.st_mode)) {
+ DIR* dir = opendir(name.c_str());
+ if (dir != NULL) {
+ while (true) {
+ struct dirent* entry = readdir(dir);
+ if (entry == NULL) break;
+ string entry_name = entry->d_name;
+ if (entry_name != "." && entry_name != "..") {
+ DeleteRecursively(name + "/" + entry_name, NULL, NULL);
+ }
+ }
+ }
+
+ closedir(dir);
+ rmdir(name.c_str());
+
+ } else if (S_ISREG(stats.st_mode)) {
+ remove(name.c_str());
+ }
+#endif
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/testing/file.h b/src/third_party/protobuf/src/google/protobuf/testing/file.h
new file mode 100644
index 0000000..a6b1c76
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testing/file.h
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/file/base/file.h
+
+#ifndef GOOGLE_PROTOBUF_TESTING_FILE_H__
+#define GOOGLE_PROTOBUF_TESTING_FILE_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+const int DEFAULT_FILE_MODE = 0777;
+
+// Protocol buffer code only uses a couple static methods of File, and only
+// in tests.
+class File {
+ public:
+ // Check if the file exists.
+ static bool Exists(const string& name);
+
+ // Read an entire file to a string. Return true if successful, false
+ // otherwise.
+ static bool ReadFileToString(const string& name, string* output);
+
+ // Same as above, but crash on failure.
+ static void ReadFileToStringOrDie(const string& name, string* output);
+
+ // Create a file and write a string to it.
+ static void WriteStringToFileOrDie(const string& contents,
+ const string& name);
+
+ // Create a directory.
+ static bool CreateDir(const string& name, int mode);
+
+ // Create a directory and all parent directories if necessary.
+ static bool RecursivelyCreateDir(const string& path, int mode);
+
+ // If "name" is a file, we delete it. If it is a directory, we
+ // call DeleteRecursively() for each file or directory (other than
+ // dot and double-dot) within it, and then delete the directory itself.
+ // The "dummy" parameters have a meaning in the original version of this
+ // method but they are not used anywhere in protocol buffers.
+ static void DeleteRecursively(const string& name,
+ void* dummy1, void* dummy2);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(File);
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_TESTING_FILE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/testing/googletest.cc b/src/third_party/protobuf/src/google/protobuf/testing/googletest.cc
new file mode 100644
index 0000000..cd094d0
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testing/googletest.cc
@@ -0,0 +1,254 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/testing/base/public/googletest.cc
+
+#include <google/protobuf/testing/googletest.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+#include <io.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <fcntl.h>
+#include <iostream>
+#include <fstream>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _WIN32
+#define mkdir(name, mode) mkdir(name)
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
+#endif
+#endif
+
+string TestSourceDir() {
+#ifdef _MSC_VER
+ // Look for the "src" directory.
+ string prefix = ".";
+
+ while (!File::Exists(prefix + "/src/google/protobuf")) {
+ if (!File::Exists(prefix)) {
+ GOOGLE_LOG(FATAL)
+ << "Could not find protobuf source code. Please run tests from "
+ "somewhere within the protobuf source package.";
+ }
+ prefix += "/..";
+ }
+ return prefix + "/src";
+#else
+ // automake sets the "srcdir" environment variable.
+ char* result = getenv("srcdir");
+ if (result == NULL) {
+ // Otherwise, the test must be run from the source directory.
+ return ".";
+ } else {
+ return result;
+ }
+#endif
+}
+
+namespace {
+
+string GetTemporaryDirectoryName() {
+ // tmpnam() is generally not considered safe but we're only using it for
+ // testing. We cannot use tmpfile() or mkstemp() since we're creating a
+ // directory.
+ char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0
+ string result = tmpnam(b);
+#ifdef _WIN32
+ // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed
+ // to be used in the current working directory. WTF?
+ if (HasPrefixString(result, "\\")) {
+ result.erase(0, 1);
+ }
+#endif // _WIN32
+ return result;
+}
+
+// Creates a temporary directory on demand and deletes it when the process
+// quits.
+class TempDirDeleter {
+ public:
+ TempDirDeleter() {}
+ ~TempDirDeleter() {
+ if (!name_.empty()) {
+ File::DeleteRecursively(name_, NULL, NULL);
+ }
+ }
+
+ string GetTempDir() {
+ if (name_.empty()) {
+ name_ = GetTemporaryDirectoryName();
+ GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno);
+
+ // Stick a file in the directory that tells people what this is, in case
+ // we abort and don't get a chance to delete it.
+ File::WriteStringToFileOrDie("", name_ + "/TEMP_DIR_FOR_PROTOBUF_TESTS");
+ }
+ return name_;
+ }
+
+ private:
+ string name_;
+};
+
+TempDirDeleter temp_dir_deleter_;
+
+} // namespace
+
+string TestTempDir() {
+ return temp_dir_deleter_.GetTempDir();
+}
+
+// TODO(kenton): Share duplicated code below. Too busy/lazy for now.
+
+static string stdout_capture_filename_;
+static string stderr_capture_filename_;
+static int original_stdout_ = -1;
+static int original_stderr_ = -1;
+
+void CaptureTestStdout() {
+ GOOGLE_CHECK_EQ(original_stdout_, -1) << "Already capturing.";
+
+ stdout_capture_filename_ = TestTempDir() + "/captured_stdout";
+
+ int fd = open(stdout_capture_filename_.c_str(),
+ O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
+ GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno);
+
+ original_stdout_ = dup(1);
+ close(1);
+ dup2(fd, 1);
+ close(fd);
+}
+
+void CaptureTestStderr() {
+ GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing.";
+
+ stderr_capture_filename_ = TestTempDir() + "/captured_stderr";
+
+ int fd = open(stderr_capture_filename_.c_str(),
+ O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
+ GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno);
+
+ original_stderr_ = dup(2);
+ close(2);
+ dup2(fd, 2);
+ close(fd);
+}
+
+string GetCapturedTestStdout() {
+ GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing.";
+
+ close(1);
+ dup2(original_stdout_, 1);
+ original_stdout_ = -1;
+
+ string result;
+ File::ReadFileToStringOrDie(stdout_capture_filename_, &result);
+
+ remove(stdout_capture_filename_.c_str());
+
+ return result;
+}
+
+string GetCapturedTestStderr() {
+ GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing.";
+
+ close(2);
+ dup2(original_stderr_, 2);
+ original_stderr_ = -1;
+
+ string result;
+ File::ReadFileToStringOrDie(stderr_capture_filename_, &result);
+
+ remove(stderr_capture_filename_.c_str());
+
+ return result;
+}
+
+ScopedMemoryLog* ScopedMemoryLog::active_log_ = NULL;
+
+ScopedMemoryLog::ScopedMemoryLog() {
+ GOOGLE_CHECK(active_log_ == NULL);
+ active_log_ = this;
+ old_handler_ = SetLogHandler(&HandleLog);
+}
+
+ScopedMemoryLog::~ScopedMemoryLog() {
+ SetLogHandler(old_handler_);
+ active_log_ = NULL;
+}
+
+const vector<string>& ScopedMemoryLog::GetMessages(LogLevel dummy) const {
+ GOOGLE_CHECK_EQ(dummy, ERROR);
+ return messages_;
+}
+
+void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename,
+ int line, const string& message) {
+ GOOGLE_CHECK(active_log_ != NULL);
+ if (level == ERROR) {
+ active_log_->messages_.push_back(message);
+ }
+}
+
+namespace {
+
+// Force shutdown at process exit so that we can test for memory leaks. To
+// actually check for leaks, I suggest using the heap checker included with
+// google-perftools. Set it to "draconian" mode to ensure that every last
+// call to malloc() has a corresponding free().
+struct ForceShutdown {
+ ~ForceShutdown() {
+ ShutdownProtobufLibrary();
+ }
+} force_shutdown;
+
+} // namespace
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/testing/googletest.h b/src/third_party/protobuf/src/google/protobuf/testing/googletest.h
new file mode 100644
index 0000000..71444c9
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testing/googletest.h
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/testing/base/public/googletest.h
+
+#ifndef GOOGLE_PROTOBUF_GOOGLETEST_H__
+#define GOOGLE_PROTOBUF_GOOGLETEST_H__
+
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// When running unittests, get the directory containing the source code.
+string TestSourceDir();
+
+// When running unittests, get a directory where temporary files may be
+// placed.
+string TestTempDir();
+
+// Capture all text written to stdout or stderr.
+void CaptureTestStdout();
+void CaptureTestStderr();
+
+// Stop capturing stdout or stderr and return the text captured.
+string GetCapturedTestStdout();
+string GetCapturedTestStderr();
+
+// For use with ScopedMemoryLog::GetMessages(). Inside Google the LogLevel
+// constants don't have the LOGLEVEL_ prefix, so the code that used
+// ScopedMemoryLog refers to LOGLEVEL_ERROR as just ERROR.
+#undef ERROR // defend against promiscuous windows.h
+static const LogLevel ERROR = LOGLEVEL_ERROR;
+
+// Receives copies of all LOG(ERROR) messages while in scope. Sample usage:
+// {
+// ScopedMemoryLog log; // constructor registers object as a log sink
+// SomeRoutineThatMayLogMessages();
+// const vector<string>& warnings = log.GetMessages(ERROR);
+// } // destructor unregisters object as a log sink
+// This is a dummy implementation which covers only what is used by protocol
+// buffer unit tests.
+class ScopedMemoryLog {
+ public:
+ ScopedMemoryLog();
+ virtual ~ScopedMemoryLog();
+
+ // Fetches all messages logged. The internal version of this class
+ // would only fetch messages at the given security level, but the protobuf
+ // open source version ignores the argument since we always pass ERROR
+ // anyway.
+ const vector<string>& GetMessages(LogLevel dummy) const;
+
+ private:
+ vector<string> messages_;
+ LogHandler* old_handler_;
+
+ static void HandleLog(LogLevel level, const char* filename, int line,
+ const string& message);
+
+ static ScopedMemoryLog* active_log_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedMemoryLog);
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_GOOGLETEST_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/testing/zcgunzip.cc b/src/third_party/protobuf/src/google/protobuf/testing/zcgunzip.cc
new file mode 100644
index 0000000..a619785
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testing/zcgunzip.cc
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Test program to verify that GzipInputStream is compatible with command line
+// gunzip or java.util.zip.GzipInputStream
+//
+// Reads gzip stream on standard input and writes decompressed data to standard
+// output.
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <google/protobuf/io/gzip_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+using google::protobuf::io::FileInputStream;
+using google::protobuf::io::GzipInputStream;
+
+int main(int argc, const char** argv) {
+ FileInputStream fin(STDIN_FILENO);
+ GzipInputStream in(&fin);
+
+ while (true) {
+ const void* inptr;
+ int inlen;
+ bool ok;
+ ok = in.Next(&inptr, &inlen);
+ if (!ok) {
+ break;
+ }
+ if (inlen > 0) {
+ int err = write(STDOUT_FILENO, inptr, inlen);
+ assert(err == inlen);
+ }
+ }
+
+ return 0;
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/testing/zcgzip.cc b/src/third_party/protobuf/src/google/protobuf/testing/zcgzip.cc
new file mode 100644
index 0000000..9133275
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/testing/zcgzip.cc
@@ -0,0 +1,79 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Test program to verify that GzipOutputStream is compatible with command line
+// gzip or java.util.zip.GzipOutputStream
+//
+// Reads data on standard input and writes compressed gzip stream to standard
+// output.
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <google/protobuf/io/gzip_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+using google::protobuf::io::FileOutputStream;
+using google::protobuf::io::GzipOutputStream;
+
+int main(int argc, const char** argv) {
+ FileOutputStream fout(STDOUT_FILENO);
+ GzipOutputStream out(&fout);
+ int readlen;
+
+ while (true) {
+ void* outptr;
+ int outlen;
+ bool ok;
+ do {
+ ok = out.Next(&outptr, &outlen);
+ if (!ok) {
+ break;
+ }
+ } while (outlen <= 0);
+ readlen = read(STDIN_FILENO, outptr, outlen);
+ if (readlen <= 0) {
+ out.BackUp(outlen);
+ break;
+ }
+ if (readlen < outlen) {
+ out.BackUp(outlen - readlen);
+ }
+ }
+
+ return 0;
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/text_format.cc b/src/third_party/protobuf/src/google/protobuf/text_format.cc
new file mode 100644
index 0000000..1494ebd
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/text_format.cc
@@ -0,0 +1,1285 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jschorr@google.com (Joseph Schorr)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+#include <stack>
+#include <limits>
+#include <vector>
+
+#include <google/protobuf/text_format.h>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+
+string Message::DebugString() const {
+ string debug_string;
+
+ TextFormat::PrintToString(*this, &debug_string);
+
+ return debug_string;
+}
+
+string Message::ShortDebugString() const {
+ string debug_string;
+
+ TextFormat::Printer printer;
+ printer.SetSingleLineMode(true);
+
+ printer.PrintToString(*this, &debug_string);
+ // Single line mode currently might have an extra space at the end.
+ if (debug_string.size() > 0 &&
+ debug_string[debug_string.size() - 1] == ' ') {
+ debug_string.resize(debug_string.size() - 1);
+ }
+
+ return debug_string;
+}
+
+string Message::Utf8DebugString() const {
+ string debug_string;
+
+ TextFormat::Printer printer;
+ printer.SetUseUtf8StringEscaping(true);
+
+ printer.PrintToString(*this, &debug_string);
+
+ return debug_string;
+}
+
+void Message::PrintDebugString() const {
+ printf("%s", DebugString().c_str());
+}
+
+
+// ===========================================================================
+// Internal class for parsing an ASCII representation of a Protocol Message.
+// This class makes use of the Protocol Message compiler's tokenizer found
+// in //google/protobuf/io/tokenizer.h. Note that class's Parse
+// method is *not* thread-safe and should only be used in a single thread at
+// a time.
+
+// Makes code slightly more readable. The meaning of "DO(foo)" is
+// "Execute foo and fail if it fails.", where failure is indicated by
+// returning false. Borrowed from parser.cc (Thanks Kenton!).
+#define DO(STATEMENT) if (STATEMENT) {} else return false
+
+class TextFormat::Parser::ParserImpl {
+ public:
+
+ // Determines if repeated values for a non-repeated field are
+ // permitted, e.g., the string "foo: 1 foo: 2" for a
+ // required/optional field named "foo".
+ enum SingularOverwritePolicy {
+ ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained
+ FORBID_SINGULAR_OVERWRITES = 1, // an error is issued
+ };
+
+ ParserImpl(const Descriptor* root_message_type,
+ io::ZeroCopyInputStream* input_stream,
+ io::ErrorCollector* error_collector,
+ TextFormat::Finder* finder,
+ SingularOverwritePolicy singular_overwrite_policy)
+ : error_collector_(error_collector),
+ finder_(finder),
+ tokenizer_error_collector_(this),
+ tokenizer_(input_stream, &tokenizer_error_collector_),
+ root_message_type_(root_message_type),
+ singular_overwrite_policy_(singular_overwrite_policy),
+ had_errors_(false) {
+ // For backwards-compatibility with proto1, we need to allow the 'f' suffix
+ // for floats.
+ tokenizer_.set_allow_f_after_float(true);
+
+ // '#' starts a comment.
+ tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
+
+ // Consume the starting token.
+ tokenizer_.Next();
+ }
+ ~ParserImpl() { }
+
+ // Parses the ASCII representation specified in input and saves the
+ // information into the output pointer (a Message). Returns
+ // false if an error occurs (an error will also be logged to
+ // GOOGLE_LOG(ERROR)).
+ bool Parse(Message* output) {
+ // Consume fields until we cannot do so anymore.
+ while(true) {
+ if (LookingAtType(io::Tokenizer::TYPE_END)) {
+ return !had_errors_;
+ }
+
+ DO(ConsumeField(output));
+ }
+ }
+
+ bool ParseField(const FieldDescriptor* field, Message* output) {
+ bool suc;
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ suc = ConsumeFieldMessage(output, output->GetReflection(), field);
+ } else {
+ suc = ConsumeFieldValue(output, output->GetReflection(), field);
+ }
+ return suc && LookingAtType(io::Tokenizer::TYPE_END);
+ }
+
+ void ReportError(int line, int col, const string& message) {
+ had_errors_ = true;
+ if (error_collector_ == NULL) {
+ if (line >= 0) {
+ GOOGLE_LOG(ERROR) << "Error parsing text-format "
+ << root_message_type_->full_name()
+ << ": " << (line + 1) << ":"
+ << (col + 1) << ": " << message;
+ } else {
+ GOOGLE_LOG(ERROR) << "Error parsing text-format "
+ << root_message_type_->full_name()
+ << ": " << message;
+ }
+ } else {
+ error_collector_->AddError(line, col, message);
+ }
+ }
+
+ void ReportWarning(int line, int col, const string& message) {
+ if (error_collector_ == NULL) {
+ if (line >= 0) {
+ GOOGLE_LOG(WARNING) << "Warning parsing text-format "
+ << root_message_type_->full_name()
+ << ": " << (line + 1) << ":"
+ << (col + 1) << ": " << message;
+ } else {
+ GOOGLE_LOG(WARNING) << "Warning parsing text-format "
+ << root_message_type_->full_name()
+ << ": " << message;
+ }
+ } else {
+ error_collector_->AddWarning(line, col, message);
+ }
+ }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
+
+ // Reports an error with the given message with information indicating
+ // the position (as derived from the current token).
+ void ReportError(const string& message) {
+ ReportError(tokenizer_.current().line, tokenizer_.current().column,
+ message);
+ }
+
+ // Reports a warning with the given message with information indicating
+ // the position (as derived from the current token).
+ void ReportWarning(const string& message) {
+ ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
+ message);
+ }
+
+ // Consumes the specified message with the given starting delimeter.
+ // This method checks to see that the end delimeter at the conclusion of
+ // the consumption matches the starting delimeter passed in here.
+ bool ConsumeMessage(Message* message, const string delimeter) {
+ while (!LookingAt(">") && !LookingAt("}")) {
+ DO(ConsumeField(message));
+ }
+
+ // Confirm that we have a valid ending delimeter.
+ DO(Consume(delimeter));
+
+ return true;
+ }
+
+ // Consumes the current field (as returned by the tokenizer) on the
+ // passed in message.
+ bool ConsumeField(Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ const Descriptor* descriptor = message->GetDescriptor();
+
+ string field_name;
+
+ const FieldDescriptor* field = NULL;
+
+ if (TryConsume("[")) {
+ // Extension.
+ DO(ConsumeIdentifier(&field_name));
+ while (TryConsume(".")) {
+ string part;
+ DO(ConsumeIdentifier(&part));
+ field_name += ".";
+ field_name += part;
+ }
+ DO(Consume("]"));
+
+ field = (finder_ != NULL
+ ? finder_->FindExtension(message, field_name)
+ : reflection->FindKnownExtensionByName(field_name));
+
+ if (field == NULL) {
+ ReportError("Extension \"" + field_name + "\" is not defined or "
+ "is not an extension of \"" +
+ descriptor->full_name() + "\".");
+ return false;
+ }
+ } else {
+ DO(ConsumeIdentifier(&field_name));
+
+ field = descriptor->FindFieldByName(field_name);
+ // Group names are expected to be capitalized as they appear in the
+ // .proto file, which actually matches their type names, not their field
+ // names.
+ if (field == NULL) {
+ string lower_field_name = field_name;
+ LowerString(&lower_field_name);
+ field = descriptor->FindFieldByName(lower_field_name);
+ // If the case-insensitive match worked but the field is NOT a group,
+ if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
+ field = NULL;
+ }
+ }
+ // Again, special-case group names as described above.
+ if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
+ && field->message_type()->name() != field_name) {
+ field = NULL;
+ }
+
+ if (field == NULL) {
+ ReportError("Message type \"" + descriptor->full_name() +
+ "\" has no field named \"" + field_name + "\".");
+ return false;
+ }
+ }
+
+ // Fail if the field is not repeated and it has already been specified.
+ if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) &&
+ !field->is_repeated() && reflection->HasField(*message, field)) {
+ ReportError("Non-repeated field \"" + field_name +
+ "\" is specified multiple times.");
+ return false;
+ }
+
+ // Perform special handling for embedded message types.
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // ':' is optional here.
+ TryConsume(":");
+ DO(ConsumeFieldMessage(message, reflection, field));
+ } else {
+ DO(Consume(":"));
+ if (field->is_repeated() && TryConsume("[")) {
+ // Short repeated format, e.g. "foo: [1, 2, 3]"
+ while (true) {
+ DO(ConsumeFieldValue(message, reflection, field));
+ if (TryConsume("]")) {
+ break;
+ }
+ DO(Consume(","));
+ }
+ } else {
+ DO(ConsumeFieldValue(message, reflection, field));
+ }
+ }
+
+ // For historical reasons, fields may optionally be separated by commas or
+ // semicolons.
+ TryConsume(";") || TryConsume(",");
+
+ if (field->options().deprecated()) {
+ ReportWarning("text format contains deprecated field \""
+ + field_name + "\"");
+ }
+
+ return true;
+ }
+
+ bool ConsumeFieldMessage(Message* message,
+ const Reflection* reflection,
+ const FieldDescriptor* field) {
+ string delimeter;
+ if (TryConsume("<")) {
+ delimeter = ">";
+ } else {
+ DO(Consume("{"));
+ delimeter = "}";
+ }
+
+ if (field->is_repeated()) {
+ DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter));
+ } else {
+ DO(ConsumeMessage(reflection->MutableMessage(message, field),
+ delimeter));
+ }
+ return true;
+ }
+
+ bool ConsumeFieldValue(Message* message,
+ const Reflection* reflection,
+ const FieldDescriptor* field) {
+
+// Define an easy to use macro for setting fields. This macro checks
+// to see if the field is repeated (in which case we need to use the Add
+// methods or not (in which case we need to use the Set methods).
+#define SET_FIELD(CPPTYPE, VALUE) \
+ if (field->is_repeated()) { \
+ reflection->Add##CPPTYPE(message, field, VALUE); \
+ } else { \
+ reflection->Set##CPPTYPE(message, field, VALUE); \
+ } \
+
+ switch(field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32: {
+ int64 value;
+ DO(ConsumeSignedInteger(&value, kint32max));
+ SET_FIELD(Int32, static_cast<int32>(value));
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_UINT32: {
+ uint64 value;
+ DO(ConsumeUnsignedInteger(&value, kuint32max));
+ SET_FIELD(UInt32, static_cast<uint32>(value));
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_INT64: {
+ int64 value;
+ DO(ConsumeSignedInteger(&value, kint64max));
+ SET_FIELD(Int64, value);
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_UINT64: {
+ uint64 value;
+ DO(ConsumeUnsignedInteger(&value, kuint64max));
+ SET_FIELD(UInt64, value);
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_FLOAT: {
+ double value;
+ DO(ConsumeDouble(&value));
+ SET_FIELD(Float, static_cast<float>(value));
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value;
+ DO(ConsumeDouble(&value));
+ SET_FIELD(Double, value);
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_STRING: {
+ string value;
+ DO(ConsumeString(&value));
+ SET_FIELD(String, value);
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_BOOL: {
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ uint64 value;
+ DO(ConsumeUnsignedInteger(&value, 1));
+ SET_FIELD(Bool, value);
+ } else {
+ string value;
+ DO(ConsumeIdentifier(&value));
+ if (value == "true" || value == "t") {
+ SET_FIELD(Bool, true);
+ } else if (value == "false" || value == "f") {
+ SET_FIELD(Bool, false);
+ } else {
+ ReportError("Invalid value for boolean field \"" + field->name()
+ + "\". Value: \"" + value + "\".");
+ return false;
+ }
+ }
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_ENUM: {
+ string value;
+ const EnumDescriptor* enum_type = field->enum_type();
+ const EnumValueDescriptor* enum_value = NULL;
+
+ if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ DO(ConsumeIdentifier(&value));
+ // Find the enumeration value.
+ enum_value = enum_type->FindValueByName(value);
+
+ } else if (LookingAt("-") ||
+ LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ int64 int_value;
+ DO(ConsumeSignedInteger(&int_value, kint32max));
+ value = SimpleItoa(int_value); // for error reporting
+ enum_value = enum_type->FindValueByNumber(int_value);
+ } else {
+ ReportError("Expected integer or identifier.");
+ return false;
+ }
+
+ if (enum_value == NULL) {
+ ReportError("Unknown enumeration value of \"" + value + "\" for "
+ "field \"" + field->name() + "\".");
+ return false;
+ }
+
+ SET_FIELD(Enum, enum_value);
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ // We should never get here. Put here instead of a default
+ // so that if new types are added, we get a nice compiler warning.
+ GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
+ break;
+ }
+ }
+#undef SET_FIELD
+ return true;
+ }
+
+ // Returns true if the current token's text is equal to that specified.
+ bool LookingAt(const string& text) {
+ return tokenizer_.current().text == text;
+ }
+
+ // Returns true if the current token's type is equal to that specified.
+ bool LookingAtType(io::Tokenizer::TokenType token_type) {
+ return tokenizer_.current().type == token_type;
+ }
+
+ // Consumes an identifier and saves its value in the identifier parameter.
+ // Returns false if the token is not of type IDENTFIER.
+ bool ConsumeIdentifier(string* identifier) {
+ if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ ReportError("Expected identifier.");
+ return false;
+ }
+
+ *identifier = tokenizer_.current().text;
+
+ tokenizer_.Next();
+ return true;
+ }
+
+ // Consumes a string and saves its value in the text parameter.
+ // Returns false if the token is not of type STRING.
+ bool ConsumeString(string* text) {
+ if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ ReportError("Expected string.");
+ return false;
+ }
+
+ text->clear();
+ while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+ io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
+
+ tokenizer_.Next();
+ }
+
+ return true;
+ }
+
+ // Consumes a uint64 and saves its value in the value parameter.
+ // Returns false if the token is not of type INTEGER.
+ bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
+ if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ ReportError("Expected integer.");
+ return false;
+ }
+
+ if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
+ max_value, value)) {
+ ReportError("Integer out of range.");
+ return false;
+ }
+
+ tokenizer_.Next();
+ return true;
+ }
+
+ // Consumes an int64 and saves its value in the value parameter.
+ // Note that since the tokenizer does not support negative numbers,
+ // we actually may consume an additional token (for the minus sign) in this
+ // method. Returns false if the token is not an integer
+ // (signed or otherwise).
+ bool ConsumeSignedInteger(int64* value, uint64 max_value) {
+ bool negative = false;
+
+ if (TryConsume("-")) {
+ negative = true;
+ // Two's complement always allows one more negative integer than
+ // positive.
+ ++max_value;
+ }
+
+ uint64 unsigned_value;
+
+ DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
+
+ *value = static_cast<int64>(unsigned_value);
+
+ if (negative) {
+ *value = -*value;
+ }
+
+ return true;
+ }
+
+ // Consumes a double and saves its value in the value parameter.
+ // Note that since the tokenizer does not support negative numbers,
+ // we actually may consume an additional token (for the minus sign) in this
+ // method. Returns false if the token is not a double
+ // (signed or otherwise).
+ bool ConsumeDouble(double* value) {
+ bool negative = false;
+
+ if (TryConsume("-")) {
+ negative = true;
+ }
+
+ // A double can actually be an integer, according to the tokenizer.
+ // Therefore, we must check both cases here.
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+ // We have found an integer value for the double.
+ uint64 integer_value;
+ DO(ConsumeUnsignedInteger(&integer_value, kuint64max));
+
+ *value = static_cast<double>(integer_value);
+ } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
+ // We have found a float value for the double.
+ *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
+
+ // Mark the current token as consumed.
+ tokenizer_.Next();
+ } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+ string text = tokenizer_.current().text;
+ LowerString(&text);
+ if (text == "inf" || text == "infinity") {
+ *value = std::numeric_limits<double>::infinity();
+ tokenizer_.Next();
+ } else if (text == "nan") {
+ *value = std::numeric_limits<double>::quiet_NaN();
+ tokenizer_.Next();
+ } else {
+ ReportError("Expected double.");
+ return false;
+ }
+ } else {
+ ReportError("Expected double.");
+ return false;
+ }
+
+ if (negative) {
+ *value = -*value;
+ }
+
+ return true;
+ }
+
+ // Consumes a token and confirms that it matches that specified in the
+ // value parameter. Returns false if the token found does not match that
+ // which was specified.
+ bool Consume(const string& value) {
+ const string& current_value = tokenizer_.current().text;
+
+ if (current_value != value) {
+ ReportError("Expected \"" + value + "\", found \"" + current_value
+ + "\".");
+ return false;
+ }
+
+ tokenizer_.Next();
+
+ return true;
+ }
+
+ // Attempts to consume the supplied value. Returns false if a the
+ // token found does not match the value specified.
+ bool TryConsume(const string& value) {
+ if (tokenizer_.current().text == value) {
+ tokenizer_.Next();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // An internal instance of the Tokenizer's error collector, used to
+ // collect any base-level parse errors and feed them to the ParserImpl.
+ class ParserErrorCollector : public io::ErrorCollector {
+ public:
+ explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
+ parser_(parser) { }
+
+ virtual ~ParserErrorCollector() { };
+
+ virtual void AddError(int line, int column, const string& message) {
+ parser_->ReportError(line, column, message);
+ }
+
+ virtual void AddWarning(int line, int column, const string& message) {
+ parser_->ReportWarning(line, column, message);
+ }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
+ TextFormat::Parser::ParserImpl* parser_;
+ };
+
+ io::ErrorCollector* error_collector_;
+ TextFormat::Finder* finder_;
+ ParserErrorCollector tokenizer_error_collector_;
+ io::Tokenizer tokenizer_;
+ const Descriptor* root_message_type_;
+ SingularOverwritePolicy singular_overwrite_policy_;
+ bool had_errors_;
+};
+
+#undef DO
+
+// ===========================================================================
+// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
+// from the Printer found in //google/protobuf/io/printer.h
+class TextFormat::Printer::TextGenerator {
+ public:
+ explicit TextGenerator(io::ZeroCopyOutputStream* output,
+ int initial_indent_level)
+ : output_(output),
+ buffer_(NULL),
+ buffer_size_(0),
+ at_start_of_line_(true),
+ failed_(false),
+ indent_(""),
+ initial_indent_level_(initial_indent_level) {
+ indent_.resize(initial_indent_level_ * 2, ' ');
+ }
+
+ ~TextGenerator() {
+ // Only BackUp() if we're sure we've successfully called Next() at least
+ // once.
+ if (buffer_size_ > 0) {
+ output_->BackUp(buffer_size_);
+ }
+ }
+
+ // Indent text by two spaces. After calling Indent(), two spaces will be
+ // inserted at the beginning of each line of text. Indent() may be called
+ // multiple times to produce deeper indents.
+ void Indent() {
+ indent_ += " ";
+ }
+
+ // Reduces the current indent level by two spaces, or crashes if the indent
+ // level is zero.
+ void Outdent() {
+ if (indent_.empty() ||
+ indent_.size() < initial_indent_level_ * 2) {
+ GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
+ return;
+ }
+
+ indent_.resize(indent_.size() - 2);
+ }
+
+ // Print text to the output stream.
+ void Print(const string& str) {
+ Print(str.data(), str.size());
+ }
+
+ // Print text to the output stream.
+ void Print(const char* text) {
+ Print(text, strlen(text));
+ }
+
+ // Print text to the output stream.
+ void Print(const char* text, int size) {
+ int pos = 0; // The number of bytes we've written so far.
+
+ for (int i = 0; i < size; i++) {
+ if (text[i] == '\n') {
+ // Saw newline. If there is more text, we may need to insert an indent
+ // here. So, write what we have so far, including the '\n'.
+ Write(text + pos, i - pos + 1);
+ pos = i + 1;
+
+ // Setting this true will cause the next Write() to insert an indent
+ // first.
+ at_start_of_line_ = true;
+ }
+ }
+
+ // Write the rest.
+ Write(text + pos, size - pos);
+ }
+
+ // True if any write to the underlying stream failed. (We don't just
+ // crash in this case because this is an I/O failure, not a programming
+ // error.)
+ bool failed() const { return failed_; }
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
+
+ void Write(const char* data, int size) {
+ if (failed_) return;
+ if (size == 0) return;
+
+ if (at_start_of_line_) {
+ // Insert an indent.
+ at_start_of_line_ = false;
+ Write(indent_.data(), indent_.size());
+ if (failed_) return;
+ }
+
+ while (size > buffer_size_) {
+ // Data exceeds space in the buffer. Copy what we can and request a
+ // new buffer.
+ memcpy(buffer_, data, buffer_size_);
+ data += buffer_size_;
+ size -= buffer_size_;
+ void* void_buffer;
+ failed_ = !output_->Next(&void_buffer, &buffer_size_);
+ if (failed_) return;
+ buffer_ = reinterpret_cast<char*>(void_buffer);
+ }
+
+ // Buffer is big enough to receive the data; copy it.
+ memcpy(buffer_, data, size);
+ buffer_ += size;
+ buffer_size_ -= size;
+ }
+
+ io::ZeroCopyOutputStream* const output_;
+ char* buffer_;
+ int buffer_size_;
+ bool at_start_of_line_;
+ bool failed_;
+
+ string indent_;
+ int initial_indent_level_;
+};
+
+// ===========================================================================
+
+TextFormat::Finder::~Finder() {
+}
+
+TextFormat::Parser::Parser()
+ : error_collector_(NULL),
+ finder_(NULL),
+ allow_partial_(false) {
+}
+
+TextFormat::Parser::~Parser() {}
+
+bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
+ Message* output) {
+ output->Clear();
+ ParserImpl parser(output->GetDescriptor(), input, error_collector_,
+ finder_, ParserImpl::FORBID_SINGULAR_OVERWRITES);
+ return MergeUsingImpl(input, output, &parser);
+}
+
+bool TextFormat::Parser::ParseFromString(const string& input,
+ Message* output) {
+ io::ArrayInputStream input_stream(input.data(), input.size());
+ return Parse(&input_stream, output);
+}
+
+bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
+ Message* output) {
+ ParserImpl parser(output->GetDescriptor(), input, error_collector_,
+ finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES);
+ return MergeUsingImpl(input, output, &parser);
+}
+
+bool TextFormat::Parser::MergeFromString(const string& input,
+ Message* output) {
+ io::ArrayInputStream input_stream(input.data(), input.size());
+ return Merge(&input_stream, output);
+}
+
+bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input,
+ Message* output,
+ ParserImpl* parser_impl) {
+ if (!parser_impl->Parse(output)) return false;
+ if (!allow_partial_ && !output->IsInitialized()) {
+ vector<string> missing_fields;
+ output->FindInitializationErrors(&missing_fields);
+ parser_impl->ReportError(-1, 0, "Message missing required fields: " +
+ JoinStrings(missing_fields, ", "));
+ return false;
+ }
+ return true;
+}
+
+bool TextFormat::Parser::ParseFieldValueFromString(
+ const string& input,
+ const FieldDescriptor* field,
+ Message* output) {
+ io::ArrayInputStream input_stream(input.data(), input.size());
+ ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
+ finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES);
+ return parser.ParseField(field, output);
+}
+
+/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
+ Message* output) {
+ return Parser().Parse(input, output);
+}
+
+/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
+ Message* output) {
+ return Parser().Merge(input, output);
+}
+
+/* static */ bool TextFormat::ParseFromString(const string& input,
+ Message* output) {
+ return Parser().ParseFromString(input, output);
+}
+
+/* static */ bool TextFormat::MergeFromString(const string& input,
+ Message* output) {
+ return Parser().MergeFromString(input, output);
+}
+
+// ===========================================================================
+
+TextFormat::Printer::Printer()
+ : initial_indent_level_(0),
+ single_line_mode_(false),
+ use_short_repeated_primitives_(false),
+ utf8_string_escaping_(false) {}
+
+TextFormat::Printer::~Printer() {}
+
+bool TextFormat::Printer::PrintToString(const Message& message,
+ string* output) const {
+ GOOGLE_DCHECK(output) << "output specified is NULL";
+
+ output->clear();
+ io::StringOutputStream output_stream(output);
+
+ bool result = Print(message, &output_stream);
+
+ return result;
+}
+
+bool TextFormat::Printer::PrintUnknownFieldsToString(
+ const UnknownFieldSet& unknown_fields,
+ string* output) const {
+ GOOGLE_DCHECK(output) << "output specified is NULL";
+
+ output->clear();
+ io::StringOutputStream output_stream(output);
+ return PrintUnknownFields(unknown_fields, &output_stream);
+}
+
+bool TextFormat::Printer::Print(const Message& message,
+ io::ZeroCopyOutputStream* output) const {
+ TextGenerator generator(output, initial_indent_level_);
+
+ Print(message, generator);
+
+ // Output false if the generator failed internally.
+ return !generator.failed();
+}
+
+bool TextFormat::Printer::PrintUnknownFields(
+ const UnknownFieldSet& unknown_fields,
+ io::ZeroCopyOutputStream* output) const {
+ TextGenerator generator(output, initial_indent_level_);
+
+ PrintUnknownFields(unknown_fields, generator);
+
+ // Output false if the generator failed internally.
+ return !generator.failed();
+}
+
+void TextFormat::Printer::Print(const Message& message,
+ TextGenerator& generator) const {
+ const Reflection* reflection = message.GetReflection();
+ vector<const FieldDescriptor*> fields;
+ reflection->ListFields(message, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ PrintField(message, reflection, fields[i], generator);
+ }
+ PrintUnknownFields(reflection->GetUnknownFields(message), generator);
+}
+
+void TextFormat::Printer::PrintFieldValueToString(
+ const Message& message,
+ const FieldDescriptor* field,
+ int index,
+ string* output) const {
+
+ GOOGLE_DCHECK(output) << "output specified is NULL";
+
+ output->clear();
+ io::StringOutputStream output_stream(output);
+ TextGenerator generator(&output_stream, initial_indent_level_);
+
+ PrintFieldValue(message, message.GetReflection(), field, index, generator);
+}
+
+void TextFormat::Printer::PrintField(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextGenerator& generator) const {
+ if (use_short_repeated_primitives_ &&
+ field->is_repeated() &&
+ field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ PrintShortRepeatedField(message, reflection, field, generator);
+ return;
+ }
+
+ int count = 0;
+
+ if (field->is_repeated()) {
+ count = reflection->FieldSize(message, field);
+ } else if (reflection->HasField(message, field)) {
+ count = 1;
+ }
+
+ for (int j = 0; j < count; ++j) {
+ PrintFieldName(message, reflection, field, generator);
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (single_line_mode_) {
+ generator.Print(" { ");
+ } else {
+ generator.Print(" {\n");
+ generator.Indent();
+ }
+ } else {
+ generator.Print(": ");
+ }
+
+ // Write the field value.
+ int field_index = j;
+ if (!field->is_repeated()) {
+ field_index = -1;
+ }
+
+ PrintFieldValue(message, reflection, field, field_index, generator);
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ if (single_line_mode_) {
+ generator.Print("} ");
+ } else {
+ generator.Outdent();
+ generator.Print("}\n");
+ }
+ } else {
+ if (single_line_mode_) {
+ generator.Print(" ");
+ } else {
+ generator.Print("\n");
+ }
+ }
+ }
+}
+
+void TextFormat::Printer::PrintShortRepeatedField(
+ const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextGenerator& generator) const {
+ // Print primitive repeated field in short form.
+ PrintFieldName(message, reflection, field, generator);
+
+ int size = reflection->FieldSize(message, field);
+ generator.Print(": [");
+ for (int i = 0; i < size; i++) {
+ if (i > 0) generator.Print(", ");
+ PrintFieldValue(message, reflection, field, i, generator);
+ }
+ if (single_line_mode_) {
+ generator.Print("] ");
+ } else {
+ generator.Print("]\n");
+ }
+}
+
+void TextFormat::Printer::PrintFieldName(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextGenerator& generator) const {
+ if (field->is_extension()) {
+ generator.Print("[");
+ // We special-case MessageSet elements for compatibility with proto1.
+ if (field->containing_type()->options().message_set_wire_format()
+ && field->type() == FieldDescriptor::TYPE_MESSAGE
+ && field->is_optional()
+ && field->extension_scope() == field->message_type()) {
+ generator.Print(field->message_type()->full_name());
+ } else {
+ generator.Print(field->full_name());
+ }
+ generator.Print("]");
+ } else {
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ // Groups must be serialized with their original capitalization.
+ generator.Print(field->message_type()->name());
+ } else {
+ generator.Print(field->name());
+ }
+ }
+}
+
+void TextFormat::Printer::PrintFieldValue(
+ const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ int index,
+ TextGenerator& generator) const {
+ GOOGLE_DCHECK(field->is_repeated() || (index == -1))
+ << "Index must be -1 for non-repeated fields";
+
+ switch (field->cpp_type()) {
+#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \
+ case FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ generator.Print(TO_STRING(field->is_repeated() ? \
+ reflection->GetRepeated##METHOD(message, field, index) : \
+ reflection->Get##METHOD(message, field))); \
+ break; \
+
+ OUTPUT_FIELD( INT32, Int32, SimpleItoa);
+ OUTPUT_FIELD( INT64, Int64, SimpleItoa);
+ OUTPUT_FIELD(UINT32, UInt32, SimpleItoa);
+ OUTPUT_FIELD(UINT64, UInt64, SimpleItoa);
+ OUTPUT_FIELD( FLOAT, Float, SimpleFtoa);
+ OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa);
+#undef OUTPUT_FIELD
+
+ case FieldDescriptor::CPPTYPE_STRING: {
+ string scratch;
+ const string& value = field->is_repeated() ?
+ reflection->GetRepeatedStringReference(
+ message, field, index, &scratch) :
+ reflection->GetStringReference(message, field, &scratch);
+
+ generator.Print("\"");
+ if (utf8_string_escaping_) {
+ generator.Print(strings::Utf8SafeCEscape(value));
+ } else {
+ generator.Print(CEscape(value));
+ }
+ generator.Print("\"");
+
+ break;
+ }
+
+ case FieldDescriptor::CPPTYPE_BOOL:
+ if (field->is_repeated()) {
+ generator.Print(reflection->GetRepeatedBool(message, field, index)
+ ? "true" : "false");
+ } else {
+ generator.Print(reflection->GetBool(message, field)
+ ? "true" : "false");
+ }
+ break;
+
+ case FieldDescriptor::CPPTYPE_ENUM:
+ generator.Print(field->is_repeated() ?
+ reflection->GetRepeatedEnum(message, field, index)->name() :
+ reflection->GetEnum(message, field)->name());
+ break;
+
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ Print(field->is_repeated() ?
+ reflection->GetRepeatedMessage(message, field, index) :
+ reflection->GetMessage(message, field),
+ generator);
+ break;
+ }
+}
+
+/* static */ bool TextFormat::Print(const Message& message,
+ io::ZeroCopyOutputStream* output) {
+ return Printer().Print(message, output);
+}
+
+/* static */ bool TextFormat::PrintUnknownFields(
+ const UnknownFieldSet& unknown_fields,
+ io::ZeroCopyOutputStream* output) {
+ return Printer().PrintUnknownFields(unknown_fields, output);
+}
+
+/* static */ bool TextFormat::PrintToString(
+ const Message& message, string* output) {
+ return Printer().PrintToString(message, output);
+}
+
+/* static */ bool TextFormat::PrintUnknownFieldsToString(
+ const UnknownFieldSet& unknown_fields, string* output) {
+ return Printer().PrintUnknownFieldsToString(unknown_fields, output);
+}
+
+/* static */ void TextFormat::PrintFieldValueToString(
+ const Message& message,
+ const FieldDescriptor* field,
+ int index,
+ string* output) {
+ return Printer().PrintFieldValueToString(message, field, index, output);
+}
+
+/* static */ bool TextFormat::ParseFieldValueFromString(
+ const string& input,
+ const FieldDescriptor* field,
+ Message* message) {
+ return Parser().ParseFieldValueFromString(input, field, message);
+}
+
+// Prints an integer as hex with a fixed number of digits dependent on the
+// integer type.
+template<typename IntType>
+static string PaddedHex(IntType value) {
+ string result;
+ result.reserve(sizeof(value) * 2);
+ for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
+ result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F));
+ }
+ return result;
+}
+
+void TextFormat::Printer::PrintUnknownFields(
+ const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ const UnknownField& field = unknown_fields.field(i);
+ string field_number = SimpleItoa(field.number());
+
+ switch (field.type()) {
+ case UnknownField::TYPE_VARINT:
+ generator.Print(field_number);
+ generator.Print(": ");
+ generator.Print(SimpleItoa(field.varint()));
+ if (single_line_mode_) {
+ generator.Print(" ");
+ } else {
+ generator.Print("\n");
+ }
+ break;
+ case UnknownField::TYPE_FIXED32: {
+ generator.Print(field_number);
+ generator.Print(": 0x");
+ char buffer[kFastToBufferSize];
+ generator.Print(FastHex32ToBuffer(field.fixed32(), buffer));
+ if (single_line_mode_) {
+ generator.Print(" ");
+ } else {
+ generator.Print("\n");
+ }
+ break;
+ }
+ case UnknownField::TYPE_FIXED64: {
+ generator.Print(field_number);
+ generator.Print(": 0x");
+ char buffer[kFastToBufferSize];
+ generator.Print(FastHex64ToBuffer(field.fixed64(), buffer));
+ if (single_line_mode_) {
+ generator.Print(" ");
+ } else {
+ generator.Print("\n");
+ }
+ break;
+ }
+ case UnknownField::TYPE_LENGTH_DELIMITED: {
+ generator.Print(field_number);
+ const string& value = field.length_delimited();
+ UnknownFieldSet embedded_unknown_fields;
+ if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
+ // This field is parseable as a Message.
+ // So it is probably an embedded message.
+ if (single_line_mode_) {
+ generator.Print(" { ");
+ } else {
+ generator.Print(" {\n");
+ generator.Indent();
+ }
+ PrintUnknownFields(embedded_unknown_fields, generator);
+ if (single_line_mode_) {
+ generator.Print("} ");
+ } else {
+ generator.Outdent();
+ generator.Print("}\n");
+ }
+ } else {
+ // This field is not parseable as a Message.
+ // So it is probably just a plain string.
+ generator.Print(": \"");
+ generator.Print(CEscape(value));
+ generator.Print("\"");
+ if (single_line_mode_) {
+ generator.Print(" ");
+ } else {
+ generator.Print("\n");
+ }
+ }
+ break;
+ }
+ case UnknownField::TYPE_GROUP:
+ generator.Print(field_number);
+ if (single_line_mode_) {
+ generator.Print(" { ");
+ } else {
+ generator.Print(" {\n");
+ generator.Indent();
+ }
+ PrintUnknownFields(field.group(), generator);
+ if (single_line_mode_) {
+ generator.Print("} ");
+ } else {
+ generator.Outdent();
+ generator.Print("}\n");
+ }
+ break;
+ }
+ }
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/text_format.h b/src/third_party/protobuf/src/google/protobuf/text_format.h
new file mode 100644
index 0000000..03c0491
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/text_format.h
@@ -0,0 +1,285 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jschorr@google.com (Joseph Schorr)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Utilities for printing and parsing protocol messages in a human-readable,
+// text-based format.
+
+#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
+#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
+
+#include <string>
+#include <google/protobuf/message.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+ class ErrorCollector; // tokenizer.h
+}
+
+// This class implements protocol buffer text format. Printing and parsing
+// protocol messages in text format is useful for debugging and human editing
+// of messages.
+//
+// This class is really a namespace that contains only static methods.
+class LIBPROTOBUF_EXPORT TextFormat {
+ public:
+ // Outputs a textual representation of the given message to the given
+ // output stream.
+ static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
+
+ // Print the fields in an UnknownFieldSet. They are printed by tag number
+ // only. Embedded messages are heuristically identified by attempting to
+ // parse them.
+ static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
+ io::ZeroCopyOutputStream* output);
+
+ // Like Print(), but outputs directly to a string.
+ static bool PrintToString(const Message& message, string* output);
+
+ // Like PrintUnknownFields(), but outputs directly to a string.
+ static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
+ string* output);
+
+ // Outputs a textual representation of the value of the field supplied on
+ // the message supplied. For non-repeated fields, an index of -1 must
+ // be supplied. Note that this method will print the default value for a
+ // field if it is not set.
+ static void PrintFieldValueToString(const Message& message,
+ const FieldDescriptor* field,
+ int index,
+ string* output);
+
+ // Class for those users which require more fine-grained control over how
+ // a protobuffer message is printed out.
+ class LIBPROTOBUF_EXPORT Printer {
+ public:
+ Printer();
+ ~Printer();
+
+ // Like TextFormat::Print
+ bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
+ // Like TextFormat::PrintUnknownFields
+ bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
+ io::ZeroCopyOutputStream* output) const;
+ // Like TextFormat::PrintToString
+ bool PrintToString(const Message& message, string* output) const;
+ // Like TextFormat::PrintUnknownFieldsToString
+ bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
+ string* output) const;
+ // Like TextFormat::PrintFieldValueToString
+ void PrintFieldValueToString(const Message& message,
+ const FieldDescriptor* field,
+ int index,
+ string* output) const;
+
+ // Adjust the initial indent level of all output. Each indent level is
+ // equal to two spaces.
+ void SetInitialIndentLevel(int indent_level) {
+ initial_indent_level_ = indent_level;
+ }
+
+ // If printing in single line mode, then the entire message will be output
+ // on a single line with no line breaks.
+ void SetSingleLineMode(bool single_line_mode) {
+ single_line_mode_ = single_line_mode;
+ }
+
+ // Set true to print repeated primitives in a format like:
+ // field_name: [1, 2, 3, 4]
+ // instead of printing each value on its own line. Short format applies
+ // only to primitive values -- i.e. everything except strings and
+ // sub-messages/groups.
+ void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
+ use_short_repeated_primitives_ = use_short_repeated_primitives;
+ }
+
+ // Set true to output UTF-8 instead of ASCII. The only difference
+ // is that bytes >= 0x80 in string fields will not be escaped,
+ // because they are assumed to be part of UTF-8 multi-byte
+ // sequences.
+ void SetUseUtf8StringEscaping(bool as_utf8) {
+ utf8_string_escaping_ = as_utf8;
+ }
+
+ private:
+ // Forward declaration of an internal class used to print the text
+ // output to the OutputStream (see text_format.cc for implementation).
+ class TextGenerator;
+
+ // Internal Print method, used for writing to the OutputStream via
+ // the TextGenerator class.
+ void Print(const Message& message,
+ TextGenerator& generator) const;
+
+ // Print a single field.
+ void PrintField(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextGenerator& generator) const;
+
+ // Print a repeated primitive field in short form.
+ void PrintShortRepeatedField(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextGenerator& generator) const;
+
+ // Print the name of a field -- i.e. everything that comes before the
+ // ':' for a single name/value pair.
+ void PrintFieldName(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ TextGenerator& generator) const;
+
+ // Outputs a textual representation of the value of the field supplied on
+ // the message supplied or the default value if not set.
+ void PrintFieldValue(const Message& message,
+ const Reflection* reflection,
+ const FieldDescriptor* field,
+ int index,
+ TextGenerator& generator) const;
+
+ // Print the fields in an UnknownFieldSet. They are printed by tag number
+ // only. Embedded messages are heuristically identified by attempting to
+ // parse them.
+ void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
+ TextGenerator& generator) const;
+
+ int initial_indent_level_;
+
+ bool single_line_mode_;
+
+ bool use_short_repeated_primitives_;
+
+ bool utf8_string_escaping_;
+ };
+
+ // Parses a text-format protocol message from the given input stream to
+ // the given message object. This function parses the format written
+ // by Print().
+ static bool Parse(io::ZeroCopyInputStream* input, Message* output);
+ // Like Parse(), but reads directly from a string.
+ static bool ParseFromString(const string& input, Message* output);
+
+ // Like Parse(), but the data is merged into the given message, as if
+ // using Message::MergeFrom().
+ static bool Merge(io::ZeroCopyInputStream* input, Message* output);
+ // Like Merge(), but reads directly from a string.
+ static bool MergeFromString(const string& input, Message* output);
+
+ // Parse the given text as a single field value and store it into the
+ // given field of the given message. If the field is a repeated field,
+ // the new value will be added to the end
+ static bool ParseFieldValueFromString(const string& input,
+ const FieldDescriptor* field,
+ Message* message);
+
+ // Interface that TextFormat::Parser can use to find extensions.
+ // This class may be extended in the future to find more information
+ // like fields, etc.
+ class LIBPROTOBUF_EXPORT Finder {
+ public:
+ virtual ~Finder();
+
+ // Try to find an extension of *message by fully-qualified field
+ // name. Returns NULL if no extension is known for this name or number.
+ virtual const FieldDescriptor* FindExtension(
+ Message* message,
+ const string& name) const = 0;
+ };
+
+ // For more control over parsing, use this class.
+ class LIBPROTOBUF_EXPORT Parser {
+ public:
+ Parser();
+ ~Parser();
+
+ // Like TextFormat::Parse().
+ bool Parse(io::ZeroCopyInputStream* input, Message* output);
+ // Like TextFormat::ParseFromString().
+ bool ParseFromString(const string& input, Message* output);
+ // Like TextFormat::Merge().
+ bool Merge(io::ZeroCopyInputStream* input, Message* output);
+ // Like TextFormat::MergeFromString().
+ bool MergeFromString(const string& input, Message* output);
+
+ // Set where to report parse errors. If NULL (the default), errors will
+ // be printed to stderr.
+ void RecordErrorsTo(io::ErrorCollector* error_collector) {
+ error_collector_ = error_collector;
+ }
+
+ // Set how parser finds extensions. If NULL (the default), the
+ // parser will use the standard Reflection object associated with
+ // the message being parsed.
+ void SetFinder(Finder* finder) {
+ finder_ = finder;
+ }
+
+ // Normally parsing fails if, after parsing, output->IsInitialized()
+ // returns false. Call AllowPartialMessage(true) to skip this check.
+ void AllowPartialMessage(bool allow) {
+ allow_partial_ = allow;
+ }
+
+ // Like TextFormat::ParseFieldValueFromString
+ bool ParseFieldValueFromString(const string& input,
+ const FieldDescriptor* field,
+ Message* output);
+
+ private:
+ // Forward declaration of an internal class used to parse text
+ // representations (see text_format.cc for implementation).
+ class ParserImpl;
+
+ // Like TextFormat::Merge(). The provided implementation is used
+ // to do the parsing.
+ bool MergeUsingImpl(io::ZeroCopyInputStream* input,
+ Message* output,
+ ParserImpl* parser_impl);
+
+ io::ErrorCollector* error_collector_;
+ Finder* finder_;
+ bool allow_partial_;
+ };
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
+};
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/text_format_unittest.cc b/src/third_party/protobuf/src/google/protobuf/text_format_unittest.cc
new file mode 100644
index 0000000..00ea8c3
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/text_format_unittest.cc
@@ -0,0 +1,1141 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jschorr@google.com (Joseph Schorr)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <math.h>
+#include <stdlib.h>
+#include <limits>
+
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_mset.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace text_format_unittest {
+
+inline bool IsNaN(double value) {
+ // NaN is never equal to anything, even itself.
+ return value != value;
+}
+
+// A basic string with different escapable characters for testing.
+const string kEscapeTestString =
+ "\"A string with ' characters \n and \r newlines and \t tabs and \001 "
+ "slashes \\ and multiple spaces";
+
+// A representation of the above string with all the characters escaped.
+const string kEscapeTestStringEscaped =
+ "\"\\\"A string with \\' characters \\n and \\r newlines "
+ "and \\t tabs and \\001 slashes \\\\ and multiple spaces\"";
+
+class TextFormatTest : public testing::Test {
+ public:
+ static void SetUpTestCase() {
+ File::ReadFileToStringOrDie(
+ TestSourceDir()
+ + "/google/protobuf/testdata/text_format_unittest_data.txt",
+ &static_proto_debug_string_);
+ }
+
+ TextFormatTest() : proto_debug_string_(static_proto_debug_string_) {}
+
+ protected:
+ // Debug string read from text_format_unittest_data.txt.
+ const string proto_debug_string_;
+ unittest::TestAllTypes proto_;
+
+ private:
+ static string static_proto_debug_string_;
+};
+string TextFormatTest::static_proto_debug_string_;
+
+class TextFormatExtensionsTest : public testing::Test {
+ public:
+ static void SetUpTestCase() {
+ File::ReadFileToStringOrDie(
+ TestSourceDir()
+ + "/google/protobuf/testdata/"
+ "text_format_unittest_extensions_data.txt",
+ &static_proto_debug_string_);
+ }
+
+ TextFormatExtensionsTest()
+ : proto_debug_string_(static_proto_debug_string_) {}
+
+ protected:
+ // Debug string read from text_format_unittest_data.txt.
+ const string proto_debug_string_;
+ unittest::TestAllExtensions proto_;
+
+ private:
+ static string static_proto_debug_string_;
+};
+string TextFormatExtensionsTest::static_proto_debug_string_;
+
+
+TEST_F(TextFormatTest, Basic) {
+ TestUtil::SetAllFields(&proto_);
+ EXPECT_EQ(proto_debug_string_, proto_.DebugString());
+}
+
+TEST_F(TextFormatExtensionsTest, Extensions) {
+ TestUtil::SetAllExtensions(&proto_);
+ EXPECT_EQ(proto_debug_string_, proto_.DebugString());
+}
+
+TEST_F(TextFormatTest, ShortDebugString) {
+ proto_.set_optional_int32(1);
+ proto_.set_optional_string("hello");
+ proto_.mutable_optional_nested_message()->set_bb(2);
+ proto_.mutable_optional_foreign_message();
+
+ EXPECT_EQ("optional_int32: 1 optional_string: \"hello\" "
+ "optional_nested_message { bb: 2 } "
+ "optional_foreign_message { }",
+ proto_.ShortDebugString());
+}
+
+TEST_F(TextFormatTest, ShortPrimitiveRepeateds) {
+ proto_.set_optional_int32(123);
+ proto_.add_repeated_int32(456);
+ proto_.add_repeated_int32(789);
+ proto_.add_repeated_string("foo");
+ proto_.add_repeated_string("bar");
+ proto_.add_repeated_nested_message()->set_bb(2);
+ proto_.add_repeated_nested_message()->set_bb(3);
+ proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO);
+ proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR);
+
+ TextFormat::Printer printer;
+ printer.SetUseShortRepeatedPrimitives(true);
+ string text;
+ printer.PrintToString(proto_, &text);
+
+ EXPECT_EQ("optional_int32: 123\n"
+ "repeated_int32: [456, 789]\n"
+ "repeated_string: \"foo\"\n"
+ "repeated_string: \"bar\"\n"
+ "repeated_nested_message {\n bb: 2\n}\n"
+ "repeated_nested_message {\n bb: 3\n}\n"
+ "repeated_nested_enum: [FOO, BAR]\n",
+ text);
+
+ // Try in single-line mode.
+ printer.SetSingleLineMode(true);
+ printer.PrintToString(proto_, &text);
+
+ EXPECT_EQ("optional_int32: 123 "
+ "repeated_int32: [456, 789] "
+ "repeated_string: \"foo\" "
+ "repeated_string: \"bar\" "
+ "repeated_nested_message { bb: 2 } "
+ "repeated_nested_message { bb: 3 } "
+ "repeated_nested_enum: [FOO, BAR] ",
+ text);
+}
+
+
+TEST_F(TextFormatTest, StringEscape) {
+ // Set the string value to test.
+ proto_.set_optional_string(kEscapeTestString);
+
+ // Get the DebugString from the proto.
+ string debug_string = proto_.DebugString();
+ string utf8_debug_string = proto_.Utf8DebugString();
+
+ // Hardcode a correct value to test against.
+ string correct_string = "optional_string: "
+ + kEscapeTestStringEscaped
+ + "\n";
+
+ // Compare.
+ EXPECT_EQ(correct_string, debug_string);
+ // UTF-8 string is the same as non-UTF-8 because
+ // the protocol buffer contains no UTF-8 text.
+ EXPECT_EQ(correct_string, utf8_debug_string);
+
+ string expected_short_debug_string = "optional_string: "
+ + kEscapeTestStringEscaped;
+ EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString());
+}
+
+TEST_F(TextFormatTest, Utf8DebugString) {
+ // Set the string value to test.
+ proto_.set_optional_string("\350\260\267\346\255\214");
+
+ // Get the DebugString from the proto.
+ string debug_string = proto_.DebugString();
+ string utf8_debug_string = proto_.Utf8DebugString();
+
+ // Hardcode a correct value to test against.
+ string correct_utf8_string = "optional_string: "
+ "\"\350\260\267\346\255\214\""
+ "\n";
+ string correct_string = "optional_string: "
+ "\"\\350\\260\\267\\346\\255\\214\""
+ "\n";
+
+ // Compare.
+ EXPECT_EQ(correct_utf8_string, utf8_debug_string);
+ EXPECT_EQ(correct_string, debug_string);
+}
+
+TEST_F(TextFormatTest, PrintUnknownFields) {
+ // Test printing of unknown fields in a message.
+
+ unittest::TestEmptyMessage message;
+ UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
+
+ unknown_fields->AddVarint(5, 1);
+ unknown_fields->AddFixed32(5, 2);
+ unknown_fields->AddFixed64(5, 3);
+ unknown_fields->AddLengthDelimited(5, "4");
+ unknown_fields->AddGroup(5)->AddVarint(10, 5);
+
+ unknown_fields->AddVarint(8, 1);
+ unknown_fields->AddVarint(8, 2);
+ unknown_fields->AddVarint(8, 3);
+
+ EXPECT_EQ(
+ "5: 1\n"
+ "5: 0x00000002\n"
+ "5: 0x0000000000000003\n"
+ "5: \"4\"\n"
+ "5 {\n"
+ " 10: 5\n"
+ "}\n"
+ "8: 1\n"
+ "8: 2\n"
+ "8: 3\n",
+ message.DebugString());
+}
+
+TEST_F(TextFormatTest, PrintUnknownMessage) {
+ // Test heuristic printing of messages in an UnknownFieldSet.
+
+ protobuf_unittest::TestAllTypes message;
+
+ // Cases which should not be interpreted as sub-messages.
+
+ // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message
+ // it should be followed by 8 bytes. Since this string only has two
+ // subsequent bytes, it should be treated as a string.
+ message.add_repeated_string("abc");
+
+ // 'd' happens to be a valid ENDGROUP tag. So,
+ // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but
+ // the ConsumedEntireMessage() check should fail.
+ message.add_repeated_string("def");
+
+ // A zero-length string should never be interpreted as a message even though
+ // it is technically valid as one.
+ message.add_repeated_string("");
+
+ // Case which should be interpreted as a sub-message.
+
+ // An actual nested message with content should always be interpreted as a
+ // nested message.
+ message.add_repeated_nested_message()->set_bb(123);
+
+ string data;
+ message.SerializeToString(&data);
+
+ string text;
+ UnknownFieldSet unknown_fields;
+ EXPECT_TRUE(unknown_fields.ParseFromString(data));
+ EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text));
+ EXPECT_EQ(
+ "44: \"abc\"\n"
+ "44: \"def\"\n"
+ "44: \"\"\n"
+ "48 {\n"
+ " 1: 123\n"
+ "}\n",
+ text);
+}
+
+TEST_F(TextFormatTest, PrintMessageWithIndent) {
+ // Test adding an initial indent to printing.
+
+ protobuf_unittest::TestAllTypes message;
+
+ message.add_repeated_string("abc");
+ message.add_repeated_string("def");
+ message.add_repeated_nested_message()->set_bb(123);
+
+ string text;
+ TextFormat::Printer printer;
+ printer.SetInitialIndentLevel(1);
+ EXPECT_TRUE(printer.PrintToString(message, &text));
+ EXPECT_EQ(
+ " repeated_string: \"abc\"\n"
+ " repeated_string: \"def\"\n"
+ " repeated_nested_message {\n"
+ " bb: 123\n"
+ " }\n",
+ text);
+}
+
+TEST_F(TextFormatTest, PrintMessageSingleLine) {
+ // Test printing a message on a single line.
+
+ protobuf_unittest::TestAllTypes message;
+
+ message.add_repeated_string("abc");
+ message.add_repeated_string("def");
+ message.add_repeated_nested_message()->set_bb(123);
+
+ string text;
+ TextFormat::Printer printer;
+ printer.SetInitialIndentLevel(1);
+ printer.SetSingleLineMode(true);
+ EXPECT_TRUE(printer.PrintToString(message, &text));
+ EXPECT_EQ(
+ " repeated_string: \"abc\" repeated_string: \"def\" "
+ "repeated_nested_message { bb: 123 } ",
+ text);
+}
+
+TEST_F(TextFormatTest, ParseBasic) {
+ io::ArrayInputStream input_stream(proto_debug_string_.data(),
+ proto_debug_string_.size());
+ TextFormat::Parse(&input_stream, &proto_);
+ TestUtil::ExpectAllFieldsSet(proto_);
+}
+
+TEST_F(TextFormatExtensionsTest, ParseExtensions) {
+ io::ArrayInputStream input_stream(proto_debug_string_.data(),
+ proto_debug_string_.size());
+ TextFormat::Parse(&input_stream, &proto_);
+ TestUtil::ExpectAllExtensionsSet(proto_);
+}
+
+TEST_F(TextFormatTest, ParseEnumFieldFromNumber) {
+ // Create a parse string with a numerical value for an enum field.
+ string parse_string = strings::Substitute("optional_nested_enum: $0",
+ unittest::TestAllTypes::BAZ);
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+ EXPECT_TRUE(proto_.has_optional_nested_enum());
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum());
+}
+
+TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
+ ASSERT_LT(unittest::SPARSE_E, 0);
+ string parse_string = strings::Substitute("sparse_enum: $0",
+ unittest::SPARSE_E);
+ unittest::SparseEnumMessage proto;
+ EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+ EXPECT_TRUE(proto.has_sparse_enum());
+ EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
+}
+
+TEST_F(TextFormatTest, ParseStringEscape) {
+ // Create a parse string with escpaed characters in it.
+ string parse_string = "optional_string: "
+ + kEscapeTestStringEscaped
+ + "\n";
+
+ io::ArrayInputStream input_stream(parse_string.data(),
+ parse_string.size());
+ TextFormat::Parse(&input_stream, &proto_);
+
+ // Compare.
+ EXPECT_EQ(kEscapeTestString, proto_.optional_string());
+}
+
+TEST_F(TextFormatTest, ParseConcatenatedString) {
+ // Create a parse string with multiple parts on one line.
+ string parse_string = "optional_string: \"foo\" \"bar\"\n";
+
+ io::ArrayInputStream input_stream1(parse_string.data(),
+ parse_string.size());
+ TextFormat::Parse(&input_stream1, &proto_);
+
+ // Compare.
+ EXPECT_EQ("foobar", proto_.optional_string());
+
+ // Create a parse string with multiple parts on seperate lines.
+ parse_string = "optional_string: \"foo\"\n"
+ "\"bar\"\n";
+
+ io::ArrayInputStream input_stream2(parse_string.data(),
+ parse_string.size());
+ TextFormat::Parse(&input_stream2, &proto_);
+
+ // Compare.
+ EXPECT_EQ("foobar", proto_.optional_string());
+}
+
+TEST_F(TextFormatTest, ParseFloatWithSuffix) {
+ // Test that we can parse a floating-point value with 'f' appended to the
+ // end. This is needed for backwards-compatibility with proto1.
+
+ // Have it parse a float with the 'f' suffix.
+ string parse_string = "optional_float: 1.0f\n";
+
+ io::ArrayInputStream input_stream(parse_string.data(),
+ parse_string.size());
+
+ TextFormat::Parse(&input_stream, &proto_);
+
+ // Compare.
+ EXPECT_EQ(1.0, proto_.optional_float());
+}
+
+TEST_F(TextFormatTest, ParseShortRepeatedForm) {
+ string parse_string =
+ // Mixed short-form and long-form are simply concatenated.
+ "repeated_int32: 1\n"
+ "repeated_int32: [456, 789]\n"
+ "repeated_nested_enum: [ FOO ,BAR, # comment\n"
+ " 3]\n"
+ // Note that while the printer won't print repeated strings in short-form,
+ // the parser will accept them.
+ "repeated_string: [ \"foo\", 'bar' ]\n";
+
+ ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+
+ ASSERT_EQ(3, proto_.repeated_int32_size());
+ EXPECT_EQ(1, proto_.repeated_int32(0));
+ EXPECT_EQ(456, proto_.repeated_int32(1));
+ EXPECT_EQ(789, proto_.repeated_int32(2));
+
+ ASSERT_EQ(3, proto_.repeated_nested_enum_size());
+ EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
+ EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
+ EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
+
+ ASSERT_EQ(2, proto_.repeated_string_size());
+ EXPECT_EQ("foo", proto_.repeated_string(0));
+ EXPECT_EQ("bar", proto_.repeated_string(1));
+}
+
+TEST_F(TextFormatTest, Comments) {
+ // Test that comments are ignored.
+
+ string parse_string = "optional_int32: 1 # a comment\n"
+ "optional_int64: 2 # another comment";
+
+ io::ArrayInputStream input_stream(parse_string.data(),
+ parse_string.size());
+
+ TextFormat::Parse(&input_stream, &proto_);
+
+ // Compare.
+ EXPECT_EQ(1, proto_.optional_int32());
+ EXPECT_EQ(2, proto_.optional_int64());
+}
+
+TEST_F(TextFormatTest, OptionalColon) {
+ // Test that we can place a ':' after the field name of a nested message,
+ // even though we don't have to.
+
+ string parse_string = "optional_nested_message: { bb: 1}\n";
+
+ io::ArrayInputStream input_stream(parse_string.data(),
+ parse_string.size());
+
+ TextFormat::Parse(&input_stream, &proto_);
+
+ // Compare.
+ EXPECT_TRUE(proto_.has_optional_nested_message());
+ EXPECT_EQ(1, proto_.optional_nested_message().bb());
+}
+
+// Some platforms (e.g. Windows) insist on padding the exponent to three
+// digits when one or two would be just fine.
+static string RemoveRedundantZeros(string text) {
+ text = StringReplace(text, "e+0", "e+", true);
+ text = StringReplace(text, "e-0", "e-", true);
+ return text;
+}
+
+TEST_F(TextFormatTest, PrintExotic) {
+ unittest::TestAllTypes message;
+
+ // Note: In C, a negative integer literal is actually the unary negation
+ // operator being applied to a positive integer literal, and
+ // 9223372036854775808 is outside the range of int64. However, it is not
+ // outside the range of uint64. Confusingly, this means that everything
+ // works if we make the literal unsigned, even though we are negating it.
+ message.add_repeated_int64(-GOOGLE_ULONGLONG(9223372036854775808));
+ message.add_repeated_uint64(GOOGLE_ULONGLONG(18446744073709551615));
+ message.add_repeated_double(123.456);
+ message.add_repeated_double(1.23e21);
+ message.add_repeated_double(1.23e-18);
+ message.add_repeated_double(std::numeric_limits<double>::infinity());
+ message.add_repeated_double(-std::numeric_limits<double>::infinity());
+ message.add_repeated_double(std::numeric_limits<double>::quiet_NaN());
+ message.add_repeated_string(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12));
+
+ // Fun story: We used to use 1.23e22 instead of 1.23e21 above, but this
+ // seemed to trigger an odd case on MinGW/GCC 3.4.5 where GCC's parsing of
+ // the value differed from strtod()'s parsing. That is to say, the
+ // following assertion fails on MinGW:
+ // assert(1.23e22 == strtod("1.23e22", NULL));
+ // As a result, SimpleDtoa() would print the value as
+ // "1.2300000000000001e+22" to make sure strtod() produce the exact same
+ // result. Our goal is to test runtime parsing, not compile-time parsing,
+ // so this wasn't our problem. It was found that using 1.23e21 did not
+ // have this problem, so we switched to that instead.
+
+ EXPECT_EQ(
+ "repeated_int64: -9223372036854775808\n"
+ "repeated_uint64: 18446744073709551615\n"
+ "repeated_double: 123.456\n"
+ "repeated_double: 1.23e+21\n"
+ "repeated_double: 1.23e-18\n"
+ "repeated_double: inf\n"
+ "repeated_double: -inf\n"
+ "repeated_double: nan\n"
+ "repeated_string: \"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\'\\\"\"\n",
+ RemoveRedundantZeros(message.DebugString()));
+}
+
+TEST_F(TextFormatTest, PrintFloatPrecision) {
+ unittest::TestAllTypes message;
+
+ message.add_repeated_float(1.2);
+ message.add_repeated_float(1.23);
+ message.add_repeated_float(1.234);
+ message.add_repeated_float(1.2345);
+ message.add_repeated_float(1.23456);
+ message.add_repeated_float(1.2e10);
+ message.add_repeated_float(1.23e10);
+ message.add_repeated_float(1.234e10);
+ message.add_repeated_float(1.2345e10);
+ message.add_repeated_float(1.23456e10);
+ message.add_repeated_double(1.2);
+ message.add_repeated_double(1.23);
+ message.add_repeated_double(1.234);
+ message.add_repeated_double(1.2345);
+ message.add_repeated_double(1.23456);
+ message.add_repeated_double(1.234567);
+ message.add_repeated_double(1.2345678);
+ message.add_repeated_double(1.23456789);
+ message.add_repeated_double(1.234567898);
+ message.add_repeated_double(1.2345678987);
+ message.add_repeated_double(1.23456789876);
+ message.add_repeated_double(1.234567898765);
+ message.add_repeated_double(1.2345678987654);
+ message.add_repeated_double(1.23456789876543);
+ message.add_repeated_double(1.2e100);
+ message.add_repeated_double(1.23e100);
+ message.add_repeated_double(1.234e100);
+ message.add_repeated_double(1.2345e100);
+ message.add_repeated_double(1.23456e100);
+ message.add_repeated_double(1.234567e100);
+ message.add_repeated_double(1.2345678e100);
+ message.add_repeated_double(1.23456789e100);
+ message.add_repeated_double(1.234567898e100);
+ message.add_repeated_double(1.2345678987e100);
+ message.add_repeated_double(1.23456789876e100);
+ message.add_repeated_double(1.234567898765e100);
+ message.add_repeated_double(1.2345678987654e100);
+ message.add_repeated_double(1.23456789876543e100);
+
+ EXPECT_EQ(
+ "repeated_float: 1.2\n"
+ "repeated_float: 1.23\n"
+ "repeated_float: 1.234\n"
+ "repeated_float: 1.2345\n"
+ "repeated_float: 1.23456\n"
+ "repeated_float: 1.2e+10\n"
+ "repeated_float: 1.23e+10\n"
+ "repeated_float: 1.234e+10\n"
+ "repeated_float: 1.2345e+10\n"
+ "repeated_float: 1.23456e+10\n"
+ "repeated_double: 1.2\n"
+ "repeated_double: 1.23\n"
+ "repeated_double: 1.234\n"
+ "repeated_double: 1.2345\n"
+ "repeated_double: 1.23456\n"
+ "repeated_double: 1.234567\n"
+ "repeated_double: 1.2345678\n"
+ "repeated_double: 1.23456789\n"
+ "repeated_double: 1.234567898\n"
+ "repeated_double: 1.2345678987\n"
+ "repeated_double: 1.23456789876\n"
+ "repeated_double: 1.234567898765\n"
+ "repeated_double: 1.2345678987654\n"
+ "repeated_double: 1.23456789876543\n"
+ "repeated_double: 1.2e+100\n"
+ "repeated_double: 1.23e+100\n"
+ "repeated_double: 1.234e+100\n"
+ "repeated_double: 1.2345e+100\n"
+ "repeated_double: 1.23456e+100\n"
+ "repeated_double: 1.234567e+100\n"
+ "repeated_double: 1.2345678e+100\n"
+ "repeated_double: 1.23456789e+100\n"
+ "repeated_double: 1.234567898e+100\n"
+ "repeated_double: 1.2345678987e+100\n"
+ "repeated_double: 1.23456789876e+100\n"
+ "repeated_double: 1.234567898765e+100\n"
+ "repeated_double: 1.2345678987654e+100\n"
+ "repeated_double: 1.23456789876543e+100\n",
+ RemoveRedundantZeros(message.DebugString()));
+}
+
+
+TEST_F(TextFormatTest, AllowPartial) {
+ unittest::TestRequired message;
+ TextFormat::Parser parser;
+ parser.AllowPartialMessage(true);
+ EXPECT_TRUE(parser.ParseFromString("a: 1", &message));
+ EXPECT_EQ(1, message.a());
+ EXPECT_FALSE(message.has_b());
+ EXPECT_FALSE(message.has_c());
+}
+
+TEST_F(TextFormatTest, ParseExotic) {
+ unittest::TestAllTypes message;
+ ASSERT_TRUE(TextFormat::ParseFromString(
+ "repeated_int32: -1\n"
+ "repeated_int32: -2147483648\n"
+ "repeated_int64: -1\n"
+ "repeated_int64: -9223372036854775808\n"
+ "repeated_uint32: 4294967295\n"
+ "repeated_uint32: 2147483648\n"
+ "repeated_uint64: 18446744073709551615\n"
+ "repeated_uint64: 9223372036854775808\n"
+ "repeated_double: 123.0\n"
+ "repeated_double: 123.5\n"
+ "repeated_double: 0.125\n"
+ "repeated_double: 1.23E17\n"
+ "repeated_double: 1.235E+22\n"
+ "repeated_double: 1.235e-18\n"
+ "repeated_double: 123.456789\n"
+ "repeated_double: inf\n"
+ "repeated_double: Infinity\n"
+ "repeated_double: -inf\n"
+ "repeated_double: -Infinity\n"
+ "repeated_double: nan\n"
+ "repeated_double: NaN\n"
+ "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\"\n",
+ &message));
+
+ ASSERT_EQ(2, message.repeated_int32_size());
+ EXPECT_EQ(-1, message.repeated_int32(0));
+ // Note: In C, a negative integer literal is actually the unary negation
+ // operator being applied to a positive integer literal, and 2147483648 is
+ // outside the range of int32. However, it is not outside the range of
+ // uint32. Confusingly, this means that everything works if we make the
+ // literal unsigned, even though we are negating it.
+ EXPECT_EQ(-2147483648u, message.repeated_int32(1));
+
+ ASSERT_EQ(2, message.repeated_int64_size());
+ EXPECT_EQ(-1, message.repeated_int64(0));
+ // Note: In C, a negative integer literal is actually the unary negation
+ // operator being applied to a positive integer literal, and
+ // 9223372036854775808 is outside the range of int64. However, it is not
+ // outside the range of uint64. Confusingly, this means that everything
+ // works if we make the literal unsigned, even though we are negating it.
+ EXPECT_EQ(-GOOGLE_ULONGLONG(9223372036854775808), message.repeated_int64(1));
+
+ ASSERT_EQ(2, message.repeated_uint32_size());
+ EXPECT_EQ(4294967295u, message.repeated_uint32(0));
+ EXPECT_EQ(2147483648u, message.repeated_uint32(1));
+
+ ASSERT_EQ(2, message.repeated_uint64_size());
+ EXPECT_EQ(GOOGLE_ULONGLONG(18446744073709551615), message.repeated_uint64(0));
+ EXPECT_EQ(GOOGLE_ULONGLONG(9223372036854775808), message.repeated_uint64(1));
+
+ ASSERT_EQ(13, message.repeated_double_size());
+ EXPECT_EQ(123.0 , message.repeated_double(0));
+ EXPECT_EQ(123.5 , message.repeated_double(1));
+ EXPECT_EQ(0.125 , message.repeated_double(2));
+ EXPECT_EQ(1.23E17 , message.repeated_double(3));
+ EXPECT_EQ(1.235E22 , message.repeated_double(4));
+ EXPECT_EQ(1.235E-18 , message.repeated_double(5));
+ EXPECT_EQ(123.456789, message.repeated_double(6));
+ EXPECT_EQ(message.repeated_double(7), numeric_limits<double>::infinity());
+ EXPECT_EQ(message.repeated_double(8), numeric_limits<double>::infinity());
+ EXPECT_EQ(message.repeated_double(9), -numeric_limits<double>::infinity());
+ EXPECT_EQ(message.repeated_double(10), -numeric_limits<double>::infinity());
+ EXPECT_TRUE(IsNaN(message.repeated_double(11)));
+ EXPECT_TRUE(IsNaN(message.repeated_double(12)));
+
+ // Note: Since these string literals have \0's in them, we must explicitly
+ // pass their sizes to string's constructor.
+ ASSERT_EQ(1, message.repeated_string_size());
+ EXPECT_EQ(string("\000\001\a\b\f\n\r\t\v\\\'\"", 12),
+ message.repeated_string(0));
+}
+
+class TextFormatParserTest : public testing::Test {
+ protected:
+ void ExpectFailure(const string& input, const string& message, int line,
+ int col) {
+ scoped_ptr<unittest::TestAllTypes> proto(new unittest::TestAllTypes);
+ ExpectFailure(input, message, line, col, proto.get());
+ }
+
+ void ExpectFailure(const string& input, const string& message, int line,
+ int col, Message* proto) {
+ ExpectMessage(input, message, line, col, proto, false);
+ }
+
+ void ExpectMessage(const string& input, const string& message, int line,
+ int col, Message* proto, bool expected_result) {
+ TextFormat::Parser parser;
+ MockErrorCollector error_collector;
+ parser.RecordErrorsTo(&error_collector);
+ EXPECT_EQ(parser.ParseFromString(input, proto), expected_result);
+ EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n",
+ error_collector.text_);
+ }
+
+ // An error collector which simply concatenates all its errors into a big
+ // block of text which can be checked.
+ class MockErrorCollector : public io::ErrorCollector {
+ public:
+ MockErrorCollector() {}
+ ~MockErrorCollector() {}
+
+ string text_;
+
+ // implements ErrorCollector -------------------------------------
+ void AddError(int line, int column, const string& message) {
+ strings::SubstituteAndAppend(&text_, "$0:$1: $2\n",
+ line + 1, column + 1, message);
+ }
+
+ void AddWarning(int line, int column, const string& message) {
+ AddError(line, column, "WARNING:" + message);
+ }
+ };
+};
+
+TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
+ scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
+ const Descriptor* d = message->GetDescriptor();
+
+#define EXPECT_FIELD(name, value, valuestring) \
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+ EXPECT_EQ(value, message->optional_##name()); \
+ EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_FLOAT_FIELD(name, value, valuestring) \
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+ EXPECT_FLOAT_EQ(value, message->optional_##name()); \
+ EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_DOUBLE_FIELD(name, value, valuestring) \
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+ EXPECT_DOUBLE_EQ(value, message->optional_##name()); \
+ EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_INVALID(name, valuestring) \
+ EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \
+ valuestring, d->FindFieldByName("optional_" #name), message.get()));
+
+ // int32
+ EXPECT_FIELD(int32, 1, "1");
+ EXPECT_FIELD(int32, -1, "-1");
+ EXPECT_FIELD(int32, 0x1234, "0x1234");
+ EXPECT_INVALID(int32, "a");
+ EXPECT_INVALID(int32, "999999999999999999999999999999999999");
+ EXPECT_INVALID(int32, "1,2");
+
+ // int64
+ EXPECT_FIELD(int64, 1, "1");
+ EXPECT_FIELD(int64, -1, "-1");
+ EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678");
+ EXPECT_INVALID(int64, "a");
+ EXPECT_INVALID(int64, "999999999999999999999999999999999999");
+ EXPECT_INVALID(int64, "1,2");
+
+ // uint64
+ EXPECT_FIELD(uint64, 1, "1");
+ EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678");
+ EXPECT_INVALID(uint64, "-1");
+ EXPECT_INVALID(uint64, "a");
+ EXPECT_INVALID(uint64, "999999999999999999999999999999999999");
+ EXPECT_INVALID(uint64, "1,2");
+
+ // fixed32
+ EXPECT_FIELD(fixed32, 1, "1");
+ EXPECT_FIELD(fixed32, 0x12345678, "0x12345678");
+ EXPECT_INVALID(fixed32, "-1");
+ EXPECT_INVALID(fixed32, "a");
+ EXPECT_INVALID(fixed32, "999999999999999999999999999999999999");
+ EXPECT_INVALID(fixed32, "1,2");
+
+ // fixed64
+ EXPECT_FIELD(fixed64, 1, "1");
+ EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678");
+ EXPECT_INVALID(fixed64, "-1");
+ EXPECT_INVALID(fixed64, "a");
+ EXPECT_INVALID(fixed64, "999999999999999999999999999999999999");
+ EXPECT_INVALID(fixed64, "1,2");
+
+ // bool
+ EXPECT_FIELD(bool, true, "true");
+ EXPECT_FIELD(bool, false, "false");
+ EXPECT_FIELD(bool, true, "1");
+ EXPECT_FIELD(bool, true, "t");
+ EXPECT_FIELD(bool, false, "0");
+ EXPECT_FIELD(bool, false, "f");
+ EXPECT_INVALID(bool, "2");
+ EXPECT_INVALID(bool, "-0");
+ EXPECT_INVALID(bool, "on");
+ EXPECT_INVALID(bool, "a");
+ EXPECT_INVALID(bool, "True");
+
+ // float
+ EXPECT_FIELD(float, 1, "1");
+ EXPECT_FLOAT_FIELD(float, 1.5, "1.5");
+ EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3");
+ EXPECT_FLOAT_FIELD(float, -4.55, "-4.55");
+ EXPECT_INVALID(float, "a");
+ EXPECT_INVALID(float, "1,2");
+
+ // double
+ EXPECT_FIELD(double, 1, "1");
+ EXPECT_FIELD(double, -1, "-1");
+ EXPECT_DOUBLE_FIELD(double, 2.3, "2.3");
+ EXPECT_DOUBLE_FIELD(double, 3e5, "3e5");
+ EXPECT_INVALID(double, "a");
+ EXPECT_INVALID(double, "1,2");
+
+ // string
+ EXPECT_FIELD(string, "hello", "\"hello\"");
+ EXPECT_FIELD(string, "-1.87", "'-1.87'");
+ EXPECT_INVALID(string, "hello"); // without quote for value
+
+ // enum
+ EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
+ EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
+ SimpleItoa(unittest::TestAllTypes::BAZ));
+ EXPECT_INVALID(nested_enum, "FOOBAR");
+
+ // message
+ EXPECT_TRUE(TextFormat::ParseFieldValueFromString(
+ "<bb:12>", d->FindFieldByName("optional_nested_message"), message.get()));
+ EXPECT_EQ(12, message->optional_nested_message().bb()); \
+ EXPECT_TRUE(message->has_optional_nested_message());
+ EXPECT_INVALID(nested_message, "any");
+
+#undef EXPECT_FIELD
+#undef EXPECT_FLOAT_FIELD
+#undef EXPECT_DOUBLE_FIELD
+#undef EXPECT_INVALID
+}
+
+
+TEST_F(TextFormatParserTest, InvalidToken) {
+ ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.",
+ 2, 1);
+
+ ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20);
+ ExpectFailure("\"some string\"", "Expected identifier.", 1, 1);
+}
+
+TEST_F(TextFormatParserTest, InvalidFieldName) {
+ ExpectFailure(
+ "invalid_field: somevalue\n",
+ "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+ "\"invalid_field\".",
+ 1, 14);
+}
+
+TEST_F(TextFormatParserTest, InvalidCapitalization) {
+ // We require that group names be exactly as they appear in the .proto.
+ ExpectFailure(
+ "optionalgroup {\na: 15\n}\n",
+ "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+ "\"optionalgroup\".",
+ 1, 15);
+ ExpectFailure(
+ "OPTIONALgroup {\na: 15\n}\n",
+ "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+ "\"OPTIONALgroup\".",
+ 1, 15);
+ ExpectFailure(
+ "Optional_Double: 10.0\n",
+ "Message type \"protobuf_unittest.TestAllTypes\" has no field named "
+ "\"Optional_Double\".",
+ 1, 16);
+}
+
+TEST_F(TextFormatParserTest, InvalidFieldValues) {
+ // Invalid values for a double/float field.
+ ExpectFailure("optional_double: \"hello\"\n", "Expected double.", 1, 18);
+ ExpectFailure("optional_double: true\n", "Expected double.", 1, 18);
+ ExpectFailure("optional_double: !\n", "Expected double.", 1, 18);
+ ExpectFailure("optional_double {\n \n}\n", "Expected \":\", found \"{\".",
+ 1, 17);
+
+ // Invalid values for a signed integer field.
+ ExpectFailure("optional_int32: \"hello\"\n", "Expected integer.", 1, 17);
+ ExpectFailure("optional_int32: true\n", "Expected integer.", 1, 17);
+ ExpectFailure("optional_int32: 4.5\n", "Expected integer.", 1, 17);
+ ExpectFailure("optional_int32: !\n", "Expected integer.", 1, 17);
+ ExpectFailure("optional_int32 {\n \n}\n", "Expected \":\", found \"{\".",
+ 1, 16);
+ ExpectFailure("optional_int32: 0x80000000\n",
+ "Integer out of range.", 1, 17);
+ ExpectFailure("optional_int32: -0x80000001\n",
+ "Integer out of range.", 1, 18);
+ ExpectFailure("optional_int64: 0x8000000000000000\n",
+ "Integer out of range.", 1, 17);
+ ExpectFailure("optional_int64: -0x8000000000000001\n",
+ "Integer out of range.", 1, 18);
+
+ // Invalid values for an unsigned integer field.
+ ExpectFailure("optional_uint64: \"hello\"\n", "Expected integer.", 1, 18);
+ ExpectFailure("optional_uint64: true\n", "Expected integer.", 1, 18);
+ ExpectFailure("optional_uint64: 4.5\n", "Expected integer.", 1, 18);
+ ExpectFailure("optional_uint64: -5\n", "Expected integer.", 1, 18);
+ ExpectFailure("optional_uint64: !\n", "Expected integer.", 1, 18);
+ ExpectFailure("optional_uint64 {\n \n}\n", "Expected \":\", found \"{\".",
+ 1, 17);
+ ExpectFailure("optional_uint32: 0x100000000\n",
+ "Integer out of range.", 1, 18);
+ ExpectFailure("optional_uint64: 0x10000000000000000\n",
+ "Integer out of range.", 1, 18);
+
+ // Invalid values for a boolean field.
+ ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16);
+ ExpectFailure("optional_bool: 5\n", "Integer out of range.", 1, 16);
+ ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16);
+ ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16);
+
+ ExpectFailure(
+ "optional_bool: meh\n",
+ "Invalid value for boolean field \"optional_bool\". Value: \"meh\".",
+ 2, 1);
+
+ ExpectFailure("optional_bool {\n \n}\n", "Expected \":\", found \"{\".",
+ 1, 15);
+
+ // Invalid values for a string field.
+ ExpectFailure("optional_string: true\n", "Expected string.", 1, 18);
+ ExpectFailure("optional_string: 5\n", "Expected string.", 1, 18);
+ ExpectFailure("optional_string: -7.5\n", "Expected string.", 1, 18);
+ ExpectFailure("optional_string: !\n", "Expected string.", 1, 18);
+ ExpectFailure("optional_string {\n \n}\n", "Expected \":\", found \"{\".",
+ 1, 17);
+
+ // Invalid values for an enumeration field.
+ ExpectFailure("optional_nested_enum: \"hello\"\n",
+ "Expected integer or identifier.", 1, 23);
+
+ // Valid token, but enum value is not defined.
+ ExpectFailure("optional_nested_enum: 5\n",
+ "Unknown enumeration value of \"5\" for field "
+ "\"optional_nested_enum\".", 2, 1);
+ // We consume the negative sign, so the error position starts one character
+ // later.
+ ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24);
+ ExpectFailure("optional_nested_enum: !\n",
+ "Expected integer or identifier.", 1, 23);
+
+ ExpectFailure(
+ "optional_nested_enum: grah\n",
+ "Unknown enumeration value of \"grah\" for field "
+ "\"optional_nested_enum\".", 2, 1);
+
+ ExpectFailure(
+ "optional_nested_enum {\n \n}\n",
+ "Expected \":\", found \"{\".", 1, 22);
+}
+
+TEST_F(TextFormatParserTest, MessageDelimeters) {
+ // Non-matching delimeters.
+ ExpectFailure("OptionalGroup <\n \n}\n", "Expected \">\", found \"}\".",
+ 3, 1);
+
+ // Invalid delimeters.
+ ExpectFailure("OptionalGroup [\n \n]\n", "Expected \"{\", found \"[\".",
+ 1, 15);
+
+ // Unending message.
+ ExpectFailure("optional_nested_message {\n \nbb: 118\n",
+ "Expected identifier.",
+ 4, 1);
+}
+
+TEST_F(TextFormatParserTest, UnknownExtension) {
+ // Non-matching delimeters.
+ ExpectFailure("[blahblah]: 123",
+ "Extension \"blahblah\" is not defined or is not an "
+ "extension of \"protobuf_unittest.TestAllTypes\".",
+ 1, 11);
+}
+
+TEST_F(TextFormatParserTest, MissingRequired) {
+ unittest::TestRequired message;
+ ExpectFailure("a: 1",
+ "Message missing required fields: b, c",
+ 0, 1, &message);
+}
+
+TEST_F(TextFormatParserTest, ParseDuplicateRequired) {
+ unittest::TestRequired message;
+ ExpectFailure("a: 1 b: 2 c: 3 a: 1",
+ "Non-repeated field \"a\" is specified multiple times.",
+ 1, 17, &message);
+}
+
+TEST_F(TextFormatParserTest, ParseDuplicateOptional) {
+ unittest::ForeignMessage message;
+ ExpectFailure("c: 1 c: 2",
+ "Non-repeated field \"c\" is specified multiple times.",
+ 1, 7, &message);
+}
+
+TEST_F(TextFormatParserTest, MergeDuplicateRequired) {
+ unittest::TestRequired message;
+ TextFormat::Parser parser;
+ EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message));
+ EXPECT_EQ(4, message.a());
+}
+
+TEST_F(TextFormatParserTest, MergeDuplicateOptional) {
+ unittest::ForeignMessage message;
+ TextFormat::Parser parser;
+ EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message));
+ EXPECT_EQ(2, message.c());
+}
+
+TEST_F(TextFormatParserTest, ExplicitDelimiters) {
+ unittest::TestRequired message;
+ EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message));
+ EXPECT_EQ(1, message.a());
+ EXPECT_EQ(2, message.b());
+ EXPECT_EQ(3, message.c());
+}
+
+TEST_F(TextFormatParserTest, PrintErrorsToStderr) {
+ vector<string> errors;
+
+ {
+ ScopedMemoryLog log;
+ unittest::TestAllTypes proto;
+ EXPECT_FALSE(TextFormat::ParseFromString("no_such_field: 1", &proto));
+ errors = log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(1, errors.size());
+ EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
+ "1:14: Message type \"protobuf_unittest.TestAllTypes\" has no field "
+ "named \"no_such_field\".",
+ errors[0]);
+}
+
+TEST_F(TextFormatParserTest, FailsOnTokenizationError) {
+ vector<string> errors;
+
+ {
+ ScopedMemoryLog log;
+ unittest::TestAllTypes proto;
+ EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto));
+ errors = log.GetMessages(ERROR);
+ }
+
+ ASSERT_EQ(1, errors.size());
+ EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
+ "1:1: Invalid control characters encountered in text.",
+ errors[0]);
+}
+
+TEST_F(TextFormatParserTest, ParseDeprecatedField) {
+ unittest::TestDeprecatedFields message;
+ ExpectMessage("deprecated_int32: 42",
+ "WARNING:text format contains deprecated field "
+ "\"deprecated_int32\"", 1, 21, &message, true);
+}
+
+class TextFormatMessageSetTest : public testing::Test {
+ protected:
+ static const char proto_debug_string_[];
+};
+const char TextFormatMessageSetTest::proto_debug_string_[] =
+"message_set {\n"
+" [protobuf_unittest.TestMessageSetExtension1] {\n"
+" i: 23\n"
+" }\n"
+" [protobuf_unittest.TestMessageSetExtension2] {\n"
+" str: \"foo\"\n"
+" }\n"
+"}\n";
+
+
+TEST_F(TextFormatMessageSetTest, Serialize) {
+ protobuf_unittest::TestMessageSetContainer proto;
+ protobuf_unittest::TestMessageSetExtension1* item_a =
+ proto.mutable_message_set()->MutableExtension(
+ protobuf_unittest::TestMessageSetExtension1::message_set_extension);
+ item_a->set_i(23);
+ protobuf_unittest::TestMessageSetExtension2* item_b =
+ proto.mutable_message_set()->MutableExtension(
+ protobuf_unittest::TestMessageSetExtension2::message_set_extension);
+ item_b->set_str("foo");
+ EXPECT_EQ(proto_debug_string_, proto.DebugString());
+}
+
+TEST_F(TextFormatMessageSetTest, Deserialize) {
+ protobuf_unittest::TestMessageSetContainer proto;
+ ASSERT_TRUE(TextFormat::ParseFromString(proto_debug_string_, &proto));
+ EXPECT_EQ(23, proto.message_set().GetExtension(
+ protobuf_unittest::TestMessageSetExtension1::message_set_extension).i());
+ EXPECT_EQ("foo", proto.message_set().GetExtension(
+ protobuf_unittest::TestMessageSetExtension2::message_set_extension).str());
+
+ // Ensure that these are the only entries present.
+ vector<const FieldDescriptor*> descriptors;
+ proto.message_set().GetReflection()->ListFields(
+ proto.message_set(), &descriptors);
+ EXPECT_EQ(2, descriptors.size());
+}
+
+} // namespace text_format_unittest
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest.proto b/src/third_party/protobuf/src/google/protobuf/unittest.proto
new file mode 100644
index 0000000..97ec674
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest.proto
@@ -0,0 +1,630 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file we will use for unit testing.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true; // auto-added
+
+import "google/protobuf/unittest_import.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest;
+
+// Protos optimized for SPEED use a strict superset of the generated code
+// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
+// tests for speed unless explicitly testing code size optimization.
+option optimize_for = SPEED;
+
+option java_outer_classname = "UnittestProto";
+
+// This proto includes every type of field in both singular and repeated
+// forms.
+message TestAllTypes {
+ message NestedMessage {
+ // The field name "b" fails to compile in proto1 because it conflicts with
+ // a local variable named "b" in one of the generated methods. Doh.
+ // This file needs to compile in proto1 to test backwards-compatibility.
+ optional int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessage optional_foreign_message = 19;
+ optional protobuf_unittest_import.ImportMessage optional_import_message = 20;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnum optional_foreign_enum = 22;
+ optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
+
+ optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+ optional string optional_cord = 25 [ctype=CORD];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessage repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnum repeated_foreign_enum = 52;
+ repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ // Singular with defaults
+ optional int32 default_int32 = 61 [default = 41 ];
+ optional int64 default_int64 = 62 [default = 42 ];
+ optional uint32 default_uint32 = 63 [default = 43 ];
+ optional uint64 default_uint64 = 64 [default = 44 ];
+ optional sint32 default_sint32 = 65 [default = -45 ];
+ optional sint64 default_sint64 = 66 [default = 46 ];
+ optional fixed32 default_fixed32 = 67 [default = 47 ];
+ optional fixed64 default_fixed64 = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32 = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64 = 70 [default = -50 ];
+ optional float default_float = 71 [default = 51.5 ];
+ optional double default_double = 72 [default = 52e3 ];
+ optional bool default_bool = 73 [default = true ];
+ optional string default_string = 74 [default = "hello"];
+ optional bytes default_bytes = 75 [default = "world"];
+
+ optional NestedEnum default_nested_enum = 81 [default = BAR ];
+ optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
+ optional protobuf_unittest_import.ImportEnum
+ default_import_enum = 83 [default = IMPORT_BAR];
+
+ optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+ optional string default_cord = 85 [ctype=CORD,default="123"];
+}
+
+message TestDeprecatedFields {
+ optional int32 deprecated_int32 = 1 [deprecated=true];
+}
+
+// Define these after TestAllTypes to make sure the compiler can handle
+// that.
+message ForeignMessage {
+ optional int32 c = 1;
+}
+
+enum ForeignEnum {
+ FOREIGN_FOO = 4;
+ FOREIGN_BAR = 5;
+ FOREIGN_BAZ = 6;
+}
+
+message TestAllExtensions {
+ extensions 1 to max;
+}
+
+extend TestAllExtensions {
+ // Singular
+ optional int32 optional_int32_extension = 1;
+ optional int64 optional_int64_extension = 2;
+ optional uint32 optional_uint32_extension = 3;
+ optional uint64 optional_uint64_extension = 4;
+ optional sint32 optional_sint32_extension = 5;
+ optional sint64 optional_sint64_extension = 6;
+ optional fixed32 optional_fixed32_extension = 7;
+ optional fixed64 optional_fixed64_extension = 8;
+ optional sfixed32 optional_sfixed32_extension = 9;
+ optional sfixed64 optional_sfixed64_extension = 10;
+ optional float optional_float_extension = 11;
+ optional double optional_double_extension = 12;
+ optional bool optional_bool_extension = 13;
+ optional string optional_string_extension = 14;
+ optional bytes optional_bytes_extension = 15;
+
+ optional group OptionalGroup_extension = 16 {
+ optional int32 a = 17;
+ }
+
+ optional TestAllTypes.NestedMessage optional_nested_message_extension = 18;
+ optional ForeignMessage optional_foreign_message_extension = 19;
+ optional protobuf_unittest_import.ImportMessage
+ optional_import_message_extension = 20;
+
+ optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21;
+ optional ForeignEnum optional_foreign_enum_extension = 22;
+ optional protobuf_unittest_import.ImportEnum
+ optional_import_enum_extension = 23;
+
+ optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE];
+ optional string optional_cord_extension = 25 [ctype=CORD];
+
+ // Repeated
+ repeated int32 repeated_int32_extension = 31;
+ repeated int64 repeated_int64_extension = 32;
+ repeated uint32 repeated_uint32_extension = 33;
+ repeated uint64 repeated_uint64_extension = 34;
+ repeated sint32 repeated_sint32_extension = 35;
+ repeated sint64 repeated_sint64_extension = 36;
+ repeated fixed32 repeated_fixed32_extension = 37;
+ repeated fixed64 repeated_fixed64_extension = 38;
+ repeated sfixed32 repeated_sfixed32_extension = 39;
+ repeated sfixed64 repeated_sfixed64_extension = 40;
+ repeated float repeated_float_extension = 41;
+ repeated double repeated_double_extension = 42;
+ repeated bool repeated_bool_extension = 43;
+ repeated string repeated_string_extension = 44;
+ repeated bytes repeated_bytes_extension = 45;
+
+ repeated group RepeatedGroup_extension = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48;
+ repeated ForeignMessage repeated_foreign_message_extension = 49;
+ repeated protobuf_unittest_import.ImportMessage
+ repeated_import_message_extension = 50;
+
+ repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51;
+ repeated ForeignEnum repeated_foreign_enum_extension = 52;
+ repeated protobuf_unittest_import.ImportEnum
+ repeated_import_enum_extension = 53;
+
+ repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord_extension = 55 [ctype=CORD];
+
+ // Singular with defaults
+ optional int32 default_int32_extension = 61 [default = 41 ];
+ optional int64 default_int64_extension = 62 [default = 42 ];
+ optional uint32 default_uint32_extension = 63 [default = 43 ];
+ optional uint64 default_uint64_extension = 64 [default = 44 ];
+ optional sint32 default_sint32_extension = 65 [default = -45 ];
+ optional sint64 default_sint64_extension = 66 [default = 46 ];
+ optional fixed32 default_fixed32_extension = 67 [default = 47 ];
+ optional fixed64 default_fixed64_extension = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32_extension = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64_extension = 70 [default = -50 ];
+ optional float default_float_extension = 71 [default = 51.5 ];
+ optional double default_double_extension = 72 [default = 52e3 ];
+ optional bool default_bool_extension = 73 [default = true ];
+ optional string default_string_extension = 74 [default = "hello"];
+ optional bytes default_bytes_extension = 75 [default = "world"];
+
+ optional TestAllTypes.NestedEnum
+ default_nested_enum_extension = 81 [default = BAR];
+ optional ForeignEnum
+ default_foreign_enum_extension = 82 [default = FOREIGN_BAR];
+ optional protobuf_unittest_import.ImportEnum
+ default_import_enum_extension = 83 [default = IMPORT_BAR];
+
+ optional string default_string_piece_extension = 84 [ctype=STRING_PIECE,
+ default="abc"];
+ optional string default_cord_extension = 85 [ctype=CORD, default="123"];
+}
+
+message TestNestedExtension {
+ extend TestAllExtensions {
+ // Check for bug where string extensions declared in tested scope did not
+ // compile.
+ optional string test = 1002 [default="test"];
+ }
+}
+
+// We have separate messages for testing required fields because it's
+// annoying to have to fill in required fields in TestProto in order to
+// do anything with it. Note that we don't need to test every type of
+// required filed because the code output is basically identical to
+// optional fields for all types.
+message TestRequired {
+ required int32 a = 1;
+ optional int32 dummy2 = 2;
+ required int32 b = 3;
+
+ extend TestAllExtensions {
+ optional TestRequired single = 1000;
+ repeated TestRequired multi = 1001;
+ }
+
+ // Pad the field count to 32 so that we can test that IsInitialized()
+ // properly checks multiple elements of has_bits_.
+ optional int32 dummy4 = 4;
+ optional int32 dummy5 = 5;
+ optional int32 dummy6 = 6;
+ optional int32 dummy7 = 7;
+ optional int32 dummy8 = 8;
+ optional int32 dummy9 = 9;
+ optional int32 dummy10 = 10;
+ optional int32 dummy11 = 11;
+ optional int32 dummy12 = 12;
+ optional int32 dummy13 = 13;
+ optional int32 dummy14 = 14;
+ optional int32 dummy15 = 15;
+ optional int32 dummy16 = 16;
+ optional int32 dummy17 = 17;
+ optional int32 dummy18 = 18;
+ optional int32 dummy19 = 19;
+ optional int32 dummy20 = 20;
+ optional int32 dummy21 = 21;
+ optional int32 dummy22 = 22;
+ optional int32 dummy23 = 23;
+ optional int32 dummy24 = 24;
+ optional int32 dummy25 = 25;
+ optional int32 dummy26 = 26;
+ optional int32 dummy27 = 27;
+ optional int32 dummy28 = 28;
+ optional int32 dummy29 = 29;
+ optional int32 dummy30 = 30;
+ optional int32 dummy31 = 31;
+ optional int32 dummy32 = 32;
+
+ required int32 c = 33;
+}
+
+message TestRequiredForeign {
+ optional TestRequired optional_message = 1;
+ repeated TestRequired repeated_message = 2;
+ optional int32 dummy = 3;
+}
+
+// Test that we can use NestedMessage from outside TestAllTypes.
+message TestForeignNested {
+ optional TestAllTypes.NestedMessage foreign_nested = 1;
+}
+
+// TestEmptyMessage is used to test unknown field support.
+message TestEmptyMessage {
+}
+
+// Like above, but declare all field numbers as potential extensions. No
+// actual extensions should ever be defined for this type.
+message TestEmptyMessageWithExtensions {
+ extensions 1 to max;
+}
+
+message TestMultipleExtensionRanges {
+ extensions 42;
+ extensions 4143 to 4243;
+ extensions 65536 to max;
+}
+
+// Test that really large tag numbers don't break anything.
+message TestReallyLargeTagNumber {
+ // The largest possible tag number is 2^28 - 1, since the wire format uses
+ // three bits to communicate wire type.
+ optional int32 a = 1;
+ optional int32 bb = 268435455;
+}
+
+message TestRecursiveMessage {
+ optional TestRecursiveMessage a = 1;
+ optional int32 i = 2;
+}
+
+// Test that mutual recursion works.
+message TestMutualRecursionA {
+ optional TestMutualRecursionB bb = 1;
+}
+
+message TestMutualRecursionB {
+ optional TestMutualRecursionA a = 1;
+ optional int32 optional_int32 = 2;
+}
+
+// Test that groups have disjoint field numbers from their siblings and
+// parents. This is NOT possible in proto1; only proto2. When attempting
+// to compile with proto1, this will emit an error; so we only include it
+// in protobuf_unittest_proto.
+message TestDupFieldNumber { // NO_PROTO1
+ optional int32 a = 1; // NO_PROTO1
+ optional group Foo = 2 { optional int32 a = 1; } // NO_PROTO1
+ optional group Bar = 3 { optional int32 a = 1; } // NO_PROTO1
+} // NO_PROTO1
+
+
+// Needed for a Python test.
+message TestNestedMessageHasBits {
+ message NestedMessage {
+ repeated int32 nestedmessage_repeated_int32 = 1;
+ repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2;
+ }
+ optional NestedMessage optional_nested_message = 1;
+}
+
+
+// Test an enum that has multiple values with the same number.
+enum TestEnumWithDupValue {
+ FOO1 = 1;
+ BAR1 = 2;
+ BAZ = 3;
+ FOO2 = 1;
+ BAR2 = 2;
+}
+
+// Test an enum with large, unordered values.
+enum TestSparseEnum {
+ SPARSE_A = 123;
+ SPARSE_B = 62374;
+ SPARSE_C = 12589234;
+ SPARSE_D = -15;
+ SPARSE_E = -53452;
+ SPARSE_F = 0;
+ SPARSE_G = 2;
+}
+
+// Test message with CamelCase field names. This violates Protocol Buffer
+// standard style.
+message TestCamelCaseFieldNames {
+ optional int32 PrimitiveField = 1;
+ optional string StringField = 2;
+ optional ForeignEnum EnumField = 3;
+ optional ForeignMessage MessageField = 4;
+ optional string StringPieceField = 5 [ctype=STRING_PIECE];
+ optional string CordField = 6 [ctype=CORD];
+
+ repeated int32 RepeatedPrimitiveField = 7;
+ repeated string RepeatedStringField = 8;
+ repeated ForeignEnum RepeatedEnumField = 9;
+ repeated ForeignMessage RepeatedMessageField = 10;
+ repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE];
+ repeated string RepeatedCordField = 12 [ctype=CORD];
+}
+
+
+// We list fields out of order, to ensure that we're using field number and not
+// field index to determine serialization order.
+message TestFieldOrderings {
+ optional string my_string = 11;
+ extensions 2 to 10;
+ optional int64 my_int = 1;
+ extensions 12 to 100;
+ optional float my_float = 101;
+}
+
+
+extend TestFieldOrderings {
+ optional string my_extension_string = 50;
+ optional int32 my_extension_int = 5;
+}
+
+
+message TestExtremeDefaultValues {
+ optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"];
+ optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF];
+ optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF];
+ optional int32 small_int32 = 4 [default = -0x7FFFFFFF];
+ optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF];
+
+ // The default value here is UTF-8 for "\u1234". (We could also just type
+ // the UTF-8 text directly into this text file rather than escape it, but
+ // lots of people use editors that would be confused by this.)
+ optional string utf8_string = 6 [default = "\341\210\264"];
+
+ // Tests for single-precision floating-point values.
+ optional float zero_float = 7 [default = 0];
+ optional float one_float = 8 [default = 1];
+ optional float small_float = 9 [default = 1.5];
+ optional float negative_one_float = 10 [default = -1];
+ optional float negative_float = 11 [default = -1.5];
+ // Using exponents
+ optional float large_float = 12 [default = 2E8];
+ optional float small_negative_float = 13 [default = -8e-28];
+
+ // Text for nonfinite floating-point values.
+ optional double inf_double = 14 [default = inf];
+ optional double neg_inf_double = 15 [default = -inf];
+ optional double nan_double = 16 [default = nan];
+ optional float inf_float = 17 [default = inf];
+ optional float neg_inf_float = 18 [default = -inf];
+ optional float nan_float = 19 [default = nan];
+
+ // Tests for C++ trigraphs.
+ // Trigraphs should be escaped in C++ generated files, but they should not be
+ // escaped for other languages.
+ // Note that in .proto file, "\?" is a valid way to escape ? in string
+ // literals.
+ optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"];
+}
+
+message SparseEnumMessage {
+ optional TestSparseEnum sparse_enum = 1;
+}
+
+// Test String and Bytes: string is for valid UTF-8 strings
+message OneString {
+ optional string data = 1;
+}
+
+message OneBytes {
+ optional bytes data = 1;
+}
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnum packed_enum = 103 [packed = true];
+}
+
+// A message with the same fields as TestPackedTypes, but without packing. Used
+// to test packed <-> unpacked wire compatibility.
+message TestUnpackedTypes {
+ repeated int32 unpacked_int32 = 90 [packed = false];
+ repeated int64 unpacked_int64 = 91 [packed = false];
+ repeated uint32 unpacked_uint32 = 92 [packed = false];
+ repeated uint64 unpacked_uint64 = 93 [packed = false];
+ repeated sint32 unpacked_sint32 = 94 [packed = false];
+ repeated sint64 unpacked_sint64 = 95 [packed = false];
+ repeated fixed32 unpacked_fixed32 = 96 [packed = false];
+ repeated fixed64 unpacked_fixed64 = 97 [packed = false];
+ repeated sfixed32 unpacked_sfixed32 = 98 [packed = false];
+ repeated sfixed64 unpacked_sfixed64 = 99 [packed = false];
+ repeated float unpacked_float = 100 [packed = false];
+ repeated double unpacked_double = 101 [packed = false];
+ repeated bool unpacked_bool = 102 [packed = false];
+ repeated ForeignEnum unpacked_enum = 103 [packed = false];
+}
+
+message TestPackedExtensions {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensions {
+ repeated int32 packed_int32_extension = 90 [packed = true];
+ repeated int64 packed_int64_extension = 91 [packed = true];
+ repeated uint32 packed_uint32_extension = 92 [packed = true];
+ repeated uint64 packed_uint64_extension = 93 [packed = true];
+ repeated sint32 packed_sint32_extension = 94 [packed = true];
+ repeated sint64 packed_sint64_extension = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension = 99 [packed = true];
+ repeated float packed_float_extension = 100 [packed = true];
+ repeated double packed_double_extension = 101 [packed = true];
+ repeated bool packed_bool_extension = 102 [packed = true];
+ repeated ForeignEnum packed_enum_extension = 103 [packed = true];
+}
+
+// Used by ExtensionSetTest/DynamicExtensions. The test actually builds
+// a set of extensions to TestAllExtensions dynamically, based on the fields
+// of this message type.
+message TestDynamicExtensions {
+ enum DynamicEnumType {
+ DYNAMIC_FOO = 2200;
+ DYNAMIC_BAR = 2201;
+ DYNAMIC_BAZ = 2202;
+ }
+ message DynamicMessageType {
+ optional int32 dynamic_field = 2100;
+ }
+
+ optional fixed32 scalar_extension = 2000;
+ optional ForeignEnum enum_extension = 2001;
+ optional DynamicEnumType dynamic_enum_extension = 2002;
+
+ optional ForeignMessage message_extension = 2003;
+ optional DynamicMessageType dynamic_message_extension = 2004;
+
+ repeated string repeated_extension = 2005;
+ repeated sint32 packed_extension = 2006 [packed = true];
+}
+
+message TestRepeatedScalarDifferentTagSizes {
+ // Parsing repeated fixed size values used to fail. This message needs to be
+ // used in order to get a tag of the right size; all of the repeated fields
+ // in TestAllTypes didn't trigger the check.
+ repeated fixed32 repeated_fixed32 = 12;
+ // Check for a varint type, just for good measure.
+ repeated int32 repeated_int32 = 13;
+
+ // These have two-byte tags.
+ repeated fixed64 repeated_fixed64 = 2046;
+ repeated int64 repeated_int64 = 2047;
+
+ // Three byte tags.
+ repeated float repeated_float = 262142;
+ repeated uint64 repeated_uint64 = 262143;
+}
+
+
+// Test that RPC services work.
+message FooRequest {}
+message FooResponse {}
+
+service TestService {
+ rpc Foo(FooRequest) returns (FooResponse);
+ rpc Bar(BarRequest) returns (BarResponse);
+}
+
+
+message BarRequest {}
+message BarResponse {}
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_custom_options.proto b/src/third_party/protobuf/src/google/protobuf/unittest_custom_options.proto
new file mode 100644
index 0000000..a610785
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_custom_options.proto
@@ -0,0 +1,366 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: benjy@google.com (Benjy Weinberger)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file used to test the "custom options" feature of proto2.
+
+
+// Some generic_services option(s) added automatically.
+// See: http://go/proto2-generic-services-default
+option cc_generic_services = true; // auto-added
+option java_generic_services = true; // auto-added
+option py_generic_services = true;
+
+// A custom file option (defined below).
+option (file_opt1) = 9876543210;
+
+import "google/protobuf/descriptor.proto";
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+package protobuf_unittest;
+
+
+// Some simple test custom options of various types.
+
+extend google.protobuf.FileOptions {
+ optional uint64 file_opt1 = 7736974;
+}
+
+extend google.protobuf.MessageOptions {
+ optional int32 message_opt1 = 7739036;
+}
+
+extend google.protobuf.FieldOptions {
+ optional fixed64 field_opt1 = 7740936;
+ // This is useful for testing that we correctly register default values for
+ // extension options.
+ optional int32 field_opt2 = 7753913 [default=42];
+}
+
+extend google.protobuf.EnumOptions {
+ optional sfixed32 enum_opt1 = 7753576;
+}
+
+extend google.protobuf.EnumValueOptions {
+ optional int32 enum_value_opt1 = 1560678;
+}
+
+extend google.protobuf.ServiceOptions {
+ optional sint64 service_opt1 = 7887650;
+}
+
+enum MethodOpt1 {
+ METHODOPT1_VAL1 = 1;
+ METHODOPT1_VAL2 = 2;
+}
+
+extend google.protobuf.MethodOptions {
+ optional MethodOpt1 method_opt1 = 7890860;
+}
+
+// A test message with custom options at all possible locations (and also some
+// regular options, to make sure they interact nicely).
+message TestMessageWithCustomOptions {
+ option message_set_wire_format = false;
+
+ option (message_opt1) = -56;
+
+ optional string field1 = 1 [ctype=CORD,
+ (field_opt1)=8765432109];
+
+ enum AnEnum {
+ option (enum_opt1) = -789;
+
+ ANENUM_VAL1 = 1;
+ ANENUM_VAL2 = 2 [(enum_value_opt1) = 123];
+ }
+}
+
+
+// A test RPC service with custom options at all possible locations (and also
+// some regular options, to make sure they interact nicely).
+message CustomOptionFooRequest {
+}
+
+message CustomOptionFooResponse {
+}
+
+service TestServiceWithCustomOptions {
+ option (service_opt1) = -9876543210;
+
+ rpc Foo(CustomOptionFooRequest) returns (CustomOptionFooResponse) {
+ option (method_opt1) = METHODOPT1_VAL2;
+ }
+}
+
+
+
+// Options of every possible field type, so we can test them all exhaustively.
+
+message DummyMessageContainingEnum {
+ enum TestEnumType {
+ TEST_OPTION_ENUM_TYPE1 = 22;
+ TEST_OPTION_ENUM_TYPE2 = -23;
+ }
+}
+
+message DummyMessageInvalidAsOptionType {
+}
+
+extend google.protobuf.MessageOptions {
+ optional bool bool_opt = 7706090;
+ optional int32 int32_opt = 7705709;
+ optional int64 int64_opt = 7705542;
+ optional uint32 uint32_opt = 7704880;
+ optional uint64 uint64_opt = 7702367;
+ optional sint32 sint32_opt = 7701568;
+ optional sint64 sint64_opt = 7700863;
+ optional fixed32 fixed32_opt = 7700307;
+ optional fixed64 fixed64_opt = 7700194;
+ optional sfixed32 sfixed32_opt = 7698645;
+ optional sfixed64 sfixed64_opt = 7685475;
+ optional float float_opt = 7675390;
+ optional double double_opt = 7673293;
+ optional string string_opt = 7673285;
+ optional bytes bytes_opt = 7673238;
+ optional DummyMessageContainingEnum.TestEnumType enum_opt = 7673233;
+ optional DummyMessageInvalidAsOptionType message_type_opt = 7665967;
+}
+
+message CustomOptionMinIntegerValues {
+ option (bool_opt) = false;
+ option (int32_opt) = -0x80000000;
+ option (int64_opt) = -0x8000000000000000;
+ option (uint32_opt) = 0;
+ option (uint64_opt) = 0;
+ option (sint32_opt) = -0x80000000;
+ option (sint64_opt) = -0x8000000000000000;
+ option (fixed32_opt) = 0;
+ option (fixed64_opt) = 0;
+ option (sfixed32_opt) = -0x80000000;
+ option (sfixed64_opt) = -0x8000000000000000;
+}
+
+message CustomOptionMaxIntegerValues {
+ option (bool_opt) = true;
+ option (int32_opt) = 0x7FFFFFFF;
+ option (int64_opt) = 0x7FFFFFFFFFFFFFFF;
+ option (uint32_opt) = 0xFFFFFFFF;
+ option (uint64_opt) = 0xFFFFFFFFFFFFFFFF;
+ option (sint32_opt) = 0x7FFFFFFF;
+ option (sint64_opt) = 0x7FFFFFFFFFFFFFFF;
+ option (fixed32_opt) = 0xFFFFFFFF;
+ option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF;
+ option (sfixed32_opt) = 0x7FFFFFFF;
+ option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF;
+}
+
+message CustomOptionOtherValues {
+ option (int32_opt) = -100; // To test sign-extension.
+ option (float_opt) = 12.3456789;
+ option (double_opt) = 1.234567890123456789;
+ option (string_opt) = "Hello, \"World\"";
+ option (bytes_opt) = "Hello\0World";
+ option (enum_opt) = TEST_OPTION_ENUM_TYPE2;
+}
+
+message SettingRealsFromPositiveInts {
+ option (float_opt) = 12;
+ option (double_opt) = 154;
+}
+
+message SettingRealsFromNegativeInts {
+ option (float_opt) = -12;
+ option (double_opt) = -154;
+}
+
+// Options of complex message types, themselves combined and extended in
+// various ways.
+
+message ComplexOptionType1 {
+ optional int32 foo = 1;
+ optional int32 foo2 = 2;
+ optional int32 foo3 = 3;
+
+ extensions 100 to max;
+}
+
+message ComplexOptionType2 {
+ optional ComplexOptionType1 bar = 1;
+ optional int32 baz = 2;
+
+ message ComplexOptionType4 {
+ optional int32 waldo = 1;
+
+ extend google.protobuf.MessageOptions {
+ optional ComplexOptionType4 complex_opt4 = 7633546;
+ }
+ }
+
+ optional ComplexOptionType4 fred = 3;
+
+ extensions 100 to max;
+}
+
+message ComplexOptionType3 {
+ optional int32 qux = 1;
+
+ optional group ComplexOptionType5 = 2 {
+ optional int32 plugh = 3;
+ }
+}
+
+extend ComplexOptionType1 {
+ optional int32 quux = 7663707;
+ optional ComplexOptionType3 corge = 7663442;
+}
+
+extend ComplexOptionType2 {
+ optional int32 grault = 7650927;
+ optional ComplexOptionType1 garply = 7649992;
+}
+
+extend google.protobuf.MessageOptions {
+ optional protobuf_unittest.ComplexOptionType1 complex_opt1 = 7646756;
+ optional ComplexOptionType2 complex_opt2 = 7636949;
+ optional ComplexOptionType3 complex_opt3 = 7636463;
+ optional group ComplexOpt6 = 7595468 {
+ optional int32 xyzzy = 7593951;
+ }
+}
+
+// Note that we try various different ways of naming the same extension.
+message VariousComplexOptions {
+ option (.protobuf_unittest.complex_opt1).foo = 42;
+ option (protobuf_unittest.complex_opt1).(.protobuf_unittest.quux) = 324;
+ option (.protobuf_unittest.complex_opt1).(protobuf_unittest.corge).qux = 876;
+ option (complex_opt2).baz = 987;
+ option (complex_opt2).(grault) = 654;
+ option (complex_opt2).bar.foo = 743;
+ option (complex_opt2).bar.(quux) = 1999;
+ option (complex_opt2).bar.(protobuf_unittest.corge).qux = 2008;
+ option (complex_opt2).(garply).foo = 741;
+ option (complex_opt2).(garply).(.protobuf_unittest.quux) = 1998;
+ option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121;
+ option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971;
+ option (complex_opt2).fred.waldo = 321;
+ option (protobuf_unittest.complex_opt3).qux = 9;
+ option (complex_opt3).complexoptiontype5.plugh = 22;
+ option (complexopt6).xyzzy = 24;
+}
+
+// ------------------------------------------------------
+// Definitions for testing aggregate option parsing.
+// See descriptor_unittest.cc.
+
+message AggregateMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message AggregateMessageSetElement {
+ extend AggregateMessageSet {
+ optional AggregateMessageSetElement message_set_extension = 15447542;
+ }
+ optional string s = 1;
+}
+
+// A helper type used to test aggregate option parsing
+message Aggregate {
+ optional int32 i = 1;
+ optional string s = 2;
+
+ // A nested object
+ optional Aggregate sub = 3;
+
+ // To test the parsing of extensions inside aggregate values
+ optional google.protobuf.FileOptions file = 4;
+ extend google.protobuf.FileOptions {
+ optional Aggregate nested = 15476903;
+ }
+
+ // An embedded message set
+ optional AggregateMessageSet mset = 5;
+}
+
+// Allow Aggregate to be used as an option at all possible locations
+// in the .proto grammer.
+extend google.protobuf.FileOptions { optional Aggregate fileopt = 15478479; }
+extend google.protobuf.MessageOptions { optional Aggregate msgopt = 15480088; }
+extend google.protobuf.FieldOptions { optional Aggregate fieldopt = 15481374; }
+extend google.protobuf.EnumOptions { optional Aggregate enumopt = 15483218; }
+extend google.protobuf.EnumValueOptions { optional Aggregate enumvalopt = 15486921; }
+extend google.protobuf.ServiceOptions { optional Aggregate serviceopt = 15497145; }
+extend google.protobuf.MethodOptions { optional Aggregate methodopt = 15512713; }
+
+// Try using AggregateOption at different points in the proto grammar
+option (fileopt) = {
+ s: 'FileAnnotation'
+ // Also test the handling of comments
+ /* of both types */ i: 100
+
+ sub { s: 'NestedFileAnnotation' }
+
+ // Include a google.protobuf.FileOptions and recursively extend it with
+ // another fileopt.
+ file {
+ [protobuf_unittest.fileopt] {
+ s:'FileExtensionAnnotation'
+ }
+ }
+
+ // A message set inside an option value
+ mset {
+ [protobuf_unittest.AggregateMessageSetElement.message_set_extension] {
+ s: 'EmbeddedMessageSetElement'
+ }
+ }
+};
+
+message AggregateMessage {
+ option (msgopt) = { i:101 s:'MessageAnnotation' };
+ optional int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }];
+}
+
+service AggregateService {
+ option (serviceopt) = { s:'ServiceAnnotation' };
+ rpc Method (AggregateMessage) returns (AggregateMessage) {
+ option (methodopt) = { s:'MethodAnnotation' };
+ }
+}
+
+enum AggregateEnum {
+ option (enumopt) = { s:'EnumAnnotation' };
+ VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }];
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_embed_optimize_for.proto b/src/third_party/protobuf/src/google/protobuf/unittest_embed_optimize_for.proto
new file mode 100644
index 0000000..fa17625
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_embed_optimize_for.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which imports a proto file that uses optimize_for = CODE_SIZE.
+
+import "google/protobuf/unittest_optimize_for.proto";
+
+package protobuf_unittest;
+
+// We optimize for speed here, but we are importing a proto that is optimized
+// for code size.
+option optimize_for = SPEED;
+
+message TestEmbedOptimizedForSize {
+ // Test that embedding a message which has optimize_for = CODE_SIZE into
+ // one optimized for speed works.
+ optional TestOptimizedForSize optional_message = 1;
+ repeated TestOptimizedForSize repeated_message = 2;
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_empty.proto b/src/third_party/protobuf/src/google/protobuf/unittest_empty.proto
new file mode 100644
index 0000000..ab12d1f
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_empty.proto
@@ -0,0 +1,37 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file intentionally left blank. (At one point this wouldn't compile
+// correctly.)
+
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_enormous_descriptor.proto b/src/third_party/protobuf/src/google/protobuf/unittest_enormous_descriptor.proto
new file mode 100644
index 0000000..bc0b7c1
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_enormous_descriptor.proto
@@ -0,0 +1,1046 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file that has an extremely large descriptor. Used to test that
+// descriptors over 64k don't break the string literal length limit in Java.
+
+
+package google.protobuf;
+option java_package = "com.google.protobuf";
+
+// Avoid generating insanely long methods.
+option optimize_for = CODE_SIZE;
+
+message TestEnormousDescriptor {
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1 = 1 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_2 = 2 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_3 = 3 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_4 = 4 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_5 = 5 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_6 = 6 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_7 = 7 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_8 = 8 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_9 = 9 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_10 = 10 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_11 = 11 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_12 = 12 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_13 = 13 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_14 = 14 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_15 = 15 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_16 = 16 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_17 = 17 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_18 = 18 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_19 = 19 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_20 = 20 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_21 = 21 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_22 = 22 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_23 = 23 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_24 = 24 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_25 = 25 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_26 = 26 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_27 = 27 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_28 = 28 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_29 = 29 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_30 = 30 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_31 = 31 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_32 = 32 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_33 = 33 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_34 = 34 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_35 = 35 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_36 = 36 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_37 = 37 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_38 = 38 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_39 = 39 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_40 = 40 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_41 = 41 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_42 = 42 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_43 = 43 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_44 = 44 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_45 = 45 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_46 = 46 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_47 = 47 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_48 = 48 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_49 = 49 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_50 = 50 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_51 = 51 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_52 = 52 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_53 = 53 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_54 = 54 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_55 = 55 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_56 = 56 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_57 = 57 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_58 = 58 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_59 = 59 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_60 = 60 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_61 = 61 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_62 = 62 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_63 = 63 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_64 = 64 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_65 = 65 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_66 = 66 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_67 = 67 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_68 = 68 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_69 = 69 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_70 = 70 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_71 = 71 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_72 = 72 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_73 = 73 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_74 = 74 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_75 = 75 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_76 = 76 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_77 = 77 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_78 = 78 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_79 = 79 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_80 = 80 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_81 = 81 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_82 = 82 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_83 = 83 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_84 = 84 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_85 = 85 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_86 = 86 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_87 = 87 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_88 = 88 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_89 = 89 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_90 = 90 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_91 = 91 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_92 = 92 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_93 = 93 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_94 = 94 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_95 = 95 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_96 = 96 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_97 = 97 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_98 = 98 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_99 = 99 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_100 = 100 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_101 = 101 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_102 = 102 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_103 = 103 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_104 = 104 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_105 = 105 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_106 = 106 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_107 = 107 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_108 = 108 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_109 = 109 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_110 = 110 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_111 = 111 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_112 = 112 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_113 = 113 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_114 = 114 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_115 = 115 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_116 = 116 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_117 = 117 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_118 = 118 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_119 = 119 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_120 = 120 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_121 = 121 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_122 = 122 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_123 = 123 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_124 = 124 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_125 = 125 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_126 = 126 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_127 = 127 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_128 = 128 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_129 = 129 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_130 = 130 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_131 = 131 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_132 = 132 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_133 = 133 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_134 = 134 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_135 = 135 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_136 = 136 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_137 = 137 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_138 = 138 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_139 = 139 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_140 = 140 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_141 = 141 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_142 = 142 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_143 = 143 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_144 = 144 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_145 = 145 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_146 = 146 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_147 = 147 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_148 = 148 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_149 = 149 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_150 = 150 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_151 = 151 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_152 = 152 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_153 = 153 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_154 = 154 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_155 = 155 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_156 = 156 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_157 = 157 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_158 = 158 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_159 = 159 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_160 = 160 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_161 = 161 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_162 = 162 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_163 = 163 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_164 = 164 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_165 = 165 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_166 = 166 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_167 = 167 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_168 = 168 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_169 = 169 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_170 = 170 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_171 = 171 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_172 = 172 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_173 = 173 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_174 = 174 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_175 = 175 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_176 = 176 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_177 = 177 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_178 = 178 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_179 = 179 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_180 = 180 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_181 = 181 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_182 = 182 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_183 = 183 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_184 = 184 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_185 = 185 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_186 = 186 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_187 = 187 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_188 = 188 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_189 = 189 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_190 = 190 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_191 = 191 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_192 = 192 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_193 = 193 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_194 = 194 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_195 = 195 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_196 = 196 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_197 = 197 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_198 = 198 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_199 = 199 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_200 = 200 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_201 = 201 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_202 = 202 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_203 = 203 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_204 = 204 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_205 = 205 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_206 = 206 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_207 = 207 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_208 = 208 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_209 = 209 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_210 = 210 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_211 = 211 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_212 = 212 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_213 = 213 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_214 = 214 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_215 = 215 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_216 = 216 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_217 = 217 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_218 = 218 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_219 = 219 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_220 = 220 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_221 = 221 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_222 = 222 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_223 = 223 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_224 = 224 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_225 = 225 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_226 = 226 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_227 = 227 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_228 = 228 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_229 = 229 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_230 = 230 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_231 = 231 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_232 = 232 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_233 = 233 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_234 = 234 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_235 = 235 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_236 = 236 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_237 = 237 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_238 = 238 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_239 = 239 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_240 = 240 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_241 = 241 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_242 = 242 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_243 = 243 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_244 = 244 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_245 = 245 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_246 = 246 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_247 = 247 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_248 = 248 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_249 = 249 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_250 = 250 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_251 = 251 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_252 = 252 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_253 = 253 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_254 = 254 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_255 = 255 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_256 = 256 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_257 = 257 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_258 = 258 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_259 = 259 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_260 = 260 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_261 = 261 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_262 = 262 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_263 = 263 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_264 = 264 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_265 = 265 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_266 = 266 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_267 = 267 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_268 = 268 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_269 = 269 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_270 = 270 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_271 = 271 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_272 = 272 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_273 = 273 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_274 = 274 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_275 = 275 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_276 = 276 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_277 = 277 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_278 = 278 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_279 = 279 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_280 = 280 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_281 = 281 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_282 = 282 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_283 = 283 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_284 = 284 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_285 = 285 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_286 = 286 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_287 = 287 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_288 = 288 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_289 = 289 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_290 = 290 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_291 = 291 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_292 = 292 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_293 = 293 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_294 = 294 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_295 = 295 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_296 = 296 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_297 = 297 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_298 = 298 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_299 = 299 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_300 = 300 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_301 = 301 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_302 = 302 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_303 = 303 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_304 = 304 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_305 = 305 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_306 = 306 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_307 = 307 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_308 = 308 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_309 = 309 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_310 = 310 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_311 = 311 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_312 = 312 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_313 = 313 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_314 = 314 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_315 = 315 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_316 = 316 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_317 = 317 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_318 = 318 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_319 = 319 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_320 = 320 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_321 = 321 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_322 = 322 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_323 = 323 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_324 = 324 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_325 = 325 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_326 = 326 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_327 = 327 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_328 = 328 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_329 = 329 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_330 = 330 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_331 = 331 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_332 = 332 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_333 = 333 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_334 = 334 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_335 = 335 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_336 = 336 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_337 = 337 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_338 = 338 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_339 = 339 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_340 = 340 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_341 = 341 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_342 = 342 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_343 = 343 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_344 = 344 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_345 = 345 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_346 = 346 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_347 = 347 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_348 = 348 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_349 = 349 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_350 = 350 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_351 = 351 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_352 = 352 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_353 = 353 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_354 = 354 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_355 = 355 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_356 = 356 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_357 = 357 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_358 = 358 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_359 = 359 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_360 = 360 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_361 = 361 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_362 = 362 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_363 = 363 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_364 = 364 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_365 = 365 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_366 = 366 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_367 = 367 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_368 = 368 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_369 = 369 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_370 = 370 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_371 = 371 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_372 = 372 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_373 = 373 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_374 = 374 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_375 = 375 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_376 = 376 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_377 = 377 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_378 = 378 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_379 = 379 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_380 = 380 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_381 = 381 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_382 = 382 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_383 = 383 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_384 = 384 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_385 = 385 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_386 = 386 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_387 = 387 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_388 = 388 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_389 = 389 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_390 = 390 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_391 = 391 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_392 = 392 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_393 = 393 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_394 = 394 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_395 = 395 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_396 = 396 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_397 = 397 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_398 = 398 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_399 = 399 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_400 = 400 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_401 = 401 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_402 = 402 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_403 = 403 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_404 = 404 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_405 = 405 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_406 = 406 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_407 = 407 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_408 = 408 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_409 = 409 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_410 = 410 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_411 = 411 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_412 = 412 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_413 = 413 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_414 = 414 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_415 = 415 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_416 = 416 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_417 = 417 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_418 = 418 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_419 = 419 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_420 = 420 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_421 = 421 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_422 = 422 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_423 = 423 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_424 = 424 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_425 = 425 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_426 = 426 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_427 = 427 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_428 = 428 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_429 = 429 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_430 = 430 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_431 = 431 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_432 = 432 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_433 = 433 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_434 = 434 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_435 = 435 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_436 = 436 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_437 = 437 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_438 = 438 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_439 = 439 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_440 = 440 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_441 = 441 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_442 = 442 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_443 = 443 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_444 = 444 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_445 = 445 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_446 = 446 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_447 = 447 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_448 = 448 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_449 = 449 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_450 = 450 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_451 = 451 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_452 = 452 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_453 = 453 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_454 = 454 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_455 = 455 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_456 = 456 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_457 = 457 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_458 = 458 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_459 = 459 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_460 = 460 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_461 = 461 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_462 = 462 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_463 = 463 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_464 = 464 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_465 = 465 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_466 = 466 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_467 = 467 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_468 = 468 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_469 = 469 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_470 = 470 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_471 = 471 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_472 = 472 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_473 = 473 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_474 = 474 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_475 = 475 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_476 = 476 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_477 = 477 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_478 = 478 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_479 = 479 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_480 = 480 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_481 = 481 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_482 = 482 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_483 = 483 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_484 = 484 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_485 = 485 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_486 = 486 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_487 = 487 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_488 = 488 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_489 = 489 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_490 = 490 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_491 = 491 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_492 = 492 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_493 = 493 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_494 = 494 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_495 = 495 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_496 = 496 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_497 = 497 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_498 = 498 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_499 = 499 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_500 = 500 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_501 = 501 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_502 = 502 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_503 = 503 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_504 = 504 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_505 = 505 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_506 = 506 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_507 = 507 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_508 = 508 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_509 = 509 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_510 = 510 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_511 = 511 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_512 = 512 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_513 = 513 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_514 = 514 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_515 = 515 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_516 = 516 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_517 = 517 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_518 = 518 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_519 = 519 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_520 = 520 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_521 = 521 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_522 = 522 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_523 = 523 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_524 = 524 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_525 = 525 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_526 = 526 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_527 = 527 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_528 = 528 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_529 = 529 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_530 = 530 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_531 = 531 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_532 = 532 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_533 = 533 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_534 = 534 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_535 = 535 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_536 = 536 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_537 = 537 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_538 = 538 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_539 = 539 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_540 = 540 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_541 = 541 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_542 = 542 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_543 = 543 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_544 = 544 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_545 = 545 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_546 = 546 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_547 = 547 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_548 = 548 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_549 = 549 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_550 = 550 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_551 = 551 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_552 = 552 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_553 = 553 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_554 = 554 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_555 = 555 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_556 = 556 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_557 = 557 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_558 = 558 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_559 = 559 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_560 = 560 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_561 = 561 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_562 = 562 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_563 = 563 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_564 = 564 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_565 = 565 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_566 = 566 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_567 = 567 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_568 = 568 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_569 = 569 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_570 = 570 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_571 = 571 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_572 = 572 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_573 = 573 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_574 = 574 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_575 = 575 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_576 = 576 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_577 = 577 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_578 = 578 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_579 = 579 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_580 = 580 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_581 = 581 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_582 = 582 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_583 = 583 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_584 = 584 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_585 = 585 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_586 = 586 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_587 = 587 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_588 = 588 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_589 = 589 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_590 = 590 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_591 = 591 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_592 = 592 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_593 = 593 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_594 = 594 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_595 = 595 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_596 = 596 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_597 = 597 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_598 = 598 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_599 = 599 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_600 = 600 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_601 = 601 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_602 = 602 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_603 = 603 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_604 = 604 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_605 = 605 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_606 = 606 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_607 = 607 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_608 = 608 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_609 = 609 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_610 = 610 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_611 = 611 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_612 = 612 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_613 = 613 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_614 = 614 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_615 = 615 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_616 = 616 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_617 = 617 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_618 = 618 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_619 = 619 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_620 = 620 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_621 = 621 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_622 = 622 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_623 = 623 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_624 = 624 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_625 = 625 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_626 = 626 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_627 = 627 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_628 = 628 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_629 = 629 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_630 = 630 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_631 = 631 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_632 = 632 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_633 = 633 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_634 = 634 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_635 = 635 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_636 = 636 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_637 = 637 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_638 = 638 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_639 = 639 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_640 = 640 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_641 = 641 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_642 = 642 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_643 = 643 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_644 = 644 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_645 = 645 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_646 = 646 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_647 = 647 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_648 = 648 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_649 = 649 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_650 = 650 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_651 = 651 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_652 = 652 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_653 = 653 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_654 = 654 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_655 = 655 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_656 = 656 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_657 = 657 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_658 = 658 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_659 = 659 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_660 = 660 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_661 = 661 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_662 = 662 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_663 = 663 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_664 = 664 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_665 = 665 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_666 = 666 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_667 = 667 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_668 = 668 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_669 = 669 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_670 = 670 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_671 = 671 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_672 = 672 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_673 = 673 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_674 = 674 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_675 = 675 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_676 = 676 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_677 = 677 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_678 = 678 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_679 = 679 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_680 = 680 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_681 = 681 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_682 = 682 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_683 = 683 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_684 = 684 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_685 = 685 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_686 = 686 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_687 = 687 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_688 = 688 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_689 = 689 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_690 = 690 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_691 = 691 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_692 = 692 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_693 = 693 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_694 = 694 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_695 = 695 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_696 = 696 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_697 = 697 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_698 = 698 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_699 = 699 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_700 = 700 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_701 = 701 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_702 = 702 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_703 = 703 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_704 = 704 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_705 = 705 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_706 = 706 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_707 = 707 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_708 = 708 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_709 = 709 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_710 = 710 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_711 = 711 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_712 = 712 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_713 = 713 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_714 = 714 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_715 = 715 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_716 = 716 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_717 = 717 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_718 = 718 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_719 = 719 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_720 = 720 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_721 = 721 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_722 = 722 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_723 = 723 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_724 = 724 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_725 = 725 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_726 = 726 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_727 = 727 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_728 = 728 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_729 = 729 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_730 = 730 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_731 = 731 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_732 = 732 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_733 = 733 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_734 = 734 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_735 = 735 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_736 = 736 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_737 = 737 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_738 = 738 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_739 = 739 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_740 = 740 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_741 = 741 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_742 = 742 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_743 = 743 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_744 = 744 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_745 = 745 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_746 = 746 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_747 = 747 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_748 = 748 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_749 = 749 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_750 = 750 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_751 = 751 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_752 = 752 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_753 = 753 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_754 = 754 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_755 = 755 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_756 = 756 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_757 = 757 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_758 = 758 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_759 = 759 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_760 = 760 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_761 = 761 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_762 = 762 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_763 = 763 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_764 = 764 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_765 = 765 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_766 = 766 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_767 = 767 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_768 = 768 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_769 = 769 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_770 = 770 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_771 = 771 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_772 = 772 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_773 = 773 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_774 = 774 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_775 = 775 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_776 = 776 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_777 = 777 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_778 = 778 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_779 = 779 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_780 = 780 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_781 = 781 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_782 = 782 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_783 = 783 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_784 = 784 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_785 = 785 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_786 = 786 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_787 = 787 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_788 = 788 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_789 = 789 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_790 = 790 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_791 = 791 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_792 = 792 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_793 = 793 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_794 = 794 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_795 = 795 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_796 = 796 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_797 = 797 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_798 = 798 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_799 = 799 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_800 = 800 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_801 = 801 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_802 = 802 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_803 = 803 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_804 = 804 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_805 = 805 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_806 = 806 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_807 = 807 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_808 = 808 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_809 = 809 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_810 = 810 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_811 = 811 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_812 = 812 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_813 = 813 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_814 = 814 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_815 = 815 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_816 = 816 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_817 = 817 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_818 = 818 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_819 = 819 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_820 = 820 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_821 = 821 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_822 = 822 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_823 = 823 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_824 = 824 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_825 = 825 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_826 = 826 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_827 = 827 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_828 = 828 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_829 = 829 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_830 = 830 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_831 = 831 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_832 = 832 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_833 = 833 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_834 = 834 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_835 = 835 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_836 = 836 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_837 = 837 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_838 = 838 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_839 = 839 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_840 = 840 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_841 = 841 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_842 = 842 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_843 = 843 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_844 = 844 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_845 = 845 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_846 = 846 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_847 = 847 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_848 = 848 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_849 = 849 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_850 = 850 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_851 = 851 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_852 = 852 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_853 = 853 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_854 = 854 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_855 = 855 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_856 = 856 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_857 = 857 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_858 = 858 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_859 = 859 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_860 = 860 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_861 = 861 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_862 = 862 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_863 = 863 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_864 = 864 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_865 = 865 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_866 = 866 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_867 = 867 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_868 = 868 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_869 = 869 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_870 = 870 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_871 = 871 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_872 = 872 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_873 = 873 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_874 = 874 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_875 = 875 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_876 = 876 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_877 = 877 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_878 = 878 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_879 = 879 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_880 = 880 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_881 = 881 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_882 = 882 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_883 = 883 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_884 = 884 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_885 = 885 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_886 = 886 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_887 = 887 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_888 = 888 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_889 = 889 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_890 = 890 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_891 = 891 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_892 = 892 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_893 = 893 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_894 = 894 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_895 = 895 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_896 = 896 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_897 = 897 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_898 = 898 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_899 = 899 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_900 = 900 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_901 = 901 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_902 = 902 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_903 = 903 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_904 = 904 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_905 = 905 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_906 = 906 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_907 = 907 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_908 = 908 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_909 = 909 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_910 = 910 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_911 = 911 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_912 = 912 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_913 = 913 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_914 = 914 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_915 = 915 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_916 = 916 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_917 = 917 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_918 = 918 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_919 = 919 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_920 = 920 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_921 = 921 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_922 = 922 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_923 = 923 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_924 = 924 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_925 = 925 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_926 = 926 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_927 = 927 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_928 = 928 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_929 = 929 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_930 = 930 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_931 = 931 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_932 = 932 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_933 = 933 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_934 = 934 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_935 = 935 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_936 = 936 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_937 = 937 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_938 = 938 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_939 = 939 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_940 = 940 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_941 = 941 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_942 = 942 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_943 = 943 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_944 = 944 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_945 = 945 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_946 = 946 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_947 = 947 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_948 = 948 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_949 = 949 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_950 = 950 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_951 = 951 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_952 = 952 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_953 = 953 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_954 = 954 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_955 = 955 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_956 = 956 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_957 = 957 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_958 = 958 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_959 = 959 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_960 = 960 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_961 = 961 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_962 = 962 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_963 = 963 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_964 = 964 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_965 = 965 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_966 = 966 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_967 = 967 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_968 = 968 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_969 = 969 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_970 = 970 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_971 = 971 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_972 = 972 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_973 = 973 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_974 = 974 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_975 = 975 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_976 = 976 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_977 = 977 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_978 = 978 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_979 = 979 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_980 = 980 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_981 = 981 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_982 = 982 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_983 = 983 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_984 = 984 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_985 = 985 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_986 = 986 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_987 = 987 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_988 = 988 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_989 = 989 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_990 = 990 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_991 = 991 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_992 = 992 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_993 = 993 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_994 = 994 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_995 = 995 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_996 = 996 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_997 = 997 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_998 = 998 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_999 = 999 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+ optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000 = 1000 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_import.proto b/src/third_party/protobuf/src/google/protobuf/unittest_import.proto
new file mode 100644
index 0000000..cd533ec
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_import.proto
@@ -0,0 +1,61 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which is imported by unittest.proto to test importing.
+
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do
+// "using namespace unittest_import = protobuf_unittest_import".
+package protobuf_unittest_import;
+
+option optimize_for = SPEED;
+
+// Excercise the java_package option.
+option java_package = "com.google.protobuf.test";
+
+// Do not set a java_outer_classname here to verify that Proto2 works without
+// one.
+
+message ImportMessage {
+ optional int32 d = 1;
+}
+
+enum ImportEnum {
+ IMPORT_FOO = 7;
+ IMPORT_BAR = 8;
+ IMPORT_BAZ = 9;
+}
+
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_import_lite.proto b/src/third_party/protobuf/src/google/protobuf/unittest_import_lite.proto
new file mode 100644
index 0000000..ebaab5c
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_import_lite.proto
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest_import.proto but with optimize_for = LITE_RUNTIME.
+
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+message ImportMessageLite {
+ optional int32 d = 1;
+}
+
+enum ImportEnumLite {
+ IMPORT_LITE_FOO = 7;
+ IMPORT_LITE_BAR = 8;
+ IMPORT_LITE_BAZ = 9;
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_lite.proto b/src/third_party/protobuf/src/google/protobuf/unittest_lite.proto
new file mode 100644
index 0000000..cca6b49
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_lite.proto
@@ -0,0 +1,312 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest.proto but with optimize_for = LITE_RUNTIME.
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_import_lite.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+// Same as TestAllTypes but with the lite runtime.
+message TestAllTypesLite {
+ message NestedMessage {
+ optional int32 bb = 1;
+ }
+
+ enum NestedEnum {
+ FOO = 1;
+ BAR = 2;
+ BAZ = 3;
+ }
+
+ // Singular
+ optional int32 optional_int32 = 1;
+ optional int64 optional_int64 = 2;
+ optional uint32 optional_uint32 = 3;
+ optional uint64 optional_uint64 = 4;
+ optional sint32 optional_sint32 = 5;
+ optional sint64 optional_sint64 = 6;
+ optional fixed32 optional_fixed32 = 7;
+ optional fixed64 optional_fixed64 = 8;
+ optional sfixed32 optional_sfixed32 = 9;
+ optional sfixed64 optional_sfixed64 = 10;
+ optional float optional_float = 11;
+ optional double optional_double = 12;
+ optional bool optional_bool = 13;
+ optional string optional_string = 14;
+ optional bytes optional_bytes = 15;
+
+ optional group OptionalGroup = 16 {
+ optional int32 a = 17;
+ }
+
+ optional NestedMessage optional_nested_message = 18;
+ optional ForeignMessageLite optional_foreign_message = 19;
+ optional protobuf_unittest_import.ImportMessageLite
+ optional_import_message = 20;
+
+ optional NestedEnum optional_nested_enum = 21;
+ optional ForeignEnumLite optional_foreign_enum = 22;
+ optional protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;
+
+ optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+ optional string optional_cord = 25 [ctype=CORD];
+
+ // Repeated
+ repeated int32 repeated_int32 = 31;
+ repeated int64 repeated_int64 = 32;
+ repeated uint32 repeated_uint32 = 33;
+ repeated uint64 repeated_uint64 = 34;
+ repeated sint32 repeated_sint32 = 35;
+ repeated sint64 repeated_sint64 = 36;
+ repeated fixed32 repeated_fixed32 = 37;
+ repeated fixed64 repeated_fixed64 = 38;
+ repeated sfixed32 repeated_sfixed32 = 39;
+ repeated sfixed64 repeated_sfixed64 = 40;
+ repeated float repeated_float = 41;
+ repeated double repeated_double = 42;
+ repeated bool repeated_bool = 43;
+ repeated string repeated_string = 44;
+ repeated bytes repeated_bytes = 45;
+
+ repeated group RepeatedGroup = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated NestedMessage repeated_nested_message = 48;
+ repeated ForeignMessageLite repeated_foreign_message = 49;
+ repeated protobuf_unittest_import.ImportMessageLite
+ repeated_import_message = 50;
+
+ repeated NestedEnum repeated_nested_enum = 51;
+ repeated ForeignEnumLite repeated_foreign_enum = 52;
+ repeated protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;
+
+ repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+ repeated string repeated_cord = 55 [ctype=CORD];
+
+ // Singular with defaults
+ optional int32 default_int32 = 61 [default = 41 ];
+ optional int64 default_int64 = 62 [default = 42 ];
+ optional uint32 default_uint32 = 63 [default = 43 ];
+ optional uint64 default_uint64 = 64 [default = 44 ];
+ optional sint32 default_sint32 = 65 [default = -45 ];
+ optional sint64 default_sint64 = 66 [default = 46 ];
+ optional fixed32 default_fixed32 = 67 [default = 47 ];
+ optional fixed64 default_fixed64 = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32 = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64 = 70 [default = -50 ];
+ optional float default_float = 71 [default = 51.5 ];
+ optional double default_double = 72 [default = 52e3 ];
+ optional bool default_bool = 73 [default = true ];
+ optional string default_string = 74 [default = "hello"];
+ optional bytes default_bytes = 75 [default = "world"];
+
+ optional NestedEnum default_nested_enum = 81 [default = BAR];
+ optional ForeignEnumLite default_foreign_enum = 82
+ [default = FOREIGN_LITE_BAR];
+ optional protobuf_unittest_import.ImportEnumLite
+ default_import_enum = 83 [default = IMPORT_LITE_BAR];
+
+ optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+ optional string default_cord = 85 [ctype=CORD,default="123"];
+}
+
+message ForeignMessageLite {
+ optional int32 c = 1;
+}
+
+enum ForeignEnumLite {
+ FOREIGN_LITE_FOO = 4;
+ FOREIGN_LITE_BAR = 5;
+ FOREIGN_LITE_BAZ = 6;
+}
+
+message TestPackedTypesLite {
+ repeated int32 packed_int32 = 90 [packed = true];
+ repeated int64 packed_int64 = 91 [packed = true];
+ repeated uint32 packed_uint32 = 92 [packed = true];
+ repeated uint64 packed_uint64 = 93 [packed = true];
+ repeated sint32 packed_sint32 = 94 [packed = true];
+ repeated sint64 packed_sint64 = 95 [packed = true];
+ repeated fixed32 packed_fixed32 = 96 [packed = true];
+ repeated fixed64 packed_fixed64 = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32 = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64 = 99 [packed = true];
+ repeated float packed_float = 100 [packed = true];
+ repeated double packed_double = 101 [packed = true];
+ repeated bool packed_bool = 102 [packed = true];
+ repeated ForeignEnumLite packed_enum = 103 [packed = true];
+}
+
+message TestAllExtensionsLite {
+ extensions 1 to max;
+}
+
+extend TestAllExtensionsLite {
+ // Singular
+ optional int32 optional_int32_extension_lite = 1;
+ optional int64 optional_int64_extension_lite = 2;
+ optional uint32 optional_uint32_extension_lite = 3;
+ optional uint64 optional_uint64_extension_lite = 4;
+ optional sint32 optional_sint32_extension_lite = 5;
+ optional sint64 optional_sint64_extension_lite = 6;
+ optional fixed32 optional_fixed32_extension_lite = 7;
+ optional fixed64 optional_fixed64_extension_lite = 8;
+ optional sfixed32 optional_sfixed32_extension_lite = 9;
+ optional sfixed64 optional_sfixed64_extension_lite = 10;
+ optional float optional_float_extension_lite = 11;
+ optional double optional_double_extension_lite = 12;
+ optional bool optional_bool_extension_lite = 13;
+ optional string optional_string_extension_lite = 14;
+ optional bytes optional_bytes_extension_lite = 15;
+
+ optional group OptionalGroup_extension_lite = 16 {
+ optional int32 a = 17;
+ }
+
+ optional TestAllTypesLite.NestedMessage optional_nested_message_extension_lite
+ = 18;
+ optional ForeignMessageLite optional_foreign_message_extension_lite = 19;
+ optional protobuf_unittest_import.ImportMessageLite
+ optional_import_message_extension_lite = 20;
+
+ optional TestAllTypesLite.NestedEnum optional_nested_enum_extension_lite = 21;
+ optional ForeignEnumLite optional_foreign_enum_extension_lite = 22;
+ optional protobuf_unittest_import.ImportEnumLite
+ optional_import_enum_extension_lite = 23;
+
+ optional string optional_string_piece_extension_lite = 24
+ [ctype=STRING_PIECE];
+ optional string optional_cord_extension_lite = 25 [ctype=CORD];
+
+ // Repeated
+ repeated int32 repeated_int32_extension_lite = 31;
+ repeated int64 repeated_int64_extension_lite = 32;
+ repeated uint32 repeated_uint32_extension_lite = 33;
+ repeated uint64 repeated_uint64_extension_lite = 34;
+ repeated sint32 repeated_sint32_extension_lite = 35;
+ repeated sint64 repeated_sint64_extension_lite = 36;
+ repeated fixed32 repeated_fixed32_extension_lite = 37;
+ repeated fixed64 repeated_fixed64_extension_lite = 38;
+ repeated sfixed32 repeated_sfixed32_extension_lite = 39;
+ repeated sfixed64 repeated_sfixed64_extension_lite = 40;
+ repeated float repeated_float_extension_lite = 41;
+ repeated double repeated_double_extension_lite = 42;
+ repeated bool repeated_bool_extension_lite = 43;
+ repeated string repeated_string_extension_lite = 44;
+ repeated bytes repeated_bytes_extension_lite = 45;
+
+ repeated group RepeatedGroup_extension_lite = 46 {
+ optional int32 a = 47;
+ }
+
+ repeated TestAllTypesLite.NestedMessage repeated_nested_message_extension_lite
+ = 48;
+ repeated ForeignMessageLite repeated_foreign_message_extension_lite = 49;
+ repeated protobuf_unittest_import.ImportMessageLite
+ repeated_import_message_extension_lite = 50;
+
+ repeated TestAllTypesLite.NestedEnum repeated_nested_enum_extension_lite = 51;
+ repeated ForeignEnumLite repeated_foreign_enum_extension_lite = 52;
+ repeated protobuf_unittest_import.ImportEnumLite
+ repeated_import_enum_extension_lite = 53;
+
+ repeated string repeated_string_piece_extension_lite = 54
+ [ctype=STRING_PIECE];
+ repeated string repeated_cord_extension_lite = 55 [ctype=CORD];
+
+ // Singular with defaults
+ optional int32 default_int32_extension_lite = 61 [default = 41 ];
+ optional int64 default_int64_extension_lite = 62 [default = 42 ];
+ optional uint32 default_uint32_extension_lite = 63 [default = 43 ];
+ optional uint64 default_uint64_extension_lite = 64 [default = 44 ];
+ optional sint32 default_sint32_extension_lite = 65 [default = -45 ];
+ optional sint64 default_sint64_extension_lite = 66 [default = 46 ];
+ optional fixed32 default_fixed32_extension_lite = 67 [default = 47 ];
+ optional fixed64 default_fixed64_extension_lite = 68 [default = 48 ];
+ optional sfixed32 default_sfixed32_extension_lite = 69 [default = 49 ];
+ optional sfixed64 default_sfixed64_extension_lite = 70 [default = -50 ];
+ optional float default_float_extension_lite = 71 [default = 51.5 ];
+ optional double default_double_extension_lite = 72 [default = 52e3 ];
+ optional bool default_bool_extension_lite = 73 [default = true ];
+ optional string default_string_extension_lite = 74 [default = "hello"];
+ optional bytes default_bytes_extension_lite = 75 [default = "world"];
+
+ optional TestAllTypesLite.NestedEnum
+ default_nested_enum_extension_lite = 81 [default = BAR];
+ optional ForeignEnumLite
+ default_foreign_enum_extension_lite = 82 [default = FOREIGN_LITE_BAR];
+ optional protobuf_unittest_import.ImportEnumLite
+ default_import_enum_extension_lite = 83 [default = IMPORT_LITE_BAR];
+
+ optional string default_string_piece_extension_lite = 84 [ctype=STRING_PIECE,
+ default="abc"];
+ optional string default_cord_extension_lite = 85 [ctype=CORD, default="123"];
+}
+
+message TestPackedExtensionsLite {
+ extensions 1 to max;
+}
+
+extend TestPackedExtensionsLite {
+ repeated int32 packed_int32_extension_lite = 90 [packed = true];
+ repeated int64 packed_int64_extension_lite = 91 [packed = true];
+ repeated uint32 packed_uint32_extension_lite = 92 [packed = true];
+ repeated uint64 packed_uint64_extension_lite = 93 [packed = true];
+ repeated sint32 packed_sint32_extension_lite = 94 [packed = true];
+ repeated sint64 packed_sint64_extension_lite = 95 [packed = true];
+ repeated fixed32 packed_fixed32_extension_lite = 96 [packed = true];
+ repeated fixed64 packed_fixed64_extension_lite = 97 [packed = true];
+ repeated sfixed32 packed_sfixed32_extension_lite = 98 [packed = true];
+ repeated sfixed64 packed_sfixed64_extension_lite = 99 [packed = true];
+ repeated float packed_float_extension_lite = 100 [packed = true];
+ repeated double packed_double_extension_lite = 101 [packed = true];
+ repeated bool packed_bool_extension_lite = 102 [packed = true];
+ repeated ForeignEnumLite packed_enum_extension_lite = 103 [packed = true];
+}
+
+message TestNestedExtensionLite {
+ extend TestAllExtensionsLite {
+ optional int32 nested_extension = 12345;
+ }
+}
+
+// Test that deprecated fields work. We only verify that they compile (at one
+// point this failed).
+message TestDeprecatedLite {
+ optional int32 deprecated_field = 1 [deprecated = true];
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_lite_imports_nonlite.proto b/src/third_party/protobuf/src/google/protobuf/unittest_lite_imports_nonlite.proto
new file mode 100644
index 0000000..d52cb8c
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_lite_imports_nonlite.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Tests that a "lite" message can import a regular message.
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+message TestLiteImportsNonlite {
+ optional TestAllTypes message = 1;
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_mset.proto b/src/third_party/protobuf/src/google/protobuf/unittest_mset.proto
new file mode 100644
index 0000000..3497f09
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_mset.proto
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains messages for testing message_set_wire_format.
+
+package protobuf_unittest;
+
+option optimize_for = SPEED;
+
+// A message with message_set_wire_format.
+message TestMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message TestMessageSetContainer {
+ optional TestMessageSet message_set = 1;
+}
+
+message TestMessageSetExtension1 {
+ extend TestMessageSet {
+ optional TestMessageSetExtension1 message_set_extension = 1545008;
+ }
+ optional int32 i = 15;
+}
+
+message TestMessageSetExtension2 {
+ extend TestMessageSet {
+ optional TestMessageSetExtension2 message_set_extension = 1547769;
+ }
+ optional string str = 25;
+}
+
+// MessageSet wire format is equivalent to this.
+message RawMessageSet {
+ repeated group Item = 1 {
+ required int32 type_id = 2;
+ required bytes message = 3;
+ }
+}
+
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_no_generic_services.proto b/src/third_party/protobuf/src/google/protobuf/unittest_no_generic_services.proto
new file mode 100644
index 0000000..cffb412
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_no_generic_services.proto
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+package google.protobuf.no_generic_services_test;
+
+// *_generic_services are false by default.
+
+message TestMessage {
+ optional int32 a = 1;
+ extensions 1000 to max;
+}
+
+enum TestEnum {
+ FOO = 1;
+}
+
+extend TestMessage {
+ optional int32 test_extension = 1000;
+}
+
+service TestService {
+ rpc Foo(TestMessage) returns(TestMessage);
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/unittest_optimize_for.proto b/src/third_party/protobuf/src/google/protobuf/unittest_optimize_for.proto
new file mode 100644
index 0000000..feecbef
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unittest_optimize_for.proto
@@ -0,0 +1,61 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file which uses optimize_for = CODE_SIZE.
+
+import "google/protobuf/unittest.proto";
+
+package protobuf_unittest;
+
+option optimize_for = CODE_SIZE;
+
+message TestOptimizedForSize {
+ optional int32 i = 1;
+ optional ForeignMessage msg = 19;
+
+ extensions 1000 to max;
+
+ extend TestOptimizedForSize {
+ optional int32 test_extension = 1234;
+ optional TestRequiredOptimizedForSize test_extension2 = 1235;
+ }
+}
+
+message TestRequiredOptimizedForSize {
+ required int32 x = 1;
+}
+
+message TestOptionalOptimizedForSize {
+ optional TestRequiredOptimizedForSize o = 1;
+}
diff --git a/src/third_party/protobuf/src/google/protobuf/unknown_field_set.cc b/src/third_party/protobuf/src/google/protobuf/unknown_field_set.cc
new file mode 100644
index 0000000..38a36d5
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unknown_field_set.cc
@@ -0,0 +1,220 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/wire_format_lite.h>
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+int StringSpaceUsedExcludingSelf(const string& str) {
+ const void* start = &str;
+ const void* end = &str + 1;
+
+ if (start <= str.data() && str.data() <= end) {
+ // The string's data is stored inside the string object itself.
+ return 0;
+ } else {
+ return str.capacity();
+ }
+}
+
+}
+
+UnknownFieldSet::UnknownFieldSet()
+ : fields_(NULL) {}
+
+UnknownFieldSet::~UnknownFieldSet() {
+ Clear();
+ delete fields_;
+}
+
+void UnknownFieldSet::ClearFallback() {
+ GOOGLE_DCHECK(fields_ != NULL);
+ for (int i = 0; i < fields_->size(); i++) {
+ (*fields_)[i].Delete();
+ }
+ fields_->clear();
+}
+
+void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
+ for (int i = 0; i < other.field_count(); i++) {
+ AddField(other.field(i));
+ }
+}
+
+int UnknownFieldSet::SpaceUsedExcludingSelf() const {
+ if (fields_ == NULL) return 0;
+
+ int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size();
+ for (int i = 0; i < fields_->size(); i++) {
+ const UnknownField& field = (*fields_)[i];
+ switch (field.type()) {
+ case UnknownField::TYPE_LENGTH_DELIMITED:
+ total_size += sizeof(*field.length_delimited_) +
+ internal::StringSpaceUsedExcludingSelf(*field.length_delimited_);
+ break;
+ case UnknownField::TYPE_GROUP:
+ total_size += field.group_->SpaceUsed();
+ break;
+ default:
+ break;
+ }
+ }
+ return total_size;
+}
+
+int UnknownFieldSet::SpaceUsed() const {
+ return sizeof(*this) + SpaceUsedExcludingSelf();
+}
+
+void UnknownFieldSet::AddVarint(int number, uint64 value) {
+ if (fields_ == NULL) fields_ = new vector<UnknownField>;
+ UnknownField field;
+ field.number_ = number;
+ field.type_ = UnknownField::TYPE_VARINT;
+ field.varint_ = value;
+ fields_->push_back(field);
+}
+
+void UnknownFieldSet::AddFixed32(int number, uint32 value) {
+ if (fields_ == NULL) fields_ = new vector<UnknownField>;
+ UnknownField field;
+ field.number_ = number;
+ field.type_ = UnknownField::TYPE_FIXED32;
+ field.fixed32_ = value;
+ fields_->push_back(field);
+}
+
+void UnknownFieldSet::AddFixed64(int number, uint64 value) {
+ if (fields_ == NULL) fields_ = new vector<UnknownField>;
+ UnknownField field;
+ field.number_ = number;
+ field.type_ = UnknownField::TYPE_FIXED64;
+ field.fixed64_ = value;
+ fields_->push_back(field);
+}
+
+string* UnknownFieldSet::AddLengthDelimited(int number) {
+ if (fields_ == NULL) fields_ = new vector<UnknownField>;
+ UnknownField field;
+ field.number_ = number;
+ field.type_ = UnknownField::TYPE_LENGTH_DELIMITED;
+ field.length_delimited_ = new string;
+ fields_->push_back(field);
+ return field.length_delimited_;
+}
+
+UnknownFieldSet* UnknownFieldSet::AddGroup(int number) {
+ if (fields_ == NULL) fields_ = new vector<UnknownField>;
+ UnknownField field;
+ field.number_ = number;
+ field.type_ = UnknownField::TYPE_GROUP;
+ field.group_ = new UnknownFieldSet;
+ fields_->push_back(field);
+ return field.group_;
+}
+
+void UnknownFieldSet::AddField(const UnknownField& field) {
+ if (fields_ == NULL) fields_ = new vector<UnknownField>;
+ fields_->push_back(field);
+ fields_->back().DeepCopy();
+}
+
+bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) {
+
+ UnknownFieldSet other;
+ if (internal::WireFormatLite::SkipMessage(input, &other) &&
+ input->ConsumedEntireMessage()) {
+ MergeFrom(other);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) {
+ Clear();
+ return MergeFromCodedStream(input);
+}
+
+bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
+ io::CodedInputStream coded_input(input);
+ return ParseFromCodedStream(&coded_input) &&
+ coded_input.ConsumedEntireMessage();
+}
+
+bool UnknownFieldSet::ParseFromArray(const void* data, int size) {
+ io::ArrayInputStream input(data, size);
+ return ParseFromZeroCopyStream(&input);
+}
+
+void UnknownField::Delete() {
+ switch (type()) {
+ case UnknownField::TYPE_LENGTH_DELIMITED:
+ delete length_delimited_;
+ break;
+ case UnknownField::TYPE_GROUP:
+ delete group_;
+ break;
+ default:
+ break;
+ }
+}
+
+void UnknownField::DeepCopy() {
+ switch (type()) {
+ case UnknownField::TYPE_LENGTH_DELIMITED:
+ length_delimited_ = new string(*length_delimited_);
+ break;
+ case UnknownField::TYPE_GROUP: {
+ UnknownFieldSet* group = new UnknownFieldSet;
+ group->MergeFrom(*group_);
+ group_ = group;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/unknown_field_set.h b/src/third_party/protobuf/src/google/protobuf/unknown_field_set.h
new file mode 100644
index 0000000..84c2e2b
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unknown_field_set.h
@@ -0,0 +1,268 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Contains classes used to keep track of unrecognized fields seen while
+// parsing a protocol message.
+
+#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
+#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/repeated_field.h>
+
+namespace google {
+namespace protobuf {
+
+class Message; // message.h
+class UnknownField; // below
+
+// An UnknownFieldSet contains fields that were encountered while parsing a
+// message but were not defined by its type. Keeping track of these can be
+// useful, especially in that they may be written if the message is serialized
+// again without being cleared in between. This means that software which
+// simply receives messages and forwards them to other servers does not need
+// to be updated every time a new field is added to the message definition.
+//
+// To get the UnknownFieldSet attached to any message, call
+// Reflection::GetUnknownFields().
+//
+// This class is necessarily tied to the protocol buffer wire format, unlike
+// the Reflection interface which is independent of any serialization scheme.
+class LIBPROTOBUF_EXPORT UnknownFieldSet {
+ public:
+ UnknownFieldSet();
+ ~UnknownFieldSet();
+
+ // Remove all fields.
+ inline void Clear();
+
+ // Is this set empty?
+ inline bool empty() const;
+
+ // Merge the contents of some other UnknownFieldSet with this one.
+ void MergeFrom(const UnknownFieldSet& other);
+
+ // Swaps the contents of some other UnknownFieldSet with this one.
+ inline void Swap(UnknownFieldSet* x);
+
+ // Computes (an estimate of) the total number of bytes currently used for
+ // storing the unknown fields in memory. Does NOT include
+ // sizeof(*this) in the calculation.
+ int SpaceUsedExcludingSelf() const;
+
+ // Version of SpaceUsed() including sizeof(*this).
+ int SpaceUsed() const;
+
+ // Returns the number of fields present in the UnknownFieldSet.
+ inline int field_count() const;
+ // Get a field in the set, where 0 <= index < field_count(). The fields
+ // appear in the order in which they were added.
+ inline const UnknownField& field(int index) const;
+ // Get a mutable pointer to a field in the set, where
+ // 0 <= index < field_count(). The fields appear in the order in which
+ // they were added.
+ inline UnknownField* mutable_field(int index);
+
+ // Adding fields ---------------------------------------------------
+
+ void AddVarint(int number, uint64 value);
+ void AddFixed32(int number, uint32 value);
+ void AddFixed64(int number, uint64 value);
+ void AddLengthDelimited(int number, const string& value);
+ string* AddLengthDelimited(int number);
+ UnknownFieldSet* AddGroup(int number);
+
+ // Adds an unknown field from another set.
+ void AddField(const UnknownField& field);
+
+ // Parsing helpers -------------------------------------------------
+ // These work exactly like the similarly-named methods of Message.
+
+ bool MergeFromCodedStream(io::CodedInputStream* input);
+ bool ParseFromCodedStream(io::CodedInputStream* input);
+ bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
+ bool ParseFromArray(const void* data, int size);
+ inline bool ParseFromString(const string& data) {
+ return ParseFromArray(data.data(), data.size());
+ }
+
+ private:
+ void ClearFallback();
+
+ vector<UnknownField>* fields_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
+};
+
+// Represents one field in an UnknownFieldSet.
+class LIBPROTOBUF_EXPORT UnknownField {
+ public:
+ enum Type {
+ TYPE_VARINT,
+ TYPE_FIXED32,
+ TYPE_FIXED64,
+ TYPE_LENGTH_DELIMITED,
+ TYPE_GROUP
+ };
+
+ // The field's tag number, as seen on the wire.
+ inline int number() const;
+
+ // The field type.
+ inline Type type() const;
+
+ // Accessors -------------------------------------------------------
+ // Each method works only for UnknownFields of the corresponding type.
+
+ inline uint64 varint() const;
+ inline uint32 fixed32() const;
+ inline uint64 fixed64() const;
+ inline const string& length_delimited() const;
+ inline const UnknownFieldSet& group() const;
+
+ inline void set_varint(uint64 value);
+ inline void set_fixed32(uint32 value);
+ inline void set_fixed64(uint64 value);
+ inline void set_length_delimited(const string& value);
+ inline string* mutable_length_delimited();
+ inline UnknownFieldSet* mutable_group();
+
+ private:
+ friend class UnknownFieldSet;
+
+ // If this UnknownField contains a pointer, delete it.
+ void Delete();
+
+ // Make a deep copy of any pointers in this UnknownField.
+ void DeepCopy();
+
+ unsigned int number_ : 29;
+ unsigned int type_ : 3;
+ union {
+ uint64 varint_;
+ uint32 fixed32_;
+ uint64 fixed64_;
+ string* length_delimited_;
+ UnknownFieldSet* group_;
+ };
+};
+
+// ===================================================================
+// inline implementations
+
+inline void UnknownFieldSet::Clear() {
+ if (fields_ != NULL) {
+ ClearFallback();
+ }
+}
+
+inline bool UnknownFieldSet::empty() const {
+ return fields_ == NULL || fields_->empty();
+}
+
+inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
+ std::swap(fields_, x->fields_);
+}
+
+inline int UnknownFieldSet::field_count() const {
+ return (fields_ == NULL) ? 0 : fields_->size();
+}
+inline const UnknownField& UnknownFieldSet::field(int index) const {
+ return (*fields_)[index];
+}
+inline UnknownField* UnknownFieldSet::mutable_field(int index) {
+ return &(*fields_)[index];
+}
+
+inline void UnknownFieldSet::AddLengthDelimited(
+ int number, const string& value) {
+ AddLengthDelimited(number)->assign(value);
+}
+
+inline int UnknownField::number() const { return number_; }
+inline UnknownField::Type UnknownField::type() const {
+ return static_cast<Type>(type_);
+}
+
+inline uint64 UnknownField::varint () const {
+ GOOGLE_DCHECK_EQ(type_, TYPE_VARINT);
+ return varint_;
+}
+inline uint32 UnknownField::fixed32() const {
+ GOOGLE_DCHECK_EQ(type_, TYPE_FIXED32);
+ return fixed32_;
+}
+inline uint64 UnknownField::fixed64() const {
+ GOOGLE_DCHECK_EQ(type_, TYPE_FIXED64);
+ return fixed64_;
+}
+inline const string& UnknownField::length_delimited() const {
+ GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED);
+ return *length_delimited_;
+}
+inline const UnknownFieldSet& UnknownField::group() const {
+ GOOGLE_DCHECK_EQ(type_, TYPE_GROUP);
+ return *group_;
+}
+
+inline void UnknownField::set_varint(uint64 value) {
+ GOOGLE_DCHECK_EQ(type_, TYPE_VARINT);
+ varint_ = value;
+}
+inline void UnknownField::set_fixed32(uint32 value) {
+ GOOGLE_DCHECK_EQ(type_, TYPE_FIXED32);
+ fixed32_ = value;
+}
+inline void UnknownField::set_fixed64(uint64 value) {
+ GOOGLE_DCHECK_EQ(type_, TYPE_FIXED64);
+ fixed64_ = value;
+}
+inline void UnknownField::set_length_delimited(const string& value) {
+ GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED);
+ length_delimited_->assign(value);
+}
+inline string* UnknownField::mutable_length_delimited() {
+ GOOGLE_DCHECK_EQ(type_, TYPE_LENGTH_DELIMITED);
+ return length_delimited_;
+}
+inline UnknownFieldSet* UnknownField::mutable_group() {
+ GOOGLE_DCHECK_EQ(type_, TYPE_GROUP);
+ return group_;
+}
+
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/unknown_field_set_unittest.cc b/src/third_party/protobuf/src/google/protobuf/unknown_field_set_unittest.cc
new file mode 100644
index 0000000..1235c9e
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/unknown_field_set_unittest.cc
@@ -0,0 +1,512 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This test is testing a lot more than just the UnknownFieldSet class. It
+// tests handling of unknown fields throughout the system.
+
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+
+namespace {
+
+class UnknownFieldSetTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ descriptor_ = unittest::TestAllTypes::descriptor();
+ TestUtil::SetAllFields(&all_fields_);
+ all_fields_.SerializeToString(&all_fields_data_);
+ ASSERT_TRUE(empty_message_.ParseFromString(all_fields_data_));
+ unknown_fields_ = empty_message_.mutable_unknown_fields();
+ }
+
+ const UnknownField* GetField(const string& name) {
+ const FieldDescriptor* field = descriptor_->FindFieldByName(name);
+ if (field == NULL) return NULL;
+ for (int i = 0; i < unknown_fields_->field_count(); i++) {
+ if (unknown_fields_->field(i).number() == field->number()) {
+ return &unknown_fields_->field(i);
+ }
+ }
+ return NULL;
+ }
+
+ // Constructs a protocol buffer which contains fields with all the same
+ // numbers as all_fields_data_ except that each field is some other wire
+ // type.
+ string GetBizarroData() {
+ unittest::TestEmptyMessage bizarro_message;
+ UnknownFieldSet* bizarro_unknown_fields =
+ bizarro_message.mutable_unknown_fields();
+ for (int i = 0; i < unknown_fields_->field_count(); i++) {
+ const UnknownField& unknown_field = unknown_fields_->field(i);
+ if (unknown_field.type() == UnknownField::TYPE_VARINT) {
+ bizarro_unknown_fields->AddFixed32(unknown_field.number(), 1);
+ } else {
+ bizarro_unknown_fields->AddVarint(unknown_field.number(), 1);
+ }
+ }
+
+ string data;
+ EXPECT_TRUE(bizarro_message.SerializeToString(&data));
+ return data;
+ }
+
+ const Descriptor* descriptor_;
+ unittest::TestAllTypes all_fields_;
+ string all_fields_data_;
+
+ // An empty message that has been parsed from all_fields_data_. So, it has
+ // unknown fields of every type.
+ unittest::TestEmptyMessage empty_message_;
+ UnknownFieldSet* unknown_fields_;
+};
+
+TEST_F(UnknownFieldSetTest, AllFieldsPresent) {
+ // All fields of TestAllTypes should be present, in numeric order (because
+ // that's the order we parsed them in). Fields that are not valid field
+ // numbers of TestAllTypes should NOT be present.
+
+ int pos = 0;
+
+ for (int i = 0; i < 1000; i++) {
+ const FieldDescriptor* field = descriptor_->FindFieldByNumber(i);
+ if (field != NULL) {
+ ASSERT_LT(pos, unknown_fields_->field_count());
+ EXPECT_EQ(i, unknown_fields_->field(pos++).number());
+ if (field->is_repeated()) {
+ // Should have a second instance.
+ ASSERT_LT(pos, unknown_fields_->field_count());
+ EXPECT_EQ(i, unknown_fields_->field(pos++).number());
+ }
+ }
+ }
+ EXPECT_EQ(unknown_fields_->field_count(), pos);
+}
+
+TEST_F(UnknownFieldSetTest, Varint) {
+ const UnknownField* field = GetField("optional_int32");
+ ASSERT_TRUE(field != NULL);
+
+ ASSERT_EQ(UnknownField::TYPE_VARINT, field->type());
+ EXPECT_EQ(all_fields_.optional_int32(), field->varint());
+}
+
+TEST_F(UnknownFieldSetTest, Fixed32) {
+ const UnknownField* field = GetField("optional_fixed32");
+ ASSERT_TRUE(field != NULL);
+
+ ASSERT_EQ(UnknownField::TYPE_FIXED32, field->type());
+ EXPECT_EQ(all_fields_.optional_fixed32(), field->fixed32());
+}
+
+TEST_F(UnknownFieldSetTest, Fixed64) {
+ const UnknownField* field = GetField("optional_fixed64");
+ ASSERT_TRUE(field != NULL);
+
+ ASSERT_EQ(UnknownField::TYPE_FIXED64, field->type());
+ EXPECT_EQ(all_fields_.optional_fixed64(), field->fixed64());
+}
+
+TEST_F(UnknownFieldSetTest, LengthDelimited) {
+ const UnknownField* field = GetField("optional_string");
+ ASSERT_TRUE(field != NULL);
+
+ ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, field->type());
+ EXPECT_EQ(all_fields_.optional_string(), field->length_delimited());
+}
+
+TEST_F(UnknownFieldSetTest, Group) {
+ const UnknownField* field = GetField("optionalgroup");
+ ASSERT_TRUE(field != NULL);
+
+ ASSERT_EQ(UnknownField::TYPE_GROUP, field->type());
+ ASSERT_EQ(1, field->group().field_count());
+
+ const UnknownField& nested_field = field->group().field(0);
+ const FieldDescriptor* nested_field_descriptor =
+ unittest::TestAllTypes::OptionalGroup::descriptor()->FindFieldByName("a");
+ ASSERT_TRUE(nested_field_descriptor != NULL);
+
+ EXPECT_EQ(nested_field_descriptor->number(), nested_field.number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, nested_field.type());
+ EXPECT_EQ(all_fields_.optionalgroup().a(), nested_field.varint());
+}
+
+TEST_F(UnknownFieldSetTest, SerializeFastAndSlowAreEquivalent) {
+ int size = WireFormat::ComputeUnknownFieldsSize(
+ empty_message_.unknown_fields());
+ string slow_buffer;
+ string fast_buffer;
+ slow_buffer.resize(size);
+ fast_buffer.resize(size);
+
+ uint8* target = reinterpret_cast<uint8*>(string_as_array(&fast_buffer));
+ uint8* result = WireFormat::SerializeUnknownFieldsToArray(
+ empty_message_.unknown_fields(), target);
+ EXPECT_EQ(size, result - target);
+
+ {
+ io::ArrayOutputStream raw_stream(string_as_array(&slow_buffer), size, 1);
+ io::CodedOutputStream output_stream(&raw_stream);
+ WireFormat::SerializeUnknownFields(empty_message_.unknown_fields(),
+ &output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+ EXPECT_TRUE(fast_buffer == slow_buffer);
+}
+
+TEST_F(UnknownFieldSetTest, Serialize) {
+ // Check that serializing the UnknownFieldSet produces the original data
+ // again.
+
+ string data;
+ empty_message_.SerializeToString(&data);
+
+ // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+ // stdout.
+ EXPECT_TRUE(data == all_fields_data_);
+}
+
+TEST_F(UnknownFieldSetTest, ParseViaReflection) {
+ // Make sure fields are properly parsed to the UnknownFieldSet when parsing
+ // via reflection.
+
+ unittest::TestEmptyMessage message;
+ io::ArrayInputStream raw_input(all_fields_data_.data(),
+ all_fields_data_.size());
+ io::CodedInputStream input(&raw_input);
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message));
+
+ EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, SerializeViaReflection) {
+ // Make sure fields are properly written from the UnknownFieldSet when
+ // serializing via reflection.
+
+ string data;
+
+ {
+ io::StringOutputStream raw_output(&data);
+ io::CodedOutputStream output(&raw_output);
+ int size = WireFormat::ByteSize(empty_message_);
+ WireFormat::SerializeWithCachedSizes(empty_message_, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Don't use EXPECT_EQ because we don't want to dump raw binary data to
+ // stdout.
+ EXPECT_TRUE(data == all_fields_data_);
+}
+
+TEST_F(UnknownFieldSetTest, CopyFrom) {
+ unittest::TestEmptyMessage message;
+
+ message.CopyFrom(empty_message_);
+
+ EXPECT_EQ(empty_message_.DebugString(), message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, Swap) {
+ unittest::TestEmptyMessage other_message;
+ ASSERT_TRUE(other_message.ParseFromString(GetBizarroData()));
+
+ EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+ EXPECT_GT(other_message.unknown_fields().field_count(), 0);
+ const string debug_string = empty_message_.DebugString();
+ const string other_debug_string = other_message.DebugString();
+ EXPECT_NE(debug_string, other_debug_string);
+
+ empty_message_.Swap(&other_message);
+ EXPECT_EQ(debug_string, other_message.DebugString());
+ EXPECT_EQ(other_debug_string, empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, SwapWithSelf) {
+ const string debug_string = empty_message_.DebugString();
+ EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+
+ empty_message_.Swap(&empty_message_);
+ EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+ EXPECT_EQ(debug_string, empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, MergeFrom) {
+ unittest::TestEmptyMessage source, destination;
+
+ destination.mutable_unknown_fields()->AddVarint(1, 1);
+ destination.mutable_unknown_fields()->AddVarint(3, 2);
+ source.mutable_unknown_fields()->AddVarint(2, 3);
+ source.mutable_unknown_fields()->AddVarint(3, 4);
+
+ destination.MergeFrom(source);
+
+ EXPECT_EQ(
+ // Note: The ordering of fields here depends on the ordering of adds
+ // and merging, above.
+ "1: 1\n"
+ "3: 2\n"
+ "2: 3\n"
+ "3: 4\n",
+ destination.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, Clear) {
+ // Clear the set.
+ empty_message_.Clear();
+ EXPECT_EQ(0, unknown_fields_->field_count());
+}
+
+TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) {
+ // Test mixing known and unknown fields when parsing.
+
+ unittest::TestEmptyMessage source;
+ source.mutable_unknown_fields()->AddVarint(123456, 654321);
+ string data;
+ ASSERT_TRUE(source.SerializeToString(&data));
+
+ unittest::TestAllTypes destination;
+ ASSERT_TRUE(destination.ParseFromString(all_fields_data_ + data));
+
+ TestUtil::ExpectAllFieldsSet(destination);
+ ASSERT_EQ(1, destination.unknown_fields().field_count());
+ ASSERT_EQ(UnknownField::TYPE_VARINT,
+ destination.unknown_fields().field(0).type());
+ EXPECT_EQ(654321, destination.unknown_fields().field(0).varint());
+}
+
+TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknown) {
+ // Test that fields of the wrong wire type are treated like unknown fields
+ // when parsing.
+
+ unittest::TestAllTypes all_types_message;
+ unittest::TestEmptyMessage empty_message;
+ string bizarro_data = GetBizarroData();
+ ASSERT_TRUE(all_types_message.ParseFromString(bizarro_data));
+ ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
+
+ // All fields should have been interpreted as unknown, so the debug strings
+ // should be the same.
+ EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, WrongTypeTreatedAsUnknownViaReflection) {
+ // Same as WrongTypeTreatedAsUnknown but via the reflection interface.
+
+ unittest::TestAllTypes all_types_message;
+ unittest::TestEmptyMessage empty_message;
+ string bizarro_data = GetBizarroData();
+ io::ArrayInputStream raw_input(bizarro_data.data(), bizarro_data.size());
+ io::CodedInputStream input(&raw_input);
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &all_types_message));
+ ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
+
+ EXPECT_EQ(empty_message.DebugString(), all_types_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownExtensions) {
+ // Make sure fields are properly parsed to the UnknownFieldSet even when
+ // they are declared as extension numbers.
+
+ unittest::TestEmptyMessageWithExtensions message;
+ ASSERT_TRUE(message.ParseFromString(all_fields_data_));
+
+ EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownExtensionsReflection) {
+ // Same as UnknownExtensions except parsing via reflection.
+
+ unittest::TestEmptyMessageWithExtensions message;
+ io::ArrayInputStream raw_input(all_fields_data_.data(),
+ all_fields_data_.size());
+ io::CodedInputStream input(&raw_input);
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message));
+
+ EXPECT_EQ(message.DebugString(), empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, WrongExtensionTypeTreatedAsUnknown) {
+ // Test that fields of the wrong wire type are treated like unknown fields
+ // when parsing extensions.
+
+ unittest::TestAllExtensions all_extensions_message;
+ unittest::TestEmptyMessage empty_message;
+ string bizarro_data = GetBizarroData();
+ ASSERT_TRUE(all_extensions_message.ParseFromString(bizarro_data));
+ ASSERT_TRUE(empty_message.ParseFromString(bizarro_data));
+
+ // All fields should have been interpreted as unknown, so the debug strings
+ // should be the same.
+ EXPECT_EQ(empty_message.DebugString(), all_extensions_message.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, UnknownEnumValue) {
+ using unittest::TestAllTypes;
+ using unittest::TestAllExtensions;
+ using unittest::TestEmptyMessage;
+
+ const FieldDescriptor* singular_field =
+ TestAllTypes::descriptor()->FindFieldByName("optional_nested_enum");
+ const FieldDescriptor* repeated_field =
+ TestAllTypes::descriptor()->FindFieldByName("repeated_nested_enum");
+ ASSERT_TRUE(singular_field != NULL);
+ ASSERT_TRUE(repeated_field != NULL);
+
+ string data;
+
+ {
+ TestEmptyMessage empty_message;
+ UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields();
+ unknown_fields->AddVarint(singular_field->number(), TestAllTypes::BAR);
+ unknown_fields->AddVarint(singular_field->number(), 5); // not valid
+ unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::FOO);
+ unknown_fields->AddVarint(repeated_field->number(), 4); // not valid
+ unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::BAZ);
+ unknown_fields->AddVarint(repeated_field->number(), 6); // not valid
+ empty_message.SerializeToString(&data);
+ }
+
+ {
+ TestAllTypes message;
+ ASSERT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(TestAllTypes::BAR, message.optional_nested_enum());
+ ASSERT_EQ(2, message.repeated_nested_enum_size());
+ EXPECT_EQ(TestAllTypes::FOO, message.repeated_nested_enum(0));
+ EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(1));
+
+ const UnknownFieldSet& unknown_fields = message.unknown_fields();
+ ASSERT_EQ(3, unknown_fields.field_count());
+
+ EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type());
+ EXPECT_EQ(5, unknown_fields.field(0).varint());
+
+ EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type());
+ EXPECT_EQ(4, unknown_fields.field(1).varint());
+
+ EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type());
+ EXPECT_EQ(6, unknown_fields.field(2).varint());
+ }
+
+ {
+ using unittest::optional_nested_enum_extension;
+ using unittest::repeated_nested_enum_extension;
+
+ TestAllExtensions message;
+ ASSERT_TRUE(message.ParseFromString(data));
+ EXPECT_EQ(TestAllTypes::BAR,
+ message.GetExtension(optional_nested_enum_extension));
+ ASSERT_EQ(2, message.ExtensionSize(repeated_nested_enum_extension));
+ EXPECT_EQ(TestAllTypes::FOO,
+ message.GetExtension(repeated_nested_enum_extension, 0));
+ EXPECT_EQ(TestAllTypes::BAZ,
+ message.GetExtension(repeated_nested_enum_extension, 1));
+
+ const UnknownFieldSet& unknown_fields = message.unknown_fields();
+ ASSERT_EQ(3, unknown_fields.field_count());
+
+ EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type());
+ EXPECT_EQ(5, unknown_fields.field(0).varint());
+
+ EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type());
+ EXPECT_EQ(4, unknown_fields.field(1).varint());
+
+ EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number());
+ ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type());
+ EXPECT_EQ(6, unknown_fields.field(2).varint());
+ }
+}
+
+TEST_F(UnknownFieldSetTest, SpaceUsed) {
+ unittest::TestEmptyMessage empty_message;
+
+ // Make sure an unknown field set has zero space used until a field is
+ // actually added.
+ int base_size = empty_message.SpaceUsed();
+ UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields();
+ EXPECT_EQ(base_size, empty_message.SpaceUsed());
+
+ // Make sure each thing we add to the set increases the SpaceUsed().
+ unknown_fields->AddVarint(1, 0);
+ EXPECT_LT(base_size, empty_message.SpaceUsed());
+ base_size = empty_message.SpaceUsed();
+
+ string* str = unknown_fields->AddLengthDelimited(1);
+ EXPECT_LT(base_size, empty_message.SpaceUsed());
+ base_size = empty_message.SpaceUsed();
+
+ str->assign(sizeof(string) + 1, 'x');
+ EXPECT_LT(base_size, empty_message.SpaceUsed());
+ base_size = empty_message.SpaceUsed();
+
+ UnknownFieldSet* group = unknown_fields->AddGroup(1);
+ EXPECT_LT(base_size, empty_message.SpaceUsed());
+ base_size = empty_message.SpaceUsed();
+
+ group->AddVarint(1, 0);
+ EXPECT_LT(base_size, empty_message.SpaceUsed());
+}
+
+TEST_F(UnknownFieldSetTest, Empty) {
+ UnknownFieldSet unknown_fields;
+ EXPECT_TRUE(unknown_fields.empty());
+ unknown_fields.AddVarint(6, 123);
+ EXPECT_FALSE(unknown_fields.empty());
+ unknown_fields.Clear();
+ EXPECT_TRUE(unknown_fields.empty());
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/wire_format.cc b/src/third_party/protobuf/src/google/protobuf/wire_format.cc
new file mode 100644
index 0000000..d07f633
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/wire_format.cc
@@ -0,0 +1,767 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <stack>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/wire_format.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/unknown_field_set.h>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+using internal::WireFormatLite;
+
+namespace {
+
+// This function turns out to be convenient when using some macros later.
+inline int GetEnumNumber(const EnumValueDescriptor* descriptor) {
+ return descriptor->number();
+}
+
+} // anonymous namespace
+
+bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
+ Message* message) {
+ const Descriptor* descriptor = message->GetDescriptor();
+ const Reflection* message_reflection = message->GetReflection();
+
+ while(true) {
+ uint32 tag = input->ReadTag();
+ if (tag == 0) {
+ // End of input. This is a valid place to end, so return true.
+ return true;
+ }
+
+ if (WireFormatLite::GetTagWireType(tag) ==
+ WireFormatLite::WIRETYPE_END_GROUP) {
+ // Must be the end of the message.
+ return true;
+ }
+
+ const FieldDescriptor* field = NULL;
+
+ if (descriptor != NULL) {
+ int field_number = WireFormatLite::GetTagFieldNumber(tag);
+ field = descriptor->FindFieldByNumber(field_number);
+
+ // If that failed, check if the field is an extension.
+ if (field == NULL && descriptor->IsExtensionNumber(field_number)) {
+ if (input->GetExtensionPool() == NULL) {
+ field = message_reflection->FindKnownExtensionByNumber(field_number);
+ } else {
+ field = input->GetExtensionPool()
+ ->FindExtensionByNumber(descriptor, field_number);
+ }
+ }
+
+ // If that failed, but we're a MessageSet, and this is the tag for a
+ // MessageSet item, then parse that.
+ if (field == NULL &&
+ descriptor->options().message_set_wire_format() &&
+ tag == WireFormatLite::kMessageSetItemStartTag) {
+ if (!ParseAndMergeMessageSetItem(input, message)) {
+ return false;
+ }
+ continue; // Skip ParseAndMergeField(); already taken care of.
+ }
+ }
+
+ if (!ParseAndMergeField(tag, field, message, input)) {
+ return false;
+ }
+ }
+}
+
+bool WireFormat::ParseAndMergeField(
+ uint32 tag,
+ const FieldDescriptor* field, // May be NULL for unknown
+ Message* message,
+ io::CodedInputStream* input) {
+ const Reflection* message_reflection = message->GetReflection();
+
+ enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format;
+
+ if (field == NULL) {
+ value_format = UNKNOWN;
+ } else if (WireFormatLite::GetTagWireType(tag) ==
+ WireTypeForFieldType(field->type())) {
+ value_format = NORMAL_FORMAT;
+ } else if (field->is_packable() &&
+ WireFormatLite::GetTagWireType(tag) ==
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+ value_format = PACKED_FORMAT;
+ } else {
+ // We don't recognize this field. Either the field number is unknown
+ // or the wire type doesn't match. Put it in our unknown field set.
+ value_format = UNKNOWN;
+ }
+
+ if (value_format == UNKNOWN) {
+ return WireFormatLite::SkipField(
+ input, tag, message_reflection->MutableUnknownFields(message));
+ } else if (value_format == PACKED_FORMAT) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ io::CodedInputStream::Limit limit = input->PushLimit(length);
+
+ switch (field->type()) {
+#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: { \
+ while (input->BytesUntilLimit() > 0) { \
+ CPPTYPE value; \
+ if (!WireFormatLite::ReadPrimitive< \
+ CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \
+ return false; \
+ message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
+ } \
+ break; \
+ }
+
+ HANDLE_PACKED_TYPE( INT32, int32, Int32)
+ HANDLE_PACKED_TYPE( INT64, int64, Int64)
+ HANDLE_PACKED_TYPE(SINT32, int32, Int32)
+ HANDLE_PACKED_TYPE(SINT64, int64, Int64)
+ HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
+ HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
+
+ HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32)
+ HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64)
+ HANDLE_PACKED_TYPE(SFIXED32, int32, Int32)
+ HANDLE_PACKED_TYPE(SFIXED64, int64, Int64)
+
+ HANDLE_PACKED_TYPE(FLOAT , float , Float )
+ HANDLE_PACKED_TYPE(DOUBLE, double, Double)
+
+ HANDLE_PACKED_TYPE(BOOL, bool, Bool)
+#undef HANDLE_PACKED_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ while (input->BytesUntilLimit() > 0) {
+ int value;
+ if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+ input, &value)) return false;
+ const EnumValueDescriptor* enum_value =
+ field->enum_type()->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ message_reflection->AddEnum(message, field, enum_value);
+ }
+ }
+
+ break;
+ }
+
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_GROUP:
+ case FieldDescriptor::TYPE_MESSAGE:
+ case FieldDescriptor::TYPE_BYTES:
+ // Can't have packed fields of these types: these should be caught by
+ // the protocol compiler.
+ return false;
+ break;
+ }
+
+ input->PopLimit(limit);
+ } else {
+ // Non-packed value (value_format == NORMAL_FORMAT)
+ switch (field->type()) {
+#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: { \
+ CPPTYPE value; \
+ if (!WireFormatLite::ReadPrimitive< \
+ CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)) \
+ return false; \
+ if (field->is_repeated()) { \
+ message_reflection->Add##CPPTYPE_METHOD(message, field, value); \
+ } else { \
+ message_reflection->Set##CPPTYPE_METHOD(message, field, value); \
+ } \
+ break; \
+ }
+
+ HANDLE_TYPE( INT32, int32, Int32)
+ HANDLE_TYPE( INT64, int64, Int64)
+ HANDLE_TYPE(SINT32, int32, Int32)
+ HANDLE_TYPE(SINT64, int64, Int64)
+ HANDLE_TYPE(UINT32, uint32, UInt32)
+ HANDLE_TYPE(UINT64, uint64, UInt64)
+
+ HANDLE_TYPE( FIXED32, uint32, UInt32)
+ HANDLE_TYPE( FIXED64, uint64, UInt64)
+ HANDLE_TYPE(SFIXED32, int32, Int32)
+ HANDLE_TYPE(SFIXED64, int64, Int64)
+
+ HANDLE_TYPE(FLOAT , float , Float )
+ HANDLE_TYPE(DOUBLE, double, Double)
+
+ HANDLE_TYPE(BOOL, bool, Bool)
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ int value;
+ if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+ input, &value)) return false;
+ const EnumValueDescriptor* enum_value =
+ field->enum_type()->FindValueByNumber(value);
+ if (enum_value != NULL) {
+ if (field->is_repeated()) {
+ message_reflection->AddEnum(message, field, enum_value);
+ } else {
+ message_reflection->SetEnum(message, field, enum_value);
+ }
+ } else {
+ // The enum value is not one of the known values. Add it to the
+ // UnknownFieldSet.
+ int64 sign_extended_value = static_cast<int64>(value);
+ message_reflection->MutableUnknownFields(message)
+ ->AddVarint(WireFormatLite::GetTagFieldNumber(tag),
+ sign_extended_value);
+ }
+ break;
+ }
+
+ // Handle strings separately so that we can optimize the ctype=CORD case.
+ case FieldDescriptor::TYPE_STRING: {
+ string value;
+ if (!WireFormatLite::ReadString(input, &value)) return false;
+ VerifyUTF8String(value.data(), value.length(), PARSE);
+ if (field->is_repeated()) {
+ message_reflection->AddString(message, field, value);
+ } else {
+ message_reflection->SetString(message, field, value);
+ }
+ break;
+ }
+
+ case FieldDescriptor::TYPE_BYTES: {
+ string value;
+ if (!WireFormatLite::ReadBytes(input, &value)) return false;
+ if (field->is_repeated()) {
+ message_reflection->AddString(message, field, value);
+ } else {
+ message_reflection->SetString(message, field, value);
+ }
+ break;
+ }
+
+ case FieldDescriptor::TYPE_GROUP: {
+ Message* sub_message;
+ if (field->is_repeated()) {
+ sub_message = message_reflection->AddMessage(
+ message, field, input->GetExtensionFactory());
+ } else {
+ sub_message = message_reflection->MutableMessage(
+ message, field, input->GetExtensionFactory());
+ }
+
+ if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag),
+ input, sub_message))
+ return false;
+ break;
+ }
+
+ case FieldDescriptor::TYPE_MESSAGE: {
+ Message* sub_message;
+ if (field->is_repeated()) {
+ sub_message = message_reflection->AddMessage(
+ message, field, input->GetExtensionFactory());
+ } else {
+ sub_message = message_reflection->MutableMessage(
+ message, field, input->GetExtensionFactory());
+ }
+
+ if (!WireFormatLite::ReadMessage(input, sub_message)) return false;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool WireFormat::ParseAndMergeMessageSetItem(
+ io::CodedInputStream* input,
+ Message* message) {
+ const Reflection* message_reflection = message->GetReflection();
+
+ // This method parses a group which should contain two fields:
+ // required int32 type_id = 2;
+ // required data message = 3;
+
+ // Once we see a type_id, we'll construct a fake tag for this extension
+ // which is the tag it would have had under the proto2 extensions wire
+ // format.
+ uint32 fake_tag = 0;
+
+ // Once we see a type_id, we'll look up the FieldDescriptor for the
+ // extension.
+ const FieldDescriptor* field = NULL;
+
+ // If we see message data before the type_id, we'll append it to this so
+ // we can parse it later. This will probably never happen in practice,
+ // as no MessageSet encoder I know of writes the message before the type ID.
+ // But, it's technically valid so we should allow it.
+ // TODO(kenton): Use a Cord instead? Do I care?
+ string message_data;
+
+ while (true) {
+ uint32 tag = input->ReadTag();
+ if (tag == 0) return false;
+
+ switch (tag) {
+ case WireFormatLite::kMessageSetTypeIdTag: {
+ uint32 type_id;
+ if (!input->ReadVarint32(&type_id)) return false;
+ fake_tag = WireFormatLite::MakeTag(
+ type_id, WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+ field = message_reflection->FindKnownExtensionByNumber(type_id);
+
+ if (!message_data.empty()) {
+ // We saw some message data before the type_id. Have to parse it
+ // now.
+ io::ArrayInputStream raw_input(message_data.data(),
+ message_data.size());
+ io::CodedInputStream sub_input(&raw_input);
+ if (!ParseAndMergeField(fake_tag, field, message,
+ &sub_input)) {
+ return false;
+ }
+ message_data.clear();
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetMessageTag: {
+ if (fake_tag == 0) {
+ // We haven't seen a type_id yet. Append this data to message_data.
+ string temp;
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (!input->ReadString(&temp, length)) return false;
+ message_data.append(temp);
+ } else {
+ // Already saw type_id, so we can parse this directly.
+ if (!ParseAndMergeField(fake_tag, field, message, input)) {
+ return false;
+ }
+ }
+
+ break;
+ }
+
+ case WireFormatLite::kMessageSetItemEndTag: {
+ return true;
+ }
+
+ default: {
+ if (!WireFormatLite::SkipField(input, tag, NULL)) return false;
+ }
+ }
+ }
+}
+
+// ===================================================================
+
+void WireFormat::SerializeWithCachedSizes(
+ const Message& message,
+ int size, io::CodedOutputStream* output) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* message_reflection = message.GetReflection();
+ int expected_endpoint = output->ByteCount() + size;
+
+ vector<const FieldDescriptor*> fields;
+ message_reflection->ListFields(message, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ SerializeFieldWithCachedSizes(fields[i], message, output);
+ }
+
+ if (descriptor->options().message_set_wire_format()) {
+ WireFormatLite::SerializeUnknownMessageSetItems(
+ message_reflection->GetUnknownFields(message), output);
+ } else {
+ WireFormatLite::SerializeUnknownFields(
+ message_reflection->GetUnknownFields(message), output);
+ }
+
+ GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint)
+ << ": Protocol message serialized to a size different from what was "
+ "originally expected. Perhaps it was modified by another thread "
+ "during serialization?";
+}
+
+void WireFormat::SerializeFieldWithCachedSizes(
+ const FieldDescriptor* field,
+ const Message& message,
+ io::CodedOutputStream* output) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ if (field->is_extension() &&
+ field->containing_type()->options().message_set_wire_format() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_repeated()) {
+ SerializeMessageSetItemWithCachedSizes(field, message, output);
+ return;
+ }
+
+ int count = 0;
+
+ if (field->is_repeated()) {
+ count = message_reflection->FieldSize(message, field);
+ } else if (message_reflection->HasField(message, field)) {
+ count = 1;
+ }
+
+ const bool is_packed = field->options().packed();
+ if (is_packed && count > 0) {
+ WireFormatLite::WriteTag(field->number(),
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+ const int data_size = FieldDataOnlyByteSize(field, message);
+ output->WriteVarint32(data_size);
+ }
+
+ for (int j = 0; j < count; j++) {
+ switch (field->type()) {
+#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: { \
+ const CPPTYPE value = field->is_repeated() ? \
+ message_reflection->GetRepeated##CPPTYPE_METHOD( \
+ message, field, j) : \
+ message_reflection->Get##CPPTYPE_METHOD( \
+ message, field); \
+ if (is_packed) { \
+ WireFormatLite::Write##TYPE_METHOD##NoTag(value, output); \
+ } else { \
+ WireFormatLite::Write##TYPE_METHOD(field->number(), value, output); \
+ } \
+ break; \
+ }
+
+ HANDLE_PRIMITIVE_TYPE( INT32, int32, Int32, Int32)
+ HANDLE_PRIMITIVE_TYPE( INT64, int64, Int64, Int64)
+ HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32)
+ HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64)
+ HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
+ HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
+
+ HANDLE_PRIMITIVE_TYPE( FIXED32, uint32, Fixed32, UInt32)
+ HANDLE_PRIMITIVE_TYPE( FIXED64, uint64, Fixed64, UInt64)
+ HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32)
+ HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64)
+
+ HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
+ HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
+
+ HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
+#undef HANDLE_PRIMITIVE_TYPE
+
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: \
+ WireFormatLite::Write##TYPE_METHOD( \
+ field->number(), \
+ field->is_repeated() ? \
+ message_reflection->GetRepeated##CPPTYPE_METHOD( \
+ message, field, j) : \
+ message_reflection->Get##CPPTYPE_METHOD(message, field), \
+ output); \
+ break;
+
+ HANDLE_TYPE(GROUP , Group , Message)
+ HANDLE_TYPE(MESSAGE, Message, Message)
+#undef HANDLE_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ const EnumValueDescriptor* value = field->is_repeated() ?
+ message_reflection->GetRepeatedEnum(message, field, j) :
+ message_reflection->GetEnum(message, field);
+ if (is_packed) {
+ WireFormatLite::WriteEnumNoTag(value->number(), output);
+ } else {
+ WireFormatLite::WriteEnum(field->number(), value->number(), output);
+ }
+ break;
+ }
+
+ // Handle strings separately so that we can get string references
+ // instead of copying.
+ case FieldDescriptor::TYPE_STRING: {
+ string scratch;
+ const string& value = field->is_repeated() ?
+ message_reflection->GetRepeatedStringReference(
+ message, field, j, &scratch) :
+ message_reflection->GetStringReference(message, field, &scratch);
+ VerifyUTF8String(value.data(), value.length(), SERIALIZE);
+ WireFormatLite::WriteString(field->number(), value, output);
+ break;
+ }
+
+ case FieldDescriptor::TYPE_BYTES: {
+ string scratch;
+ const string& value = field->is_repeated() ?
+ message_reflection->GetRepeatedStringReference(
+ message, field, j, &scratch) :
+ message_reflection->GetStringReference(message, field, &scratch);
+ WireFormatLite::WriteBytes(field->number(), value, output);
+ break;
+ }
+ }
+ }
+}
+
+void WireFormat::SerializeMessageSetItemWithCachedSizes(
+ const FieldDescriptor* field,
+ const Message& message,
+ io::CodedOutputStream* output) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ // Start group.
+ output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
+
+ // Write type ID.
+ output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
+ output->WriteVarint32(field->number());
+
+ // Write message.
+ output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
+
+ const Message& sub_message = message_reflection->GetMessage(message, field);
+ output->WriteVarint32(sub_message.GetCachedSize());
+ sub_message.SerializeWithCachedSizes(output);
+
+ // End group.
+ output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
+}
+
+// ===================================================================
+
+int WireFormat::ByteSize(const Message& message) {
+ const Descriptor* descriptor = message.GetDescriptor();
+ const Reflection* message_reflection = message.GetReflection();
+
+ int our_size = 0;
+
+ vector<const FieldDescriptor*> fields;
+ message_reflection->ListFields(message, &fields);
+ for (int i = 0; i < fields.size(); i++) {
+ our_size += FieldByteSize(fields[i], message);
+ }
+
+ if (descriptor->options().message_set_wire_format()) {
+ our_size += WireFormatLite::ComputeUnknownMessageSetItemsSize(
+ message_reflection->GetUnknownFields(message));
+ } else {
+ our_size += WireFormatLite::ComputeUnknownFieldsSize(
+ message_reflection->GetUnknownFields(message));
+ }
+
+ return our_size;
+}
+
+int WireFormat::FieldByteSize(
+ const FieldDescriptor* field,
+ const Message& message) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ if (field->is_extension() &&
+ field->containing_type()->options().message_set_wire_format() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_repeated()) {
+ return MessageSetItemByteSize(field, message);
+ }
+
+ int count = 0;
+ if (field->is_repeated()) {
+ count = message_reflection->FieldSize(message, field);
+ } else if (message_reflection->HasField(message, field)) {
+ count = 1;
+ }
+
+ const int data_size = FieldDataOnlyByteSize(field, message);
+ int our_size = data_size;
+ if (field->options().packed()) {
+ if (data_size > 0) {
+ // Packed fields get serialized like a string, not their native type.
+ // Technically this doesn't really matter; the size only changes if it's
+ // a GROUP
+ our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
+ our_size += io::CodedOutputStream::VarintSize32(data_size);
+ }
+ } else {
+ our_size += count * TagSize(field->number(), field->type());
+ }
+ return our_size;
+}
+
+int WireFormat::FieldDataOnlyByteSize(
+ const FieldDescriptor* field,
+ const Message& message) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ int count = 0;
+ if (field->is_repeated()) {
+ count = message_reflection->FieldSize(message, field);
+ } else if (message_reflection->HasField(message, field)) {
+ count = 1;
+ }
+
+ int data_size = 0;
+ switch (field->type()) {
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: \
+ if (field->is_repeated()) { \
+ for (int j = 0; j < count; j++) { \
+ data_size += WireFormatLite::TYPE_METHOD##Size( \
+ message_reflection->GetRepeated##CPPTYPE_METHOD( \
+ message, field, j)); \
+ } \
+ } else { \
+ data_size += WireFormatLite::TYPE_METHOD##Size( \
+ message_reflection->Get##CPPTYPE_METHOD(message, field)); \
+ } \
+ break;
+
+#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \
+ case FieldDescriptor::TYPE_##TYPE: \
+ data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \
+ break;
+
+ HANDLE_TYPE( INT32, Int32, Int32)
+ HANDLE_TYPE( INT64, Int64, Int64)
+ HANDLE_TYPE(SINT32, SInt32, Int32)
+ HANDLE_TYPE(SINT64, SInt64, Int64)
+ HANDLE_TYPE(UINT32, UInt32, UInt32)
+ HANDLE_TYPE(UINT64, UInt64, UInt64)
+
+ HANDLE_FIXED_TYPE( FIXED32, Fixed32)
+ HANDLE_FIXED_TYPE( FIXED64, Fixed64)
+ HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
+ HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
+
+ HANDLE_FIXED_TYPE(FLOAT , Float )
+ HANDLE_FIXED_TYPE(DOUBLE, Double)
+
+ HANDLE_FIXED_TYPE(BOOL, Bool)
+
+ HANDLE_TYPE(GROUP , Group , Message)
+ HANDLE_TYPE(MESSAGE, Message, Message)
+#undef HANDLE_TYPE
+#undef HANDLE_FIXED_TYPE
+
+ case FieldDescriptor::TYPE_ENUM: {
+ if (field->is_repeated()) {
+ for (int j = 0; j < count; j++) {
+ data_size += WireFormatLite::EnumSize(
+ message_reflection->GetRepeatedEnum(message, field, j)->number());
+ }
+ } else {
+ data_size += WireFormatLite::EnumSize(
+ message_reflection->GetEnum(message, field)->number());
+ }
+ break;
+ }
+
+ // Handle strings separately so that we can get string references
+ // instead of copying.
+ case FieldDescriptor::TYPE_STRING:
+ case FieldDescriptor::TYPE_BYTES: {
+ for (int j = 0; j < count; j++) {
+ string scratch;
+ const string& value = field->is_repeated() ?
+ message_reflection->GetRepeatedStringReference(
+ message, field, j, &scratch) :
+ message_reflection->GetStringReference(message, field, &scratch);
+ data_size += WireFormatLite::StringSize(value);
+ }
+ break;
+ }
+ }
+ return data_size;
+}
+
+int WireFormat::MessageSetItemByteSize(
+ const FieldDescriptor* field,
+ const Message& message) {
+ const Reflection* message_reflection = message.GetReflection();
+
+ int our_size = WireFormatLite::kMessageSetItemTagsSize;
+
+ // type_id
+ our_size += io::CodedOutputStream::VarintSize32(field->number());
+
+ // message
+ const Message& sub_message = message_reflection->GetMessage(message, field);
+ int message_size = sub_message.ByteSize();
+
+ our_size += io::CodedOutputStream::VarintSize32(message_size);
+ our_size += message_size;
+
+ return our_size;
+}
+
+void WireFormat::VerifyUTF8StringFallback(const char* data,
+ int size,
+ Operation op) {
+ if (!IsStructurallyValidUTF8(data, size)) {
+ const char* operation_str = NULL;
+ switch (op) {
+ case PARSE:
+ operation_str = "parsing";
+ break;
+ case SERIALIZE:
+ operation_str = "serializing";
+ break;
+ // no default case: have the compiler warn if a case is not covered.
+ }
+ GOOGLE_LOG(ERROR) << "Encountered string containing invalid UTF-8 data while "
+ << operation_str
+ << " protocol buffer. Strings must contain only UTF-8; "
+ "use the 'bytes' type for raw bytes.";
+ }
+}
+
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/wire_format.h b/src/third_party/protobuf/src/google/protobuf/wire_format.h
new file mode 100644
index 0000000..d52bc4a
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/wire_format.h
@@ -0,0 +1,240 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// atenasio@google.com (Chris Atenasio) (ZigZag transform)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__
+
+#include <string>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/wire_format_lite.h>
+
+// Do UTF-8 validation on string type in Debug build only
+#ifndef NDEBUG
+#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+#endif
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class CodedInputStream; // coded_stream.h
+ class CodedOutputStream; // coded_stream.h
+ }
+ class UnknownFieldSet; // unknown_field_set.h
+}
+
+namespace protobuf {
+namespace internal {
+
+// This class is for internal use by the protocol buffer library and by
+// protocol-complier-generated message classes. It must not be called
+// directly by clients.
+//
+// This class contains code for implementing the binary protocol buffer
+// wire format via reflection. The WireFormatLite class implements the
+// non-reflection based routines.
+//
+// This class is really a namespace that contains only static methods
+class LIBPROTOBUF_EXPORT WireFormat {
+ public:
+
+ // Given a field return its WireType
+ static inline WireFormatLite::WireType WireTypeForField(
+ const FieldDescriptor* field);
+
+ // Given a FieldSescriptor::Type return its WireType
+ static inline WireFormatLite::WireType WireTypeForFieldType(
+ FieldDescriptor::Type type);
+
+ // Compute the byte size of a tag. For groups, this includes both the start
+ // and end tags.
+ static inline int TagSize(int field_number, FieldDescriptor::Type type);
+
+ // These procedures can be used to implement the methods of Message which
+ // handle parsing and serialization of the protocol buffer wire format
+ // using only the Reflection interface. When you ask the protocol
+ // compiler to optimize for code size rather than speed, it will implement
+ // those methods in terms of these procedures. Of course, these are much
+ // slower than the specialized implementations which the protocol compiler
+ // generates when told to optimize for speed.
+
+ // Read a message in protocol buffer wire format.
+ //
+ // This procedure reads either to the end of the input stream or through
+ // a WIRETYPE_END_GROUP tag ending the message, whichever comes first.
+ // It returns false if the input is invalid.
+ //
+ // Required fields are NOT checked by this method. You must call
+ // IsInitialized() on the resulting message yourself.
+ static bool ParseAndMergePartial(io::CodedInputStream* input,
+ Message* message);
+
+ // Serialize a message in protocol buffer wire format.
+ //
+ // Any embedded messages within the message must have their correct sizes
+ // cached. However, the top-level message need not; its size is passed as
+ // a parameter to this procedure.
+ //
+ // These return false iff the underlying stream returns a write error.
+ static void SerializeWithCachedSizes(
+ const Message& message,
+ int size, io::CodedOutputStream* output);
+
+ // Implements Message::ByteSize() via reflection. WARNING: The result
+ // of this method is *not* cached anywhere. However, all embedded messages
+ // will have their ByteSize() methods called, so their sizes will be cached.
+ // Therefore, calling this method is sufficient to allow you to call
+ // WireFormat::SerializeWithCachedSizes() on the same object.
+ static int ByteSize(const Message& message);
+
+
+ // Helper functions for encoding and decoding tags. (Inlined below and in
+ // _inl.h)
+ //
+ // This is different from MakeTag(field->number(), field->type()) in the case
+ // of packed repeated fields.
+ static uint32 MakeTag(const FieldDescriptor* field);
+
+ // Parse a single field. The input should start out positioned immidately
+ // after the tag.
+ static bool ParseAndMergeField(
+ uint32 tag,
+ const FieldDescriptor* field, // May be NULL for unknown
+ Message* message,
+ io::CodedInputStream* input);
+
+ // Serialize a single field.
+ static void SerializeFieldWithCachedSizes(
+ const FieldDescriptor* field, // Cannot be NULL
+ const Message& message,
+ io::CodedOutputStream* output);
+
+ // Compute size of a single field. If the field is a message type, this
+ // will call ByteSize() for the embedded message, insuring that it caches
+ // its size.
+ static int FieldByteSize(
+ const FieldDescriptor* field, // Cannot be NULL
+ const Message& message);
+
+ // Parse/serialize a MessageSet::Item group. Used with messages that use
+ // opion message_set_wire_format = true.
+ static bool ParseAndMergeMessageSetItem(
+ io::CodedInputStream* input,
+ Message* message);
+ static void SerializeMessageSetItemWithCachedSizes(
+ const FieldDescriptor* field,
+ const Message& message,
+ io::CodedOutputStream* output);
+ static int MessageSetItemByteSize(
+ const FieldDescriptor* field,
+ const Message& message);
+
+ // Computes the byte size of a field, excluding tags. For packed fields, it
+ // only includes the size of the raw data, and not the size of the total
+ // length, but for other length-delimited types, the size of the length is
+ // included.
+ static int FieldDataOnlyByteSize(
+ const FieldDescriptor* field, // Cannot be NULL
+ const Message& message);
+
+ enum Operation {
+ PARSE,
+ SERIALIZE,
+ };
+
+ // Verifies that a string field is valid UTF8, logging an error if not.
+ static void VerifyUTF8String(const char* data, int size, Operation op);
+
+ private:
+ // Verifies that a string field is valid UTF8, logging an error if not.
+ static void VerifyUTF8StringFallback(
+ const char* data,
+ int size,
+ Operation op);
+
+
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat);
+};
+
+// inline methods ====================================================
+
+inline WireFormatLite::WireType WireFormat::WireTypeForField(
+ const FieldDescriptor* field) {
+ if (field->options().packed()) {
+ return WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+ } else {
+ return WireTypeForFieldType(field->type());
+ }
+}
+
+inline WireFormatLite::WireType WireFormat::WireTypeForFieldType(
+ FieldDescriptor::Type type) {
+ // Some compilers don't like enum -> enum casts, so we implicit_cast to
+ // int first.
+ return WireFormatLite::WireTypeForFieldType(
+ static_cast<WireFormatLite::FieldType>(
+ implicit_cast<int>(type)));
+}
+
+inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) {
+ return WireFormatLite::MakeTag(field->number(), WireTypeForField(field));
+}
+
+inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) {
+ // Some compilers don't like enum -> enum casts, so we implicit_cast to
+ // int first.
+ return WireFormatLite::TagSize(field_number,
+ static_cast<WireFormatLite::FieldType>(
+ implicit_cast<int>(type)));
+}
+
+inline void WireFormat::VerifyUTF8String(const char* data, int size,
+ WireFormat::Operation op) {
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ WireFormat::VerifyUTF8StringFallback(data, size, op);
+#endif
+}
+
+
+} // namespace internal
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/wire_format_lite.cc b/src/third_party/protobuf/src/google/protobuf/wire_format_lite.cc
new file mode 100644
index 0000000..3bf9268
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/wire_format_lite.cc
@@ -0,0 +1,584 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/wire_format_lite_inl.h>
+
+#include <stack>
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream_inl.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/unknown_field_set.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC
+ // requires them.
+const int WireFormatLite::kMessageSetItemStartTag;
+const int WireFormatLite::kMessageSetItemEndTag;
+const int WireFormatLite::kMessageSetTypeIdTag;
+const int WireFormatLite::kMessageSetMessageTag;
+
+#endif
+
+// ===================================================================
+
+bool FieldSkipper::SkipField(
+ io::CodedInputStream* input, uint32 tag) {
+ return WireFormatLite::SkipField(input, tag, unknown_fields_);
+}
+
+bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
+ return WireFormatLite::SkipMessage(input, unknown_fields_);
+}
+
+void FieldSkipper::SkipUnknownEnum(
+ int field_number, int value) {
+ unknown_fields_->AddVarint(field_number, value);
+}
+
+// ===================================================================
+
+const int WireFormatLite::kMessageSetItemTagsSize =
+ io::CodedOutputStream::StaticVarintSize32<kMessageSetItemStartTag>::value +
+ io::CodedOutputStream::StaticVarintSize32<kMessageSetItemEndTag>::value +
+ io::CodedOutputStream::StaticVarintSize32<kMessageSetTypeIdTag>::value +
+ io::CodedOutputStream::StaticVarintSize32<kMessageSetMessageTag>::value;
+
+const WireFormatLite::CppType
+WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
+ static_cast<CppType>(0), // 0 is reserved for errors
+
+ CPPTYPE_DOUBLE, // TYPE_DOUBLE
+ CPPTYPE_FLOAT, // TYPE_FLOAT
+ CPPTYPE_INT64, // TYPE_INT64
+ CPPTYPE_UINT64, // TYPE_UINT64
+ CPPTYPE_INT32, // TYPE_INT32
+ CPPTYPE_UINT64, // TYPE_FIXED64
+ CPPTYPE_UINT32, // TYPE_FIXED32
+ CPPTYPE_BOOL, // TYPE_BOOL
+ CPPTYPE_STRING, // TYPE_STRING
+ CPPTYPE_MESSAGE, // TYPE_GROUP
+ CPPTYPE_MESSAGE, // TYPE_MESSAGE
+ CPPTYPE_STRING, // TYPE_BYTES
+ CPPTYPE_UINT32, // TYPE_UINT32
+ CPPTYPE_ENUM, // TYPE_ENUM
+ CPPTYPE_INT32, // TYPE_SFIXED32
+ CPPTYPE_INT64, // TYPE_SFIXED64
+ CPPTYPE_INT32, // TYPE_SINT32
+ CPPTYPE_INT64, // TYPE_SINT64
+};
+
+const WireFormatLite::WireType
+WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
+ static_cast<WireFormatLite::WireType>(-1), // invalid
+ WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE
+ WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32
+ WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64
+ WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING
+ WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM
+ WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32
+ WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32
+ WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64
+};
+
+bool WireFormatLite::SkipField(io::CodedInputStream* input, uint32 tag,
+ UnknownFieldSet* unknown_fields) {
+ int number = WireFormatLite::GetTagFieldNumber(tag);
+
+ switch (WireFormatLite::GetTagWireType(tag)) {
+ case WireFormatLite::WIRETYPE_VARINT: {
+ uint64 value;
+ if (!input->ReadVarint64(&value)) return false;
+ if (unknown_fields != NULL) unknown_fields->AddVarint(number, value);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_FIXED64: {
+ uint64 value;
+ if (!input->ReadLittleEndian64(&value)) return false;
+ if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value);
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (unknown_fields == NULL) {
+ if (!input->Skip(length)) return false;
+ } else {
+ if (!input->ReadString(unknown_fields->AddLengthDelimited(number),
+ length)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_START_GROUP: {
+ if (!input->IncrementRecursionDepth()) return false;
+ if (!SkipMessage(input, (unknown_fields == NULL) ?
+ NULL : unknown_fields->AddGroup(number))) {
+ return false;
+ }
+ input->DecrementRecursionDepth();
+ // Check that the ending tag matched the starting tag.
+ if (!input->LastTagWas(WireFormatLite::MakeTag(
+ WireFormatLite::GetTagFieldNumber(tag),
+ WireFormatLite::WIRETYPE_END_GROUP))) {
+ return false;
+ }
+ return true;
+ }
+ case WireFormatLite::WIRETYPE_END_GROUP: {
+ return false;
+ }
+ case WireFormatLite::WIRETYPE_FIXED32: {
+ uint32 value;
+ if (!input->ReadLittleEndian32(&value)) return false;
+ if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value);
+ return true;
+ }
+ default: {
+ return false;
+ }
+ }
+}
+
+bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
+ UnknownFieldSet* unknown_fields) {
+ while(true) {
+ uint32 tag = input->ReadTag();
+ if (tag == 0) {
+ // End of input. This is a valid place to end, so return true.
+ return true;
+ }
+
+ WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+
+ if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
+ // Must be the end of the message.
+ return true;
+ }
+
+ if (!SkipField(input, tag, unknown_fields)) return false;
+ }
+}
+
+void WireFormatLite::SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
+ io::CodedOutputStream* output) {
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ const UnknownField& field = unknown_fields.field(i);
+ switch (field.type()) {
+ case UnknownField::TYPE_VARINT:
+ output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_VARINT));
+ output->WriteVarint64(field.varint());
+ break;
+ case UnknownField::TYPE_FIXED32:
+ output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_FIXED32));
+ output->WriteLittleEndian32(field.fixed32());
+ break;
+ case UnknownField::TYPE_FIXED64:
+ output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_FIXED64));
+ output->WriteLittleEndian64(field.fixed64());
+ break;
+ case UnknownField::TYPE_LENGTH_DELIMITED:
+ output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
+ output->WriteVarint32(field.length_delimited().size());
+ output->WriteString(field.length_delimited());
+ break;
+ case UnknownField::TYPE_GROUP:
+ output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_START_GROUP));
+ SerializeUnknownFields(field.group(), output);
+ output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_END_GROUP));
+ break;
+ }
+ }
+}
+
+uint8* WireFormatLite::SerializeUnknownFieldsToArray(
+ const UnknownFieldSet& unknown_fields,
+ uint8* target) {
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ const UnknownField& field = unknown_fields.field(i);
+
+ switch (field.type()) {
+ case UnknownField::TYPE_VARINT:
+ target = WireFormatLite::WriteInt64ToArray(
+ field.number(), field.varint(), target);
+ break;
+ case UnknownField::TYPE_FIXED32:
+ target = WireFormatLite::WriteFixed32ToArray(
+ field.number(), field.fixed32(), target);
+ break;
+ case UnknownField::TYPE_FIXED64:
+ target = WireFormatLite::WriteFixed64ToArray(
+ field.number(), field.fixed64(), target);
+ break;
+ case UnknownField::TYPE_LENGTH_DELIMITED:
+ target = WireFormatLite::WriteBytesToArray(
+ field.number(), field.length_delimited(), target);
+ break;
+ case UnknownField::TYPE_GROUP:
+ target = WireFormatLite::WriteTagToArray(
+ field.number(), WireFormatLite::WIRETYPE_START_GROUP, target);
+ target = SerializeUnknownFieldsToArray(field.group(), target);
+ target = WireFormatLite::WriteTagToArray(
+ field.number(), WireFormatLite::WIRETYPE_END_GROUP, target);
+ break;
+ }
+ }
+ return target;
+}
+
+void WireFormatLite::SerializeUnknownMessageSetItems(
+ const UnknownFieldSet& unknown_fields,
+ io::CodedOutputStream* output) {
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ const UnknownField& field = unknown_fields.field(i);
+ // The only unknown fields that are allowed to exist in a MessageSet are
+ // messages, which are length-delimited.
+ if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
+ const string& data = field.length_delimited();
+
+ // Start group.
+ output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
+
+ // Write type ID.
+ output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
+ output->WriteVarint32(field.number());
+
+ // Write message.
+ output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
+ output->WriteVarint32(data.size());
+ output->WriteString(data);
+
+ // End group.
+ output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
+ }
+ }
+}
+
+uint8* WireFormatLite::SerializeUnknownMessageSetItemsToArray(
+ const UnknownFieldSet& unknown_fields,
+ uint8* target) {
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ const UnknownField& field = unknown_fields.field(i);
+
+ // The only unknown fields that are allowed to exist in a MessageSet are
+ // messages, which are length-delimited.
+ if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
+ const string& data = field.length_delimited();
+
+ // Start group.
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetItemStartTag, target);
+
+ // Write type ID.
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetTypeIdTag, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(
+ field.number(), target);
+
+ // Write message.
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetMessageTag, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
+ target = io::CodedOutputStream::WriteStringToArray(data, target);
+
+ // End group.
+ target = io::CodedOutputStream::WriteTagToArray(
+ WireFormatLite::kMessageSetItemEndTag, target);
+ }
+ }
+
+ return target;
+}
+
+int WireFormatLite::ComputeUnknownFieldsSize(
+ const UnknownFieldSet& unknown_fields) {
+ int size = 0;
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ const UnknownField& field = unknown_fields.field(i);
+
+ switch (field.type()) {
+ case UnknownField::TYPE_VARINT:
+ size += io::CodedOutputStream::VarintSize32(
+ WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_VARINT));
+ size += io::CodedOutputStream::VarintSize64(field.varint());
+ break;
+ case UnknownField::TYPE_FIXED32:
+ size += io::CodedOutputStream::VarintSize32(
+ WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_FIXED32));
+ size += sizeof(int32);
+ break;
+ case UnknownField::TYPE_FIXED64:
+ size += io::CodedOutputStream::VarintSize32(
+ WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_FIXED64));
+ size += sizeof(int64);
+ break;
+ case UnknownField::TYPE_LENGTH_DELIMITED:
+ size += io::CodedOutputStream::VarintSize32(
+ WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
+ size += io::CodedOutputStream::VarintSize32(
+ field.length_delimited().size());
+ size += field.length_delimited().size();
+ break;
+ case UnknownField::TYPE_GROUP:
+ size += io::CodedOutputStream::VarintSize32(
+ WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_START_GROUP));
+ size += ComputeUnknownFieldsSize(field.group());
+ size += io::CodedOutputStream::VarintSize32(
+ WireFormatLite::MakeTag(field.number(),
+ WireFormatLite::WIRETYPE_END_GROUP));
+ break;
+ }
+ }
+
+ return size;
+}
+
+int WireFormatLite::ComputeUnknownMessageSetItemsSize(
+ const UnknownFieldSet& unknown_fields) {
+ int size = 0;
+ for (int i = 0; i < unknown_fields.field_count(); i++) {
+ const UnknownField& field = unknown_fields.field(i);
+
+ // The only unknown fields that are allowed to exist in a MessageSet are
+ // messages, which are length-delimited.
+ if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
+ size += WireFormatLite::kMessageSetItemTagsSize;
+ size += io::CodedOutputStream::VarintSize32(field.number());
+ size += io::CodedOutputStream::VarintSize32(
+ field.length_delimited().size());
+ size += field.length_delimited().size();
+ }
+ }
+
+ return size;
+}
+
+bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
+ bool (*is_valid)(int),
+ RepeatedField<int>* values) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ io::CodedInputStream::Limit limit = input->PushLimit(length);
+ while (input->BytesUntilLimit() > 0) {
+ int value;
+ if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, WireFormatLite::TYPE_ENUM>(input, &value)) {
+ return false;
+ }
+ if (is_valid(value)) {
+ values->Add(value);
+ }
+ }
+ input->PopLimit(limit);
+ return true;
+}
+
+void WireFormatLite::WriteInt32(int field_number, int32 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteInt32NoTag(value, output);
+}
+void WireFormatLite::WriteInt64(int field_number, int64 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteInt64NoTag(value, output);
+}
+void WireFormatLite::WriteUInt32(int field_number, uint32 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteUInt32NoTag(value, output);
+}
+void WireFormatLite::WriteUInt64(int field_number, uint64 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteUInt64NoTag(value, output);
+}
+void WireFormatLite::WriteSInt32(int field_number, int32 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteSInt32NoTag(value, output);
+}
+void WireFormatLite::WriteSInt64(int field_number, int64 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteSInt64NoTag(value, output);
+}
+void WireFormatLite::WriteFixed32(int field_number, uint32 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED32, output);
+ WriteFixed32NoTag(value, output);
+}
+void WireFormatLite::WriteFixed64(int field_number, uint64 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED64, output);
+ WriteFixed64NoTag(value, output);
+}
+void WireFormatLite::WriteSFixed32(int field_number, int32 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED32, output);
+ WriteSFixed32NoTag(value, output);
+}
+void WireFormatLite::WriteSFixed64(int field_number, int64 value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED64, output);
+ WriteSFixed64NoTag(value, output);
+}
+void WireFormatLite::WriteFloat(int field_number, float value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED32, output);
+ WriteFloatNoTag(value, output);
+}
+void WireFormatLite::WriteDouble(int field_number, double value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_FIXED64, output);
+ WriteDoubleNoTag(value, output);
+}
+void WireFormatLite::WriteBool(int field_number, bool value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteBoolNoTag(value, output);
+}
+void WireFormatLite::WriteEnum(int field_number, int value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_VARINT, output);
+ WriteEnumNoTag(value, output);
+}
+
+void WireFormatLite::WriteString(int field_number, const string& value,
+ io::CodedOutputStream* output) {
+ // String is for UTF-8 text only
+ WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(value.size());
+ output->WriteString(value);
+}
+void WireFormatLite::WriteBytes(int field_number, const string& value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(value.size());
+ output->WriteString(value);
+}
+
+
+void WireFormatLite::WriteGroup(int field_number,
+ const MessageLite& value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_START_GROUP, output);
+ value.SerializeWithCachedSizes(output);
+ WriteTag(field_number, WIRETYPE_END_GROUP, output);
+}
+
+void WireFormatLite::WriteMessage(int field_number,
+ const MessageLite& value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+ const int size = value.GetCachedSize();
+ output->WriteVarint32(size);
+ value.SerializeWithCachedSizes(output);
+}
+
+void WireFormatLite::WriteGroupMaybeToArray(int field_number,
+ const MessageLite& value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_START_GROUP, output);
+ const int size = value.GetCachedSize();
+ uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
+ if (target != NULL) {
+ uint8* end = value.SerializeWithCachedSizesToArray(target);
+ GOOGLE_DCHECK_EQ(end - target, size);
+ } else {
+ value.SerializeWithCachedSizes(output);
+ }
+ WriteTag(field_number, WIRETYPE_END_GROUP, output);
+}
+
+void WireFormatLite::WriteMessageMaybeToArray(int field_number,
+ const MessageLite& value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+ const int size = value.GetCachedSize();
+ output->WriteVarint32(size);
+ uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
+ if (target != NULL) {
+ uint8* end = value.SerializeWithCachedSizesToArray(target);
+ GOOGLE_DCHECK_EQ(end - target, size);
+ } else {
+ value.SerializeWithCachedSizes(output);
+ }
+}
+
+bool WireFormatLite::ReadString(io::CodedInputStream* input,
+ string* value) {
+ // String is for UTF-8 text only
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (!input->InternalReadStringInline(value, length)) return false;
+ return true;
+}
+bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
+ string* value) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ return input->InternalReadStringInline(value, length);
+}
+
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/src/google/protobuf/wire_format_lite.h b/src/third_party/protobuf/src/google/protobuf/wire_format_lite.h
new file mode 100644
index 0000000..eea23f3
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/wire_format_lite.h
@@ -0,0 +1,669 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// atenasio@google.com (Chris Atenasio) (ZigZag transform)
+// wink@google.com (Wink Saville) (refactored from wire_format.h)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+
+#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
+
+#include <string>
+#include <google/protobuf/message_lite.h>
+
+namespace google {
+
+namespace protobuf {
+ template <typename T> class RepeatedField; // repeated_field.h
+ namespace io {
+ class CodedInputStream; // coded_stream.h
+ class CodedOutputStream; // coded_stream.h
+ }
+ class UnknownFieldSet;
+}
+
+namespace protobuf {
+namespace internal {
+
+class StringPieceField;
+
+// This class is for internal use by the protocol buffer library and by
+// protocol-complier-generated message classes. It must not be called
+// directly by clients.
+//
+// This class contains helpers for implementing the binary protocol buffer
+// wire format without the need for reflection. Use WireFormat when using
+// reflection.
+//
+// This class is really a namespace that contains only static methods.
+class LIBPROTOBUF_EXPORT WireFormatLite {
+ public:
+
+ // -----------------------------------------------------------------
+ // Helper constants and functions related to the format. These are
+ // mostly meant for internal and generated code to use.
+
+ // The wire format is composed of a sequence of tag/value pairs, each
+ // of which contains the value of one field (or one element of a repeated
+ // field). Each tag is encoded as a varint. The lower bits of the tag
+ // identify its wire type, which specifies the format of the data to follow.
+ // The rest of the bits contain the field number. Each type of field (as
+ // declared by FieldDescriptor::Type, in descriptor.h) maps to one of
+ // these wire types. Immediately following each tag is the field's value,
+ // encoded in the format specified by the wire type. Because the tag
+ // identifies the encoding of this data, it is possible to skip
+ // unrecognized fields for forwards compatibility.
+
+ enum WireType {
+ WIRETYPE_VARINT = 0,
+ WIRETYPE_FIXED64 = 1,
+ WIRETYPE_LENGTH_DELIMITED = 2,
+ WIRETYPE_START_GROUP = 3,
+ WIRETYPE_END_GROUP = 4,
+ WIRETYPE_FIXED32 = 5,
+ };
+
+ // Lite alternative to FieldDescriptor::Type. Must be kept in sync.
+ enum FieldType {
+ TYPE_DOUBLE = 1,
+ TYPE_FLOAT = 2,
+ TYPE_INT64 = 3,
+ TYPE_UINT64 = 4,
+ TYPE_INT32 = 5,
+ TYPE_FIXED64 = 6,
+ TYPE_FIXED32 = 7,
+ TYPE_BOOL = 8,
+ TYPE_STRING = 9,
+ TYPE_GROUP = 10,
+ TYPE_MESSAGE = 11,
+ TYPE_BYTES = 12,
+ TYPE_UINT32 = 13,
+ TYPE_ENUM = 14,
+ TYPE_SFIXED32 = 15,
+ TYPE_SFIXED64 = 16,
+ TYPE_SINT32 = 17,
+ TYPE_SINT64 = 18,
+ MAX_FIELD_TYPE = 18,
+ };
+
+ // Lite alternative to FieldDescriptor::CppType. Must be kept in sync.
+ enum CppType {
+ CPPTYPE_INT32 = 1,
+ CPPTYPE_INT64 = 2,
+ CPPTYPE_UINT32 = 3,
+ CPPTYPE_UINT64 = 4,
+ CPPTYPE_DOUBLE = 5,
+ CPPTYPE_FLOAT = 6,
+ CPPTYPE_BOOL = 7,
+ CPPTYPE_ENUM = 8,
+ CPPTYPE_STRING = 9,
+ CPPTYPE_MESSAGE = 10,
+ MAX_CPPTYPE = 10,
+ };
+
+ // Helper method to get the CppType for a particular Type.
+ static CppType FieldTypeToCppType(FieldType type);
+
+ // Given a FieldSescriptor::Type return its WireType
+ static inline WireFormatLite::WireType WireTypeForFieldType(
+ WireFormatLite::FieldType type) {
+ return kWireTypeForFieldType[type];
+ }
+
+ // Number of bits in a tag which identify the wire type.
+ static const int kTagTypeBits = 3;
+ // Mask for those bits.
+ static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1;
+
+ // Helper functions for encoding and decoding tags. (Inlined below and in
+ // _inl.h)
+ //
+ // This is different from MakeTag(field->number(), field->type()) in the case
+ // of packed repeated fields.
+ static uint32 MakeTag(int field_number, WireType type);
+ static WireType GetTagWireType(uint32 tag);
+ static int GetTagFieldNumber(uint32 tag);
+
+ // Compute the byte size of a tag. For groups, this includes both the start
+ // and end tags.
+ static inline int TagSize(int field_number, WireFormatLite::FieldType type);
+
+ // -----------------------------------------------------------------
+ // Helpers for dealing with unknown fields
+
+ // Skips a field value with the given tag. The input should start
+ // positioned immediately after the tag. Skipped values are simply discarded,
+ // not recorded anywhere. See WireFormat::SkipField() for a version that
+ // records to an UnknownFieldSet.
+ // TODO(xiaomings, b/21405951): The optional value NULL for unknown_field was
+ // added to make it compatible with protoc-2.4.0. This should be removed once
+ // we can compile protoc from source code.
+ static bool SkipField(io::CodedInputStream* input,
+ uint32 tag,
+ UnknownFieldSet* unknown_fields = NULL);
+
+ // Reads and ignores a message from the input. If unknown_fields is non-NULL,
+ // the contents will be added to it.
+ static bool SkipMessage(io::CodedInputStream* input,
+ UnknownFieldSet* unknown_fields);
+
+
+ // Reads and ignores a message from the input. Skipped values may be stored
+ // in the UnknownFieldSet if it exists.
+ static bool SkipMessage(io::CodedInputStream* input);
+
+// This macro does the same thing as WireFormatLite::MakeTag(), but the
+// result is usable as a compile-time constant, which makes it usable
+// as a switch case or a template input. WireFormatLite::MakeTag() is more
+// type-safe, though, so prefer it if possible.
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \
+ static_cast<uint32>( \
+ ((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \
+ | (TYPE))
+
+ // These are the tags for the old MessageSet format, which was defined as:
+ // message MessageSet {
+ // repeated group Item = 1 {
+ // required int32 type_id = 2;
+ // required string message = 3;
+ // }
+ // }
+ static const int kMessageSetItemNumber = 1;
+ static const int kMessageSetTypeIdNumber = 2;
+ static const int kMessageSetMessageNumber = 3;
+ static const int kMessageSetItemStartTag =
+ GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
+ WireFormatLite::WIRETYPE_START_GROUP);
+ static const int kMessageSetItemEndTag =
+ GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
+ WireFormatLite::WIRETYPE_END_GROUP);
+ static const int kMessageSetTypeIdTag =
+ GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber,
+ WireFormatLite::WIRETYPE_VARINT);
+ static const int kMessageSetMessageTag =
+ GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber,
+ WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+
+ // Byte size of all tags of a MessageSet::Item combined.
+ static const int kMessageSetItemTagsSize;
+
+ // Helper functions for converting between floats/doubles and IEEE-754
+ // uint32s/uint64s so that they can be written. (Assumes your platform
+ // uses IEEE-754 floats.)
+ static uint32 EncodeFloat(float value);
+ static float DecodeFloat(uint32 value);
+ static uint64 EncodeDouble(double value);
+ static double DecodeDouble(uint64 value);
+
+ // Helper functions for mapping signed integers to unsigned integers in
+ // such a way that numbers with small magnitudes will encode to smaller
+ // varints. If you simply static_cast a negative number to an unsigned
+ // number and varint-encode it, it will always take 10 bytes, defeating
+ // the purpose of varint. So, for the "sint32" and "sint64" field types,
+ // we ZigZag-encode the values.
+ static uint32 ZigZagEncode32(int32 n);
+ static int32 ZigZagDecode32(uint32 n);
+ static uint64 ZigZagEncode64(int64 n);
+ static int64 ZigZagDecode64(uint64 n);
+
+ // Write the contents of an UnknownFieldSet to the output.
+ static void SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
+ io::CodedOutputStream* output);
+ // Same as above, except writing directly to the provided buffer.
+ // Requires that the buffer have sufficient capacity for
+ // ComputeUnknownFieldsSize(unknown_fields).
+ //
+ // Returns a pointer past the last written byte.
+ static uint8* SerializeUnknownFieldsToArray(
+ const UnknownFieldSet& unknown_fields,
+ uint8* target);
+
+ // Same thing except for messages that have the message_set_wire_format
+ // option.
+ static void SerializeUnknownMessageSetItems(
+ const UnknownFieldSet& unknown_fields,
+ io::CodedOutputStream* output);
+ // Same as above, except writing directly to the provided buffer.
+ // Requires that the buffer have sufficient capacity for
+ // ComputeUnknownMessageSetItemsSize(unknown_fields).
+ //
+ // Returns a pointer past the last written byte.
+ static uint8* SerializeUnknownMessageSetItemsToArray(
+ const UnknownFieldSet& unknown_fields,
+ uint8* target);
+
+ // Compute the size of the UnknownFieldSet on the wire.
+ static int ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields);
+
+ // Same thing except for messages that have the message_set_wire_format
+ // option.
+ static int ComputeUnknownMessageSetItemsSize(
+ const UnknownFieldSet& unknown_fields);
+
+ // =================================================================
+ // Methods for reading/writing individual field. The implementations
+ // of these methods are defined in wire_format_lite_inl.h; you must #include
+ // that file to use these.
+
+// Avoid ugly line wrapping
+#define input io::CodedInputStream* input
+#define output io::CodedOutputStream* output
+#define field_number int field_number
+#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+
+ // Read fields, not including tags. The assumption is that you already
+ // read the tag to determine what field to read.
+
+ // For primitive fields, we just use a templatized routine parameterized by
+ // the represented type and the FieldType. These are specialized with the
+ // appropriate definition for each declared type.
+ template <typename CType, enum FieldType DeclaredType>
+ static inline bool ReadPrimitive(input, CType* value) INL;
+
+ // Reads repeated primitive values, with optimizations for repeats.
+ // tag_size and tag should both be compile-time constants provided by the
+ // protocol compiler.
+ template <typename CType, enum FieldType DeclaredType>
+ static inline bool ReadRepeatedPrimitive(int tag_size,
+ uint32 tag,
+ input,
+ RepeatedField<CType>* value) INL;
+
+ // Identical to ReadRepeatedPrimitive, except will not inline the
+ // implementation.
+ template <typename CType, enum FieldType DeclaredType>
+ static bool ReadRepeatedPrimitiveNoInline(int tag_size,
+ uint32 tag,
+ input,
+ RepeatedField<CType>* value);
+
+ // Reads a primitive value directly from the provided buffer. It returns a
+ // pointer past the segment of data that was read.
+ //
+ // This is only implemented for the types with fixed wire size, e.g.
+ // float, double, and the (s)fixed* types.
+ template <typename CType, enum FieldType DeclaredType>
+ static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer,
+ CType* value) INL;
+
+ // Reads a primitive packed field.
+ //
+ // This is only implemented for packable types.
+ template <typename CType, enum FieldType DeclaredType>
+ static inline bool ReadPackedPrimitive(input,
+ RepeatedField<CType>* value) INL;
+
+ // Identical to ReadPackedPrimitive, except will not inline the
+ // implementation.
+ template <typename CType, enum FieldType DeclaredType>
+ static bool ReadPackedPrimitiveNoInline(input, RepeatedField<CType>* value);
+
+ // Read a packed enum field. Values for which is_valid() returns false are
+ // dropped.
+ static bool ReadPackedEnumNoInline(input,
+ bool (*is_valid)(int),
+ RepeatedField<int>* value);
+
+ static bool ReadString(input, string* value);
+ static bool ReadBytes (input, string* value);
+
+ static inline bool ReadGroup (field_number, input, MessageLite* value);
+ static inline bool ReadMessage(input, MessageLite* value);
+
+ // Like above, but de-virtualize the call to MergePartialFromCodedStream().
+ // The pointer must point at an instance of MessageType, *not* a subclass (or
+ // the subclass must not override MergePartialFromCodedStream()).
+ template<typename MessageType>
+ static inline bool ReadGroupNoVirtual(field_number, input,
+ MessageType* value);
+ template<typename MessageType>
+ static inline bool ReadMessageNoVirtual(input, MessageType* value);
+
+ // Write a tag. The Write*() functions typically include the tag, so
+ // normally there's no need to call this unless using the Write*NoTag()
+ // variants.
+ static inline void WriteTag(field_number, WireType type, output) INL;
+
+ // Write fields, without tags.
+ static inline void WriteInt32NoTag (int32 value, output) INL;
+ static inline void WriteInt64NoTag (int64 value, output) INL;
+ static inline void WriteUInt32NoTag (uint32 value, output) INL;
+ static inline void WriteUInt64NoTag (uint64 value, output) INL;
+ static inline void WriteSInt32NoTag (int32 value, output) INL;
+ static inline void WriteSInt64NoTag (int64 value, output) INL;
+ static inline void WriteFixed32NoTag (uint32 value, output) INL;
+ static inline void WriteFixed64NoTag (uint64 value, output) INL;
+ static inline void WriteSFixed32NoTag(int32 value, output) INL;
+ static inline void WriteSFixed64NoTag(int64 value, output) INL;
+ static inline void WriteFloatNoTag (float value, output) INL;
+ static inline void WriteDoubleNoTag (double value, output) INL;
+ static inline void WriteBoolNoTag (bool value, output) INL;
+ static inline void WriteEnumNoTag (int value, output) INL;
+
+ // Write fields, including tags.
+ static void WriteInt32 (field_number, int32 value, output);
+ static void WriteInt64 (field_number, int64 value, output);
+ static void WriteUInt32 (field_number, uint32 value, output);
+ static void WriteUInt64 (field_number, uint64 value, output);
+ static void WriteSInt32 (field_number, int32 value, output);
+ static void WriteSInt64 (field_number, int64 value, output);
+ static void WriteFixed32 (field_number, uint32 value, output);
+ static void WriteFixed64 (field_number, uint64 value, output);
+ static void WriteSFixed32(field_number, int32 value, output);
+ static void WriteSFixed64(field_number, int64 value, output);
+ static void WriteFloat (field_number, float value, output);
+ static void WriteDouble (field_number, double value, output);
+ static void WriteBool (field_number, bool value, output);
+ static void WriteEnum (field_number, int value, output);
+
+ static void WriteString(field_number, const string& value, output);
+ static void WriteBytes (field_number, const string& value, output);
+
+ static void WriteGroup(
+ field_number, const MessageLite& value, output);
+ static void WriteMessage(
+ field_number, const MessageLite& value, output);
+ // Like above, but these will check if the output stream has enough
+ // space to write directly to a flat array.
+ static void WriteGroupMaybeToArray(
+ field_number, const MessageLite& value, output);
+ static void WriteMessageMaybeToArray(
+ field_number, const MessageLite& value, output);
+
+ // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
+ // pointer must point at an instance of MessageType, *not* a subclass (or
+ // the subclass must not override SerializeWithCachedSizes()).
+ template<typename MessageType>
+ static inline void WriteGroupNoVirtual(
+ field_number, const MessageType& value, output);
+ template<typename MessageType>
+ static inline void WriteMessageNoVirtual(
+ field_number, const MessageType& value, output);
+
+#undef output
+#define output uint8* target
+
+ // Like above, but use only *ToArray methods of CodedOutputStream.
+ static inline uint8* WriteTagToArray(field_number, WireType type, output) INL;
+
+ // Write fields, without tags.
+ static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL;
+ static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL;
+ static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL;
+ static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL;
+ static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL;
+ static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL;
+ static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL;
+ static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL;
+ static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL;
+ static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL;
+ static inline uint8* WriteFloatNoTagToArray (float value, output) INL;
+ static inline uint8* WriteDoubleNoTagToArray (double value, output) INL;
+ static inline uint8* WriteBoolNoTagToArray (bool value, output) INL;
+ static inline uint8* WriteEnumNoTagToArray (int value, output) INL;
+
+ // Write fields, including tags.
+ static inline uint8* WriteInt32ToArray(
+ field_number, int32 value, output) INL;
+ static inline uint8* WriteInt64ToArray(
+ field_number, int64 value, output) INL;
+ static inline uint8* WriteUInt32ToArray(
+ field_number, uint32 value, output) INL;
+ static inline uint8* WriteUInt64ToArray(
+ field_number, uint64 value, output) INL;
+ static inline uint8* WriteSInt32ToArray(
+ field_number, int32 value, output) INL;
+ static inline uint8* WriteSInt64ToArray(
+ field_number, int64 value, output) INL;
+ static inline uint8* WriteFixed32ToArray(
+ field_number, uint32 value, output) INL;
+ static inline uint8* WriteFixed64ToArray(
+ field_number, uint64 value, output) INL;
+ static inline uint8* WriteSFixed32ToArray(
+ field_number, int32 value, output) INL;
+ static inline uint8* WriteSFixed64ToArray(
+ field_number, int64 value, output) INL;
+ static inline uint8* WriteFloatToArray(
+ field_number, float value, output) INL;
+ static inline uint8* WriteDoubleToArray(
+ field_number, double value, output) INL;
+ static inline uint8* WriteBoolToArray(
+ field_number, bool value, output) INL;
+ static inline uint8* WriteEnumToArray(
+ field_number, int value, output) INL;
+
+ static inline uint8* WriteStringToArray(
+ field_number, const string& value, output) INL;
+ static inline uint8* WriteBytesToArray(
+ field_number, const string& value, output) INL;
+
+ static inline uint8* WriteGroupToArray(
+ field_number, const MessageLite& value, output) INL;
+ static inline uint8* WriteMessageToArray(
+ field_number, const MessageLite& value, output) INL;
+
+ // Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
+ // pointer must point at an instance of MessageType, *not* a subclass (or
+ // the subclass must not override SerializeWithCachedSizes()).
+ template<typename MessageType>
+ static inline uint8* WriteGroupNoVirtualToArray(
+ field_number, const MessageType& value, output) INL;
+ template<typename MessageType>
+ static inline uint8* WriteMessageNoVirtualToArray(
+ field_number, const MessageType& value, output) INL;
+
+#undef output
+#undef input
+#undef INL
+
+#undef field_number
+
+ // Compute the byte size of a field. The XxSize() functions do NOT include
+ // the tag, so you must also call TagSize(). (This is because, for repeated
+ // fields, you should only call TagSize() once and multiply it by the element
+ // count, but you may have to call XxSize() for each individual element.)
+ static inline int Int32Size ( int32 value);
+ static inline int Int64Size ( int64 value);
+ static inline int UInt32Size (uint32 value);
+ static inline int UInt64Size (uint64 value);
+ static inline int SInt32Size ( int32 value);
+ static inline int SInt64Size ( int64 value);
+ static inline int EnumSize ( int value);
+
+ // These types always have the same size.
+ static const int kFixed32Size = 4;
+ static const int kFixed64Size = 8;
+ static const int kSFixed32Size = 4;
+ static const int kSFixed64Size = 8;
+ static const int kFloatSize = 4;
+ static const int kDoubleSize = 8;
+ static const int kBoolSize = 1;
+
+ static inline int StringSize(const string& value);
+ static inline int BytesSize (const string& value);
+
+ static inline int GroupSize (const MessageLite& value);
+ static inline int MessageSize(const MessageLite& value);
+
+ // Like above, but de-virtualize the call to ByteSize(). The
+ // pointer must point at an instance of MessageType, *not* a subclass (or
+ // the subclass must not override ByteSize()).
+ template<typename MessageType>
+ static inline int GroupSizeNoVirtual (const MessageType& value);
+ template<typename MessageType>
+ static inline int MessageSizeNoVirtual(const MessageType& value);
+
+ private:
+ // A helper method for the repeated primitive reader. This method has
+ // optimizations for primitive types that have fixed size on the wire, and
+ // can be read using potentially faster paths.
+ template <typename CType, enum FieldType DeclaredType>
+ static inline bool ReadRepeatedFixedSizePrimitive(
+ int tag_size,
+ uint32 tag,
+ google::protobuf::io::CodedInputStream* input,
+ RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+ static const CppType kFieldTypeToCppTypeMap[];
+ static const WireFormatLite::WireType kWireTypeForFieldType[];
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite);
+};
+
+// A class which deals with unknown values by saving them to an UnknownFieldSet.
+class LIBPROTOBUF_EXPORT FieldSkipper {
+ public:
+ FieldSkipper(UnknownFieldSet* unknown_fields)
+ : unknown_fields_(unknown_fields) {}
+
+ // Skip a field whose tag has already been consumed.
+ bool SkipField(io::CodedInputStream* input, uint32 tag);
+
+ // Skip an entire message or group, up to an end-group tag (which is consumed)
+ // or end-of-stream.
+ bool SkipMessage(io::CodedInputStream* input);
+
+ // Deal with an already-parsed unrecognized enum value. The default
+ // implementation does nothing, but the UnknownFieldSet-based implementation
+ // saves it as an unknown varint.
+ void SkipUnknownEnum(int field_number, int value);
+
+ private:
+ UnknownFieldSet* unknown_fields_;
+};
+
+// inline methods ====================================================
+
+inline WireFormatLite::CppType
+WireFormatLite::FieldTypeToCppType(FieldType type) {
+ return kFieldTypeToCppTypeMap[type];
+}
+
+inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) {
+ return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
+}
+
+inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) {
+ return static_cast<WireType>(tag & kTagTypeMask);
+}
+
+inline int WireFormatLite::GetTagFieldNumber(uint32 tag) {
+ return static_cast<int>(tag >> kTagTypeBits);
+}
+
+inline int WireFormatLite::TagSize(int field_number,
+ WireFormatLite::FieldType type) {
+ int result = io::CodedOutputStream::VarintSize32(
+ static_cast<uint32>(field_number << kTagTypeBits));
+
+ if (type == TYPE_GROUP) {
+ // Groups have both a start and an end tag.
+ return result * 2;
+ } else {
+ return result;
+ }
+}
+
+inline uint32 WireFormatLite::EncodeFloat(float value) {
+ union {float f; uint32 i;};
+ f = value;
+ return i;
+}
+
+inline float WireFormatLite::DecodeFloat(uint32 value) {
+ union {float f; uint32 i;};
+ i = value;
+ return f;
+}
+
+inline uint64 WireFormatLite::EncodeDouble(double value) {
+ union {double f; uint64 i;};
+ f = value;
+ return i;
+}
+
+inline double WireFormatLite::DecodeDouble(uint64 value) {
+ union {double f; uint64 i;};
+ i = value;
+ return f;
+}
+
+// ZigZag Transform: Encodes signed integers so that they can be
+// effectively used with varint encoding.
+//
+// varint operates on unsigned integers, encoding smaller numbers into
+// fewer bytes. If you try to use it on a signed integer, it will treat
+// this number as a very large unsigned integer, which means that even
+// small signed numbers like -1 will take the maximum number of bytes
+// (10) to encode. ZigZagEncode() maps signed integers to unsigned
+// in such a way that those with a small absolute value will have smaller
+// encoded values, making them appropriate for encoding using varint.
+//
+// int32 -> uint32
+// -------------------------
+// 0 -> 0
+// -1 -> 1
+// 1 -> 2
+// -2 -> 3
+// ... -> ...
+// 2147483647 -> 4294967294
+// -2147483648 -> 4294967295
+//
+// >> encode >>
+// << decode <<
+
+inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
+ // Note: the right-shift must be arithmetic
+ return static_cast<uint32>((n << 1) ^ (n >> 31));
+}
+
+inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
+ return static_cast<int32>((n >> 1) ^ -static_cast<int32>(n & 1));
+}
+
+inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
+ // Note: the right-shift must be arithmetic
+ return static_cast<uint64>((n << 1) ^ (n >> 63));
+}
+
+inline int64 WireFormatLite::ZigZagDecode64(uint64 n) {
+ return static_cast<int64>((n >> 1) ^ -static_cast<int64>(n & 1));
+}
+
+} // namespace internal
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h b/src/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h
new file mode 100644
index 0000000..1e61abf
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h
@@ -0,0 +1,778 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// wink@google.com (Wink Saville) (refactored from wire_format.h)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/io/coded_stream.h>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Implementation details of ReadPrimitive.
+
+template <>
+inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
+ io::CodedInputStream* input,
+ int32* value) {
+ uint32 temp;
+ if (!input->ReadVarint32(&temp)) return false;
+ *value = static_cast<int32>(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
+ io::CodedInputStream* input,
+ int64* value) {
+ uint64 temp;
+ if (!input->ReadVarint64(&temp)) return false;
+ *value = static_cast<int64>(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
+ io::CodedInputStream* input,
+ uint32* value) {
+ return input->ReadVarint32(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
+ io::CodedInputStream* input,
+ uint64* value) {
+ return input->ReadVarint64(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
+ io::CodedInputStream* input,
+ int32* value) {
+ uint32 temp;
+ if (!input->ReadVarint32(&temp)) return false;
+ *value = ZigZagDecode32(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
+ io::CodedInputStream* input,
+ int64* value) {
+ uint64 temp;
+ if (!input->ReadVarint64(&temp)) return false;
+ *value = ZigZagDecode64(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
+ io::CodedInputStream* input,
+ uint32* value) {
+ return input->ReadLittleEndian32(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
+ io::CodedInputStream* input,
+ uint64* value) {
+ return input->ReadLittleEndian64(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
+ io::CodedInputStream* input,
+ int32* value) {
+ uint32 temp;
+ if (!input->ReadLittleEndian32(&temp)) return false;
+ *value = static_cast<int32>(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
+ io::CodedInputStream* input,
+ int64* value) {
+ uint64 temp;
+ if (!input->ReadLittleEndian64(&temp)) return false;
+ *value = static_cast<int64>(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
+ io::CodedInputStream* input,
+ float* value) {
+ uint32 temp;
+ if (!input->ReadLittleEndian32(&temp)) return false;
+ *value = DecodeFloat(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
+ io::CodedInputStream* input,
+ double* value) {
+ uint64 temp;
+ if (!input->ReadLittleEndian64(&temp)) return false;
+ *value = DecodeDouble(temp);
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
+ io::CodedInputStream* input,
+ bool* value) {
+ uint32 temp;
+ if (!input->ReadVarint32(&temp)) return false;
+ *value = temp != 0;
+ return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+ io::CodedInputStream* input,
+ int* value) {
+ uint32 temp;
+ if (!input->ReadVarint32(&temp)) return false;
+ *value = static_cast<int>(temp);
+ return true;
+}
+
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+ uint32, WireFormatLite::TYPE_FIXED32>(
+ const uint8* buffer,
+ uint32* value) {
+ return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+ uint64, WireFormatLite::TYPE_FIXED64>(
+ const uint8* buffer,
+ uint64* value) {
+ return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+ int32, WireFormatLite::TYPE_SFIXED32>(
+ const uint8* buffer,
+ int32* value) {
+ uint32 temp;
+ buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
+ *value = static_cast<int32>(temp);
+ return buffer;
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+ int64, WireFormatLite::TYPE_SFIXED64>(
+ const uint8* buffer,
+ int64* value) {
+ uint64 temp;
+ buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
+ *value = static_cast<int64>(temp);
+ return buffer;
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+ float, WireFormatLite::TYPE_FLOAT>(
+ const uint8* buffer,
+ float* value) {
+ uint32 temp;
+ buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
+ *value = DecodeFloat(temp);
+ return buffer;
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+ double, WireFormatLite::TYPE_DOUBLE>(
+ const uint8* buffer,
+ double* value) {
+ uint64 temp;
+ buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
+ *value = DecodeDouble(temp);
+ return buffer;
+}
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused.
+ uint32 tag,
+ io::CodedInputStream* input,
+ RepeatedField<CType>* values) {
+ CType value;
+ if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+ values->Add(value);
+ int elements_already_reserved = values->Capacity() - values->size();
+ while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
+ if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+ values->AddAlreadyReserved(value);
+ elements_already_reserved--;
+ }
+ return true;
+}
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
+ int tag_size,
+ uint32 tag,
+ io::CodedInputStream* input,
+ RepeatedField<CType>* values) {
+ GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
+ CType value;
+ if (!ReadPrimitive<CType, DeclaredType>(input, &value))
+ return false;
+ values->Add(value);
+
+ // For fixed size values, repeated values can be read more quickly by
+ // reading directly from a raw array.
+ //
+ // We can get a tight loop by only reading as many elements as can be
+ // added to the RepeatedField without having to do any resizing. Additionally,
+ // we only try to read as many elements as are available from the current
+ // buffer space. Doing so avoids having to perform boundary checks when
+ // reading the value: the maximum number of elements that can be read is
+ // known outside of the loop.
+ const void* void_pointer;
+ int size;
+ input->GetDirectBufferPointerInline(&void_pointer, &size);
+ if (size > 0) {
+ const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
+ // The number of bytes each type occupies on the wire.
+ const int per_value_size = static_cast<int>(tag_size + sizeof(value));
+
+ int elements_available = min(values->Capacity() - values->size(),
+ size / per_value_size);
+ int num_read = 0;
+ while (num_read < elements_available &&
+ (buffer = io::CodedInputStream::ExpectTagFromArray(
+ buffer, tag)) != NULL) {
+ buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
+ values->AddAlreadyReserved(value);
+ ++num_read;
+ }
+ const int read_bytes = num_read * per_value_size;
+ if (read_bytes > 0) {
+ input->Skip(read_bytes);
+ }
+ }
+ return true;
+}
+
+// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
+// the optimized code path.
+#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
+template <> \
+inline bool WireFormatLite::ReadRepeatedPrimitive< \
+ CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
+ int tag_size, \
+ uint32 tag, \
+ io::CodedInputStream* input, \
+ RepeatedField<CPPTYPE>* values) { \
+ return ReadRepeatedFixedSizePrimitive< \
+ CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
+ tag_size, tag, input, values); \
+}
+
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
+
+#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
+ int tag_size,
+ uint32 tag,
+ io::CodedInputStream* input,
+ RepeatedField<CType>* value) {
+ return ReadRepeatedPrimitive<CType, DeclaredType>(
+ tag_size, tag, input, value);
+}
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
+ RepeatedField<CType>* values) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ io::CodedInputStream::Limit limit = input->PushLimit(length);
+ while (input->BytesUntilLimit() > 0) {
+ CType value;
+ if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+ values->Add(value);
+ }
+ input->PopLimit(limit);
+ return true;
+}
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
+ RepeatedField<CType>* values) {
+ return ReadPackedPrimitive<CType, DeclaredType>(input, values);
+}
+
+
+inline bool WireFormatLite::ReadGroup(int field_number,
+ io::CodedInputStream* input,
+ MessageLite* value) {
+ if (!input->IncrementRecursionDepth()) return false;
+ if (!value->MergePartialFromCodedStream(input)) return false;
+ input->DecrementRecursionDepth();
+ // Make sure the last thing read was an end tag for this group.
+ if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
+ return false;
+ }
+ return true;
+}
+inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
+ MessageLite* value) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (!input->IncrementRecursionDepth()) return false;
+ io::CodedInputStream::Limit limit =
+ input->PushLimit(static_cast<int>(length));
+ if (!value->MergePartialFromCodedStream(input)) return false;
+ // Make sure that parsing stopped when the limit was hit, not at an endgroup
+ // tag.
+ if (!input->ConsumedEntireMessage()) return false;
+ input->PopLimit(limit);
+ input->DecrementRecursionDepth();
+ return true;
+}
+
+// We name the template parameter something long and extremely unlikely to occur
+// elsewhere because a *qualified* member access expression designed to avoid
+// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
+// name of the qualifying class to be looked up both in the context of the full
+// expression (finding the template parameter) and in the context of the object
+// whose member we are accessing. This could potentially find a nested type
+// within that object. The standard goes on to require these names to refer to
+// the same entity, which this collision would violate. The lack of a safe way
+// to avoid this collision appears to be a defect in the standard, but until it
+// is corrected, we choose the name to avoid accidental collisions.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline bool WireFormatLite::ReadGroupNoVirtual(
+ int field_number, io::CodedInputStream* input,
+ MessageType_WorkAroundCppLookupDefect* value) {
+ if (!input->IncrementRecursionDepth()) return false;
+ if (!value->
+ MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
+ return false;
+ input->DecrementRecursionDepth();
+ // Make sure the last thing read was an end tag for this group.
+ if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
+ return false;
+ }
+ return true;
+}
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline bool WireFormatLite::ReadMessageNoVirtual(
+ io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
+ uint32 length;
+ if (!input->ReadVarint32(&length)) return false;
+ if (!input->IncrementRecursionDepth()) return false;
+ io::CodedInputStream::Limit limit =
+ input->PushLimit(static_cast<int>(length));
+ if (!value->
+ MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
+ return false;
+ // Make sure that parsing stopped when the limit was hit, not at an endgroup
+ // tag.
+ if (!input->ConsumedEntireMessage()) return false;
+ input->PopLimit(limit);
+ input->DecrementRecursionDepth();
+ return true;
+}
+
+// ===================================================================
+
+inline void WireFormatLite::WriteTag(int field_number, WireType type,
+ io::CodedOutputStream* output) {
+ output->WriteTag(MakeTag(field_number, type));
+}
+
+inline void WireFormatLite::WriteInt32NoTag(int32 value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint32SignExtended(value);
+}
+inline void WireFormatLite::WriteInt64NoTag(int64 value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint64(static_cast<uint64>(value));
+}
+inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint32(value);
+}
+inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint64(value);
+}
+inline void WireFormatLite::WriteSInt32NoTag(int32 value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint32(ZigZagEncode32(value));
+}
+inline void WireFormatLite::WriteSInt64NoTag(int64 value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint64(ZigZagEncode64(value));
+}
+inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian32(value);
+}
+inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian64(value);
+}
+inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian32(static_cast<uint32>(value));
+}
+inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian64(static_cast<uint64>(value));
+}
+inline void WireFormatLite::WriteFloatNoTag(float value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian32(EncodeFloat(value));
+}
+inline void WireFormatLite::WriteDoubleNoTag(double value,
+ io::CodedOutputStream* output) {
+ output->WriteLittleEndian64(EncodeDouble(value));
+}
+inline void WireFormatLite::WriteBoolNoTag(bool value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint32(value ? 1 : 0u);
+}
+inline void WireFormatLite::WriteEnumNoTag(int value,
+ io::CodedOutputStream* output) {
+ output->WriteVarint32SignExtended(value);
+}
+
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline void WireFormatLite::WriteGroupNoVirtual(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_START_GROUP, output);
+ value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
+ WriteTag(field_number, WIRETYPE_END_GROUP, output);
+}
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline void WireFormatLite::WriteMessageNoVirtual(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ io::CodedOutputStream* output) {
+ WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+ output->WriteVarint32(
+ value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
+ value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
+}
+
+// ===================================================================
+
+inline uint8* WireFormatLite::WriteTagToArray(int field_number,
+ WireType type,
+ uint8* target) {
+ return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
+ target);
+}
+
+inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteVarint64ToArray(
+ static_cast<uint64>(value), target);
+}
+inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteVarint32ToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteVarint64ToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
+ target);
+}
+inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
+ target);
+}
+inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteLittleEndian32ToArray(
+ static_cast<uint32>(value), target);
+}
+inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteLittleEndian64ToArray(
+ static_cast<uint64>(value), target);
+}
+inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
+ target);
+}
+inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
+ target);
+}
+inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0u, target);
+}
+inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
+ uint8* target) {
+ return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
+}
+
+inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
+ int32 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteInt32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
+ int64 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteInt64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
+ uint32 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteUInt32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
+ uint64 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteUInt64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
+ int32 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteSInt32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
+ int64 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteSInt64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
+ uint32 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
+ return WriteFixed32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
+ uint64 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
+ return WriteFixed64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
+ int32 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
+ return WriteSFixed32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
+ int64 value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
+ return WriteSFixed64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
+ float value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
+ return WriteFloatNoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
+ double value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
+ return WriteDoubleNoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
+ bool value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteBoolNoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
+ int value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+ return WriteEnumNoTagToArray(value, target);
+}
+
+inline uint8* WireFormatLite::WriteStringToArray(int field_number,
+ const string& value,
+ uint8* target) {
+ // String is for UTF-8 text only
+ // WARNING: In wire_format.cc, both strings and bytes are handled by
+ // WriteString() to avoid code duplication. If the implementations become
+ // different, you will need to update that usage.
+ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(
+ static_cast<uint32>(value.size()), target);
+ return io::CodedOutputStream::WriteStringToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
+ const string& value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(
+ static_cast<uint32>(value.size()), target);
+ return io::CodedOutputStream::WriteStringToArray(value, target);
+}
+
+
+inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
+ const MessageLite& value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
+ target = value.SerializeWithCachedSizesToArray(target);
+ return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
+}
+inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
+ const MessageLite& value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(
+ static_cast<uint32>(value.GetCachedSize()), target);
+ return value.SerializeWithCachedSizesToArray(target);
+}
+
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
+ target = value.MessageType_WorkAroundCppLookupDefect
+ ::SerializeWithCachedSizesToArray(target);
+ return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
+}
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
+ int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+ uint8* target) {
+ target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+ target = io::CodedOutputStream::WriteVarint32ToArray(
+ value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
+ return value.MessageType_WorkAroundCppLookupDefect
+ ::SerializeWithCachedSizesToArray(target);
+}
+
+// ===================================================================
+
+inline int WireFormatLite::Int32Size(int32 value) {
+ return io::CodedOutputStream::VarintSize32SignExtended(value);
+}
+inline int WireFormatLite::Int64Size(int64 value) {
+ return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
+}
+inline int WireFormatLite::UInt32Size(uint32 value) {
+ return io::CodedOutputStream::VarintSize32(value);
+}
+inline int WireFormatLite::UInt64Size(uint64 value) {
+ return io::CodedOutputStream::VarintSize64(value);
+}
+inline int WireFormatLite::SInt32Size(int32 value) {
+ return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
+}
+inline int WireFormatLite::SInt64Size(int64 value) {
+ return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
+}
+inline int WireFormatLite::EnumSize(int value) {
+ return io::CodedOutputStream::VarintSize32SignExtended(value);
+}
+
+inline int WireFormatLite::StringSize(const string& value) {
+ return static_cast<int>(io::CodedOutputStream::VarintSize32(
+ static_cast<uint32>(value.size())) + value.size());
+}
+inline int WireFormatLite::BytesSize(const string& value) {
+ return static_cast<int>(io::CodedOutputStream::VarintSize32(
+ static_cast<uint32>(value.size())) + value.size());
+}
+
+
+inline int WireFormatLite::GroupSize(const MessageLite& value) {
+ return value.ByteSize();
+}
+inline int WireFormatLite::MessageSize(const MessageLite& value) {
+ int size = value.ByteSize();
+ return io::CodedOutputStream::VarintSize32(static_cast<uint32>(size)) + size;
+}
+
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline int WireFormatLite::GroupSizeNoVirtual(
+ const MessageType_WorkAroundCppLookupDefect& value) {
+ return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
+}
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline int WireFormatLite::MessageSizeNoVirtual(
+ const MessageType_WorkAroundCppLookupDefect& value) {
+ int size = value.MessageType_WorkAroundCppLookupDefect::ByteSize();
+ return io::CodedOutputStream::VarintSize32(static_cast<uint32>(size)) + size;
+}
+
+} // namespace internal
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
diff --git a/src/third_party/protobuf/src/google/protobuf/wire_format_unittest.cc b/src/third_party/protobuf/src/google/protobuf/wire_format_unittest.cc
new file mode 100644
index 0000000..867970c
--- /dev/null
+++ b/src/third_party/protobuf/src/google/protobuf/wire_format_unittest.cc
@@ -0,0 +1,905 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_mset.pb.h>
+#include <google/protobuf/test_util.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util-inl.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(WireFormatTest, EnumsInSync) {
+ // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match
+ // FieldDescriptor::Type and FieldDescriptor::CppType.
+
+ EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE),
+ implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE));
+ EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE),
+ implicit_cast<int>(WireFormatLite::MAX_CPPTYPE));
+
+ for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) {
+ EXPECT_EQ(
+ implicit_cast<int>(FieldDescriptor::TypeToCppType(
+ static_cast<FieldDescriptor::Type>(i))),
+ implicit_cast<int>(WireFormatLite::FieldTypeToCppType(
+ static_cast<WireFormatLite::FieldType>(i))));
+ }
+}
+
+TEST(WireFormatTest, MaxFieldNumber) {
+ // Make sure the max field number constant is accurate.
+ EXPECT_EQ((1 << (32 - WireFormatLite::kTagTypeBits)) - 1,
+ FieldDescriptor::kMaxNumber);
+}
+
+TEST(WireFormatTest, Parse) {
+ unittest::TestAllTypes source, dest;
+ string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetAllFields(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectAllFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParseExtensions) {
+ unittest::TestAllExtensions source, dest;
+ string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetAllExtensions(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectAllExtensionsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePacked) {
+ unittest::TestPackedTypes source, dest;
+ string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetPackedFields(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectPackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePackedFromUnpacked) {
+ // Serialize using the generated code.
+ unittest::TestUnpackedTypes source;
+ TestUtil::SetUnpackedFields(&source);
+ string data = source.SerializeAsString();
+
+ // Parse using WireFormat.
+ unittest::TestPackedTypes dest;
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectPackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParseUnpackedFromPacked) {
+ // Serialize using the generated code.
+ unittest::TestPackedTypes source;
+ TestUtil::SetPackedFields(&source);
+ string data = source.SerializeAsString();
+
+ // Parse using WireFormat.
+ unittest::TestUnpackedTypes dest;
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectUnpackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePackedExtensions) {
+ unittest::TestPackedExtensions source, dest;
+ string data;
+
+ // Serialize using the generated code.
+ TestUtil::SetPackedExtensions(&source);
+ source.SerializeToString(&data);
+
+ // Parse using WireFormat.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ WireFormat::ParseAndMergePartial(&input, &dest);
+
+ // Check.
+ TestUtil::ExpectPackedExtensionsSet(dest);
+}
+
+TEST(WireFormatTest, ByteSize) {
+ unittest::TestAllTypes message;
+ TestUtil::SetAllFields(&message);
+
+ EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSize());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizeExtensions) {
+ unittest::TestAllExtensions message;
+ TestUtil::SetAllExtensions(&message);
+
+ EXPECT_EQ(message.ByteSize(),
+ WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSize());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizePacked) {
+ unittest::TestPackedTypes message;
+ TestUtil::SetPackedFields(&message);
+
+ EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSize());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizePackedExtensions) {
+ unittest::TestPackedExtensions message;
+ TestUtil::SetPackedExtensions(&message);
+
+ EXPECT_EQ(message.ByteSize(),
+ WireFormat::ByteSize(message));
+ message.Clear();
+ EXPECT_EQ(0, message.ByteSize());
+ EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, Serialize) {
+ unittest::TestAllTypes message;
+ string generated_data;
+ string dynamic_data;
+
+ TestUtil::SetAllFields(&message);
+ int size = message.ByteSize();
+
+ // Serialize using the generated code.
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should be the same.
+ // Don't use EXPECT_EQ here because we're comparing raw binary data and
+ // we really don't want it dumped to stdout on failure.
+ EXPECT_TRUE(dynamic_data == generated_data);
+}
+
+TEST(WireFormatTest, SerializeExtensions) {
+ unittest::TestAllExtensions message;
+ string generated_data;
+ string dynamic_data;
+
+ TestUtil::SetAllExtensions(&message);
+ int size = message.ByteSize();
+
+ // Serialize using the generated code.
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should be the same.
+ // Don't use EXPECT_EQ here because we're comparing raw binary data and
+ // we really don't want it dumped to stdout on failure.
+ EXPECT_TRUE(dynamic_data == generated_data);
+}
+
+TEST(WireFormatTest, SerializeFieldsAndExtensions) {
+ unittest::TestFieldOrderings message;
+ string generated_data;
+ string dynamic_data;
+
+ TestUtil::SetAllFieldsAndExtensions(&message);
+ int size = message.ByteSize();
+
+ // Serialize using the generated code.
+ {
+ io::StringOutputStream raw_output(&generated_data);
+ io::CodedOutputStream output(&raw_output);
+ message.SerializeWithCachedSizes(&output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Serialize using WireFormat.
+ {
+ io::StringOutputStream raw_output(&dynamic_data);
+ io::CodedOutputStream output(&raw_output);
+ WireFormat::SerializeWithCachedSizes(message, size, &output);
+ ASSERT_FALSE(output.HadError());
+ }
+
+ // Should be the same.
+ // Don't use EXPECT_EQ here because we're comparing raw binary data and
+ // we really don't want it dumped to stdout on failure.
+ EXPECT_TRUE(dynamic_data == generated_data);
+
+ // Should output in canonical order.
+ TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data);
+ TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data);
+}
+
+TEST(WireFormatTest, ParseMultipleExtensionRanges) {
+ // Make sure we can parse a message that contains multiple extensions ranges.
+ unittest::TestFieldOrderings source;
+ string data;
+
+ TestUtil::SetAllFieldsAndExtensions(&source);
+ source.SerializeToString(&data);
+
+ {
+ unittest::TestFieldOrderings dest;
+ EXPECT_TRUE(dest.ParseFromString(data));
+ EXPECT_EQ(source.DebugString(), dest.DebugString());
+ }
+
+ // Also test using reflection-based parsing.
+ {
+ unittest::TestFieldOrderings dest;
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream coded_input(&raw_input);
+ EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest));
+ EXPECT_EQ(source.DebugString(), dest.DebugString());
+ }
+}
+
+const int kUnknownTypeId = 1550055;
+
+TEST(WireFormatTest, SerializeMessageSet) {
+ // Set up a TestMessageSet with two known messages and an unknown one.
+ unittest::TestMessageSet message_set;
+ message_set.MutableExtension(
+ unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
+ message_set.MutableExtension(
+ unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
+ message_set.mutable_unknown_fields()->AddLengthDelimited(
+ kUnknownTypeId, "bar");
+
+ string data;
+ ASSERT_TRUE(message_set.SerializeToString(&data));
+
+ // Parse back using RawMessageSet and check the contents.
+ unittest::RawMessageSet raw;
+ ASSERT_TRUE(raw.ParseFromString(data));
+
+ EXPECT_EQ(0, raw.unknown_fields().field_count());
+
+ ASSERT_EQ(3, raw.item_size());
+ EXPECT_EQ(
+ unittest::TestMessageSetExtension1::descriptor()->extension(0)->number(),
+ raw.item(0).type_id());
+ EXPECT_EQ(
+ unittest::TestMessageSetExtension2::descriptor()->extension(0)->number(),
+ raw.item(1).type_id());
+ EXPECT_EQ(kUnknownTypeId, raw.item(2).type_id());
+
+ unittest::TestMessageSetExtension1 message1;
+ EXPECT_TRUE(message1.ParseFromString(raw.item(0).message()));
+ EXPECT_EQ(123, message1.i());
+
+ unittest::TestMessageSetExtension2 message2;
+ EXPECT_TRUE(message2.ParseFromString(raw.item(1).message()));
+ EXPECT_EQ("foo", message2.str());
+
+ EXPECT_EQ("bar", raw.item(2).message());
+}
+
+TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) {
+ // Serialize a MessageSet to a stream and to a flat array using generated
+ // code, and also using WireFormat, and check that the results are equal.
+ // Set up a TestMessageSet with two known messages and an unknown one, as
+ // above.
+
+ unittest::TestMessageSet message_set;
+ message_set.MutableExtension(
+ unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
+ message_set.MutableExtension(
+ unittest::TestMessageSetExtension2::message_set_extension)->set_str("foo");
+ message_set.mutable_unknown_fields()->AddLengthDelimited(
+ kUnknownTypeId, "bar");
+
+ int size = message_set.ByteSize();
+ EXPECT_EQ(size, message_set.GetCachedSize());
+ ASSERT_EQ(size, WireFormat::ByteSize(message_set));
+
+ string flat_data;
+ string stream_data;
+ string dynamic_data;
+ flat_data.resize(size);
+ stream_data.resize(size);
+
+ // Serialize to flat array
+ {
+ uint8* target = reinterpret_cast<uint8*>(string_as_array(&flat_data));
+ uint8* end = message_set.SerializeWithCachedSizesToArray(target);
+ EXPECT_EQ(size, end - target);
+ }
+
+ // Serialize to buffer
+ {
+ io::ArrayOutputStream array_stream(string_as_array(&stream_data), size, 1);
+ io::CodedOutputStream output_stream(&array_stream);
+ message_set.SerializeWithCachedSizes(&output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+
+ // Serialize to buffer with WireFormat.
+ {
+ io::StringOutputStream string_stream(&dynamic_data);
+ io::CodedOutputStream output_stream(&string_stream);
+ WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream);
+ ASSERT_FALSE(output_stream.HadError());
+ }
+
+ EXPECT_TRUE(flat_data == stream_data);
+ EXPECT_TRUE(flat_data == dynamic_data);
+}
+
+TEST(WireFormatTest, ParseMessageSet) {
+ // Set up a RawMessageSet with two known messages and an unknown one.
+ unittest::RawMessageSet raw;
+
+ {
+ unittest::RawMessageSet::Item* item = raw.add_item();
+ item->set_type_id(
+ unittest::TestMessageSetExtension1::descriptor()->extension(0)->number());
+ unittest::TestMessageSetExtension1 message;
+ message.set_i(123);
+ message.SerializeToString(item->mutable_message());
+ }
+
+ {
+ unittest::RawMessageSet::Item* item = raw.add_item();
+ item->set_type_id(
+ unittest::TestMessageSetExtension2::descriptor()->extension(0)->number());
+ unittest::TestMessageSetExtension2 message;
+ message.set_str("foo");
+ message.SerializeToString(item->mutable_message());
+ }
+
+ {
+ unittest::RawMessageSet::Item* item = raw.add_item();
+ item->set_type_id(kUnknownTypeId);
+ item->set_message("bar");
+ }
+
+ string data;
+ ASSERT_TRUE(raw.SerializeToString(&data));
+
+ // Parse as a TestMessageSet and check the contents.
+ unittest::TestMessageSet message_set;
+ ASSERT_TRUE(message_set.ParseFromString(data));
+
+ EXPECT_EQ(123, message_set.GetExtension(
+ unittest::TestMessageSetExtension1::message_set_extension).i());
+ EXPECT_EQ("foo", message_set.GetExtension(
+ unittest::TestMessageSetExtension2::message_set_extension).str());
+
+ ASSERT_EQ(1, message_set.unknown_fields().field_count());
+ ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED,
+ message_set.unknown_fields().field(0).type());
+ EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited());
+
+ // Also parse using WireFormat.
+ unittest::TestMessageSet dynamic_message_set;
+ io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
+ data.size());
+ ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set));
+ EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString());
+}
+
+TEST(WireFormatTest, RecursionLimit) {
+ unittest::TestRecursiveMessage message;
+ message.mutable_a()->mutable_a()->mutable_a()->mutable_a()->set_i(1);
+ string data;
+ message.SerializeToString(&data);
+
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetRecursionLimit(4);
+ unittest::TestRecursiveMessage message2;
+ EXPECT_TRUE(message2.ParseFromCodedStream(&input));
+ }
+
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetRecursionLimit(3);
+ unittest::TestRecursiveMessage message2;
+ EXPECT_FALSE(message2.ParseFromCodedStream(&input));
+ }
+}
+
+TEST(WireFormatTest, UnknownFieldRecursionLimit) {
+ unittest::TestEmptyMessage message;
+ message.mutable_unknown_fields()
+ ->AddGroup(1234)
+ ->AddGroup(1234)
+ ->AddGroup(1234)
+ ->AddGroup(1234)
+ ->AddVarint(1234, 123);
+ string data;
+ message.SerializeToString(&data);
+
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetRecursionLimit(4);
+ unittest::TestEmptyMessage message2;
+ EXPECT_TRUE(message2.ParseFromCodedStream(&input));
+ }
+
+ {
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream input(&raw_input);
+ input.SetRecursionLimit(3);
+ unittest::TestEmptyMessage message2;
+ EXPECT_FALSE(message2.ParseFromCodedStream(&input));
+ }
+}
+
+TEST(WireFormatTest, ZigZag) {
+// avoid line-wrapping
+#define LL(x) GOOGLE_LONGLONG(x)
+#define ULL(x) GOOGLE_ULONGLONG(x)
+#define ZigZagEncode32(x) WireFormatLite::ZigZagEncode32(x)
+#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x)
+#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x)
+#define ZigZagDecode64(x) WireFormatLite::ZigZagDecode64(x)
+
+ EXPECT_EQ(0u, ZigZagEncode32( 0));
+ EXPECT_EQ(1u, ZigZagEncode32(-1));
+ EXPECT_EQ(2u, ZigZagEncode32( 1));
+ EXPECT_EQ(3u, ZigZagEncode32(-2));
+ EXPECT_EQ(0x7FFFFFFEu, ZigZagEncode32(0x3FFFFFFF));
+ EXPECT_EQ(0x7FFFFFFFu, ZigZagEncode32(0xC0000000));
+ EXPECT_EQ(0xFFFFFFFEu, ZigZagEncode32(0x7FFFFFFF));
+ EXPECT_EQ(0xFFFFFFFFu, ZigZagEncode32(0x80000000));
+
+ EXPECT_EQ( 0, ZigZagDecode32(0u));
+ EXPECT_EQ(-1, ZigZagDecode32(1u));
+ EXPECT_EQ( 1, ZigZagDecode32(2u));
+ EXPECT_EQ(-2, ZigZagDecode32(3u));
+ EXPECT_EQ(0x3FFFFFFF, ZigZagDecode32(0x7FFFFFFEu));
+ EXPECT_EQ(0xC0000000, ZigZagDecode32(0x7FFFFFFFu));
+ EXPECT_EQ(0x7FFFFFFF, ZigZagDecode32(0xFFFFFFFEu));
+ EXPECT_EQ(0x80000000, ZigZagDecode32(0xFFFFFFFFu));
+
+ EXPECT_EQ(0u, ZigZagEncode64( 0));
+ EXPECT_EQ(1u, ZigZagEncode64(-1));
+ EXPECT_EQ(2u, ZigZagEncode64( 1));
+ EXPECT_EQ(3u, ZigZagEncode64(-2));
+ EXPECT_EQ(ULL(0x000000007FFFFFFE), ZigZagEncode64(LL(0x000000003FFFFFFF)));
+ EXPECT_EQ(ULL(0x000000007FFFFFFF), ZigZagEncode64(LL(0xFFFFFFFFC0000000)));
+ EXPECT_EQ(ULL(0x00000000FFFFFFFE), ZigZagEncode64(LL(0x000000007FFFFFFF)));
+ EXPECT_EQ(ULL(0x00000000FFFFFFFF), ZigZagEncode64(LL(0xFFFFFFFF80000000)));
+ EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFE), ZigZagEncode64(LL(0x7FFFFFFFFFFFFFFF)));
+ EXPECT_EQ(ULL(0xFFFFFFFFFFFFFFFF), ZigZagEncode64(LL(0x8000000000000000)));
+
+ EXPECT_EQ( 0, ZigZagDecode64(0u));
+ EXPECT_EQ(-1, ZigZagDecode64(1u));
+ EXPECT_EQ( 1, ZigZagDecode64(2u));
+ EXPECT_EQ(-2, ZigZagDecode64(3u));
+ EXPECT_EQ(LL(0x000000003FFFFFFF), ZigZagDecode64(ULL(0x000000007FFFFFFE)));
+ EXPECT_EQ(LL(0xFFFFFFFFC0000000), ZigZagDecode64(ULL(0x000000007FFFFFFF)));
+ EXPECT_EQ(LL(0x000000007FFFFFFF), ZigZagDecode64(ULL(0x00000000FFFFFFFE)));
+ EXPECT_EQ(LL(0xFFFFFFFF80000000), ZigZagDecode64(ULL(0x00000000FFFFFFFF)));
+ EXPECT_EQ(LL(0x7FFFFFFFFFFFFFFF), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFE)));
+ EXPECT_EQ(LL(0x8000000000000000), ZigZagDecode64(ULL(0xFFFFFFFFFFFFFFFF)));
+
+ // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
+ // were chosen semi-randomly via keyboard bashing.
+ EXPECT_EQ( 0, ZigZagDecode32(ZigZagEncode32( 0)));
+ EXPECT_EQ( 1, ZigZagDecode32(ZigZagEncode32( 1)));
+ EXPECT_EQ( -1, ZigZagDecode32(ZigZagEncode32( -1)));
+ EXPECT_EQ(14927, ZigZagDecode32(ZigZagEncode32(14927)));
+ EXPECT_EQ(-3612, ZigZagDecode32(ZigZagEncode32(-3612)));
+
+ EXPECT_EQ( 0, ZigZagDecode64(ZigZagEncode64( 0)));
+ EXPECT_EQ( 1, ZigZagDecode64(ZigZagEncode64( 1)));
+ EXPECT_EQ( -1, ZigZagDecode64(ZigZagEncode64( -1)));
+ EXPECT_EQ(14927, ZigZagDecode64(ZigZagEncode64(14927)));
+ EXPECT_EQ(-3612, ZigZagDecode64(ZigZagEncode64(-3612)));
+
+ EXPECT_EQ(LL(856912304801416), ZigZagDecode64(ZigZagEncode64(
+ LL(856912304801416))));
+ EXPECT_EQ(LL(-75123905439571256), ZigZagDecode64(ZigZagEncode64(
+ LL(-75123905439571256))));
+}
+
+TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) {
+ // At one point checks would trigger when parsing repeated fixed scalar
+ // fields.
+ protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2;
+ for (int i = 0; i < 100; ++i) {
+ msg1.add_repeated_fixed32(i);
+ msg1.add_repeated_int32(i);
+ msg1.add_repeated_fixed64(i);
+ msg1.add_repeated_int64(i);
+ msg1.add_repeated_float(i);
+ msg1.add_repeated_uint64(i);
+ }
+
+ // Make sure that we have a variety of tag sizes.
+ const google::protobuf::Descriptor* desc = msg1.GetDescriptor();
+ const google::protobuf::FieldDescriptor* field;
+ field = desc->FindFieldByName("repeated_fixed32");
+ ASSERT_TRUE(field != NULL);
+ ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_int32");
+ ASSERT_TRUE(field != NULL);
+ ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_fixed64");
+ ASSERT_TRUE(field != NULL);
+ ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_int64");
+ ASSERT_TRUE(field != NULL);
+ ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_float");
+ ASSERT_TRUE(field != NULL);
+ ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
+ field = desc->FindFieldByName("repeated_uint64");
+ ASSERT_TRUE(field != NULL);
+ ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
+
+ EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString()));
+ EXPECT_EQ(msg1.DebugString(), msg2.DebugString());
+}
+
+class WireFormatInvalidInputTest : public testing::Test {
+ protected:
+ // Make a serialized TestAllTypes in which the field optional_nested_message
+ // contains exactly the given bytes, which may be invalid.
+ string MakeInvalidEmbeddedMessage(const char* bytes, int size) {
+ const FieldDescriptor* field =
+ unittest::TestAllTypes::descriptor()->FindFieldByName(
+ "optional_nested_message");
+ GOOGLE_CHECK(field != NULL);
+
+ string result;
+
+ {
+ io::StringOutputStream raw_output(&result);
+ io::CodedOutputStream output(&raw_output);
+
+ WireFormatLite::WriteBytes(field->number(), string(bytes, size), &output);
+ }
+
+ return result;
+ }
+
+ // Make a serialized TestAllTypes in which the field optionalgroup
+ // contains exactly the given bytes -- which may be invalid -- and
+ // possibly no end tag.
+ string MakeInvalidGroup(const char* bytes, int size, bool include_end_tag) {
+ const FieldDescriptor* field =
+ unittest::TestAllTypes::descriptor()->FindFieldByName(
+ "optionalgroup");
+ GOOGLE_CHECK(field != NULL);
+
+ string result;
+
+ {
+ io::StringOutputStream raw_output(&result);
+ io::CodedOutputStream output(&raw_output);
+
+ output.WriteVarint32(WireFormat::MakeTag(field));
+ output.WriteString(string(bytes, size));
+ if (include_end_tag) {
+ output.WriteVarint32(WireFormatLite::MakeTag(
+ field->number(), WireFormatLite::WIRETYPE_END_GROUP));
+ }
+ }
+
+ return result;
+ }
+};
+
+TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) {
+ unittest::TestAllTypes message;
+
+ // Control case.
+ EXPECT_TRUE(message.ParseFromString(MakeInvalidEmbeddedMessage("", 0)));
+
+ // The byte is a valid varint, but not a valid tag (zero).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\0", 1)));
+
+ // The byte is a malformed varint.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\200", 1)));
+
+ // The byte is an endgroup tag, but we aren't parsing a group.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\014", 1)));
+
+ // The byte is a valid varint but not a valid tag (bad wire type).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1)));
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidGroup) {
+ unittest::TestAllTypes message;
+
+ // Control case.
+ EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
+
+ // Missing end tag. Groups cannot end at EOF.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
+
+ // The byte is a valid varint, but not a valid tag (zero).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
+
+ // The byte is a malformed varint.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
+
+ // The byte is an endgroup tag, but not the right one for this group.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
+
+ // The byte is a valid varint but not a valid tag (bad wire type).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidUnknownGroup) {
+ // Use TestEmptyMessage so that the group made by MakeInvalidGroup will not
+ // be a known tag number.
+ unittest::TestEmptyMessage message;
+
+ // Control case.
+ EXPECT_TRUE(message.ParseFromString(MakeInvalidGroup("", 0, true)));
+
+ // Missing end tag. Groups cannot end at EOF.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("", 0, false)));
+
+ // The byte is a valid varint, but not a valid tag (zero).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\0", 1, false)));
+
+ // The byte is a malformed varint.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\200", 1, false)));
+
+ // The byte is an endgroup tag, but not the right one for this group.
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\014", 1, false)));
+
+ // The byte is a valid varint but not a valid tag (bad wire type).
+ EXPECT_FALSE(message.ParseFromString(MakeInvalidGroup("\017", 1, true)));
+}
+
+TEST_F(WireFormatInvalidInputTest, InvalidStringInUnknownGroup) {
+ // Test a bug fix: SkipMessage should fail if the message contains a string
+ // whose length would extend beyond the message end.
+
+ unittest::TestAllTypes message;
+ message.set_optional_string("foo foo foo foo");
+ string data;
+ message.SerializeToString(&data);
+
+ // Chop some bytes off the end.
+ data.resize(data.size() - 4);
+
+ // Try to skip it. Note that the bug was only present when parsing to an
+ // UnknownFieldSet.
+ io::ArrayInputStream raw_input(data.data(), data.size());
+ io::CodedInputStream coded_input(&raw_input);
+ UnknownFieldSet unknown_fields;
+ EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields));
+}
+
+// Test differences between string and bytes.
+// Value of a string type must be valid UTF-8 string. When UTF-8
+// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED):
+// WriteInvalidUTF8String: see error message.
+// ReadInvalidUTF8String: see error message.
+// WriteValidUTF8String: fine.
+// ReadValidUTF8String: fine.
+// WriteAnyBytes: fine.
+// ReadAnyBytes: fine.
+const char * kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0";
+// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to
+// interpret \u differently from GCC.
+const char * kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214";
+
+template<typename T>
+bool WriteMessage(const char *value, T *message, string *wire_buffer) {
+ message->set_data(value);
+ wire_buffer->clear();
+ message->AppendToString(wire_buffer);
+ return (wire_buffer->size() > 0);
+}
+
+template<typename T>
+bool ReadMessage(const string &wire_buffer, T *message) {
+ return message->ParseFromArray(wire_buffer.data(), wire_buffer.size());
+}
+
+TEST(Utf8ValidationTest, WriteInvalidUTF8String) {
+ string wire_buffer;
+ protobuf_unittest::OneString input;
+ vector<string> errors;
+ {
+ ScopedMemoryLog log;
+ WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+ errors = log.GetMessages(ERROR);
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ ASSERT_EQ(1, errors.size());
+ EXPECT_EQ("Encountered string containing invalid UTF-8 data while "
+ "serializing protocol buffer. Strings must contain only UTF-8; "
+ "use the 'bytes' type for raw bytes.",
+ errors[0]);
+
+#else
+ ASSERT_EQ(0, errors.size());
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+}
+
+TEST(Utf8ValidationTest, ReadInvalidUTF8String) {
+ string wire_buffer;
+ protobuf_unittest::OneString input;
+ WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+ protobuf_unittest::OneString output;
+ vector<string> errors;
+ {
+ ScopedMemoryLog log;
+ ReadMessage(wire_buffer, &output);
+ errors = log.GetMessages(ERROR);
+ }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+ ASSERT_EQ(1, errors.size());
+ EXPECT_EQ("Encountered string containing invalid UTF-8 data while "
+ "parsing protocol buffer. Strings must contain only UTF-8; "
+ "use the 'bytes' type for raw bytes.",
+ errors[0]);
+
+#else
+ ASSERT_EQ(0, errors.size());
+#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+}
+
+TEST(Utf8ValidationTest, WriteValidUTF8String) {
+ string wire_buffer;
+ protobuf_unittest::OneString input;
+ vector<string> errors;
+ {
+ ScopedMemoryLog log;
+ WriteMessage(kValidUTF8String, &input, &wire_buffer);
+ errors = log.GetMessages(ERROR);
+ }
+ ASSERT_EQ(0, errors.size());
+}
+
+TEST(Utf8ValidationTest, ReadValidUTF8String) {
+ string wire_buffer;
+ protobuf_unittest::OneString input;
+ WriteMessage(kValidUTF8String, &input, &wire_buffer);
+ protobuf_unittest::OneString output;
+ vector<string> errors;
+ {
+ ScopedMemoryLog log;
+ ReadMessage(wire_buffer, &output);
+ errors = log.GetMessages(ERROR);
+ }
+ ASSERT_EQ(0, errors.size());
+ EXPECT_EQ(input.data(), output.data());
+}
+
+// Bytes: anything can pass as bytes, use invalid UTF-8 string to test
+TEST(Utf8ValidationTest, WriteArbitraryBytes) {
+ string wire_buffer;
+ protobuf_unittest::OneBytes input;
+ vector<string> errors;
+ {
+ ScopedMemoryLog log;
+ WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+ errors = log.GetMessages(ERROR);
+ }
+ ASSERT_EQ(0, errors.size());
+}
+
+TEST(Utf8ValidationTest, ReadArbitraryBytes) {
+ string wire_buffer;
+ protobuf_unittest::OneBytes input;
+ WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+ protobuf_unittest::OneBytes output;
+ vector<string> errors;
+ {
+ ScopedMemoryLog log;
+ ReadMessage(wire_buffer, &output);
+ errors = log.GetMessages(ERROR);
+ }
+ ASSERT_EQ(0, errors.size());
+ EXPECT_EQ(input.data(), output.data());
+}
+
+} // namespace
+} // namespace internal
+} // namespace protobuf
+} // namespace google
diff --git a/src/third_party/protobuf/vsprojects/config.h b/src/third_party/protobuf/vsprojects/config.h
new file mode 100644
index 0000000..2c64450
--- /dev/null
+++ b/src/third_party/protobuf/vsprojects/config.h
@@ -0,0 +1,29 @@
+/* protobuf config.h for MSVC. On other platforms, this is generated
+ * automatically by autoheader / autoconf / configure. */
+
+/* the location of <hash_map> */
+#define HASH_MAP_H <hash_map>
+
+/* the namespace of hash_map/hash_set */
+// Apparently Microsoft decided to move hash_map *back* to the std namespace
+// in MSVC 2010:
+// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
+// TODO(kenton): Use unordered_map instead, which is available in MSVC 2010.
+#if _MSC_VER < 1310 || _MSC_VER >= 1600
+#define HASH_NAMESPACE std
+#else
+#define HASH_NAMESPACE stdext
+#endif
+
+/* the location of <hash_set> */
+#define HASH_SET_H <hash_set>
+
+/* define if the compiler has hash_map */
+#define HAVE_HASH_MAP 1
+
+/* define if the compiler has hash_set */
+#define HAVE_HASH_SET 1
+
+/* define if you want to use zlib. See readme.txt for additional
+ * requirements. */
+// #define HAVE_ZLIB 1
diff --git a/src/third_party/protobuf/vsprojects/convert2008to2005.sh b/src/third_party/protobuf/vsprojects/convert2008to2005.sh
new file mode 100755
index 0000000..60eccaf
--- /dev/null
+++ b/src/third_party/protobuf/vsprojects/convert2008to2005.sh
@@ -0,0 +1,20 @@
+#! /bin/sh -e
+
+# This script downgrades MSVC 2008 projects to MSVC 2005 projects, allowing
+# people with MSVC 2005 to open them. Otherwise, MSVC 2005 simply refuses to
+# open projects created with 2008. We run this as part of our release process.
+# If you obtained the code direct from version control and you want to use
+# MSVC 2005, you may have to run this manually. (Hint: Use Cygwin or MSYS.)
+
+for file in *.sln; do
+ echo "downgrading $file..."
+ sed -i -re 's/Format Version 10.00/Format Version 9.00/g;
+ s/Visual Studio 2008/Visual Studio 2005/g;' $file
+done
+
+for file in *.vcproj; do
+ echo "downgrading $file..."
+ sed -i -re 's/Version="9.00"/Version="8.00"/g;' $file
+done
+
+# Yes, really, that's it.
diff --git a/src/third_party/protobuf/vsprojects/extract_includes.bat b/src/third_party/protobuf/vsprojects/extract_includes.bat
new file mode 100755
index 0000000..70fdf73
--- /dev/null
+++ b/src/third_party/protobuf/vsprojects/extract_includes.bat
@@ -0,0 +1,46 @@
+md include
+md include\google
+md include\google\protobuf
+md include\google\protobuf\stubs
+md include\google\protobuf\io
+md include\google\protobuf\compiler
+md include\google\protobuf\compiler\cpp
+md include\google\protobuf\compiler\java
+md include\google\protobuf\compiler\python
+copy ..\src\google\protobuf\stubs\atomicops.h include\google\protobuf\stubs\atomicops.h
+copy ..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h include\google\protobuf\stubs\atomicops_internals_x86_msvc.h
+copy ..\src\google\protobuf\stubs\common.h include\google\protobuf\stubs\common.h
+copy ..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h
+copy ..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h
+copy ..\src\google\protobuf\descriptor.h include\google\protobuf\descriptor.h
+copy ..\src\google\protobuf\descriptor.pb.h include\google\protobuf\descriptor.pb.h
+copy ..\src\google\protobuf\descriptor_database.h include\google\protobuf\descriptor_database.h
+copy ..\src\google\protobuf\dynamic_message.h include\google\protobuf\dynamic_message.h
+copy ..\src\google\protobuf\extension_set.h include\google\protobuf\extension_set.h
+copy ..\src\google\protobuf\generated_message_util.h include\google\protobuf\generated_message_util.h
+copy ..\src\google\protobuf\generated_message_reflection.h include\google\protobuf\generated_message_reflection.h
+copy ..\src\google\protobuf\message.h include\google\protobuf\message.h
+copy ..\src\google\protobuf\message_lite.h include\google\protobuf\message_lite.h
+copy ..\src\google\protobuf\reflection_ops.h include\google\protobuf\reflection_ops.h
+copy ..\src\google\protobuf\repeated_field.h include\google\protobuf\repeated_field.h
+copy ..\src\google\protobuf\service.h include\google\protobuf\service.h
+copy ..\src\google\protobuf\text_format.h include\google\protobuf\text_format.h
+copy ..\src\google\protobuf\unknown_field_set.h include\google\protobuf\unknown_field_set.h
+copy ..\src\google\protobuf\wire_format.h include\google\protobuf\wire_format.h
+copy ..\src\google\protobuf\wire_format_lite.h include\google\protobuf\wire_format_lite.h
+copy ..\src\google\protobuf\wire_format_lite_inl.h include\google\protobuf\wire_format_lite_inl.h
+copy ..\src\google\protobuf\io\coded_stream.h include\google\protobuf\io\coded_stream.h
+copy ..\src\google\protobuf\io\gzip_stream.h include\google\protobuf\io\gzip_stream.h
+copy ..\src\google\protobuf\io\printer.h include\google\protobuf\io\printer.h
+copy ..\src\google\protobuf\io\tokenizer.h include\google\protobuf\io\tokenizer.h
+copy ..\src\google\protobuf\io\zero_copy_stream.h include\google\protobuf\io\zero_copy_stream.h
+copy ..\src\google\protobuf\io\zero_copy_stream_impl.h include\google\protobuf\io\zero_copy_stream_impl.h
+copy ..\src\google\protobuf\io\zero_copy_stream_impl_lite.h include\google\protobuf\io\zero_copy_stream_impl_lite.h
+copy ..\src\google\protobuf\compiler\code_generator.h include\google\protobuf\compiler\code_generator.h
+copy ..\src\google\protobuf\compiler\command_line_interface.h include\google\protobuf\compiler\command_line_interface.h
+copy ..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h
+copy ..\src\google\protobuf\compiler\parser.h include\google\protobuf\compiler\parser.h
+copy ..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h
+copy ..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h
+copy ..\src\google\protobuf\compiler\python\python_generator.h include\google\protobuf\compiler\python\python_generator.h
+copy ..\src\google\protobuf\compiler\plugin.h include\google\protobuf\compiler\plugin.h
diff --git a/src/third_party/protobuf/vsprojects/readme.txt b/src/third_party/protobuf/vsprojects/readme.txt
new file mode 100644
index 0000000..288345a
--- /dev/null
+++ b/src/third_party/protobuf/vsprojects/readme.txt
@@ -0,0 +1,114 @@
+This directory contains project files for compiling Protocol Buffers using
+MSVC. This is not the recommended way to do Protocol Buffer development --
+we prefer to develop under a Unix-like environment -- but it may be more
+accessible to those who primarily work with MSVC.
+
+Compiling and Installing
+========================
+
+1) Open protobuf.sln in Microsoft Visual Studio.
+2) Choose "Debug" or "Release" configuration as desired.*
+3) From the Build menu, choose "Build Solution". Wait for compiling to finish.
+4) From a command shell, run tests.exe and lite-test.exe and check that all
+ tests pass.
+5) Run extract_includes.bat to copy all the public headers into a separate
+ "include" directory (under the top-level package directory).
+6) Copy the contents of the include directory to wherever you want to put
+ headers.
+7) Copy protoc.exe wherever you put build tools (probably somewhere in your
+ PATH).
+8) Copy libprotobuf.lib, libprotobuf-lite.lib, and libprotoc.lib wherever you
+ put libraries.
+
+* To avoid conflicts between the MSVC debug and release runtime libraries, when
+ compiling a debug build of your application, you may need to link against a
+ debug build of libprotobuf.lib. Similarly, release builds should link against
+ release libs.
+
+DLLs vs. static linking
+=======================
+
+Static linking is now the default for the Protocol Buffer libraries. Due to
+issues with Win32's use of a separate heap for each DLL, as well as binary
+compatibility issues between different versions of MSVC's STL library, it is
+recommended that you use static linkage only. However, it is possible to
+build libprotobuf and libprotoc as DLLs if you really want. To do this,
+do the following:
+
+ 1) Open protobuf.sln in MSVC.
+ 2) For each of the projects libprotobuf, libprotobuf-lite, and libprotoc, do
+ the following:
+ 2a) Right-click the project and choose "properties".
+ 2b) From the side bar, choose "General", under "Configuration Properties".
+ 2c) Change the "Configuration Type" to "Dynamic Library (.dll)".
+ 2d) From the side bar, choose "Preprocessor", under "C/C++".
+ 2e) Add PROTOBUF_USE_DLLS to the list of preprocessor defines.
+ 3) When compiling your project, make sure to #define PROTOBUF_USE_DLLS.
+
+When distributing your software to end users, we strongly recommend that you
+do NOT install libprotobuf.dll or libprotoc.dll to any shared location.
+Instead, keep these libraries next to your binaries, in your application's
+own install directory. C++ makes it very difficult to maintain binary
+compatibility between releases, so it is likely that future versions of these
+libraries will *not* be usable as drop-in replacements.
+
+If your project is itself a DLL intended for use by third-party software, we
+recommend that you do NOT expose protocol buffer objects in your library's
+public interface, and that you statically link protocol buffers into your
+library.
+
+ZLib support
+============
+
+If you want to include GzipInputStream and GzipOutputStream
+(google/protobuf/io/gzip_stream.h) in libprotoc, you will need to do a few
+additional steps:
+
+1) Obtain a copy of the zlib library. The pre-compiled DLL at zlib.net works.
+2) Make sure zlib's two headers are in your include path and that the .lib file
+ is in your library path. You could place all three files directly into the
+ vsproject directory to compile libprotobuf, but they need to be visible to
+ your own project as well, so you should probably just put them into the
+ VC shared icnlude and library directories.
+3) Right-click on the "tests" project and choose "properties". Navigate the
+ sidebar to "Configuration Properties" -> "Linker" -> "Input".
+4) Under "Additional Dependencies", add the name of the zlib .lib file (e.g.
+ zdll.lib). Make sure to update both the Debug and Release configurations.
+5) If you are compiling libprotobuf and libprotoc as DLLs (see previous
+ section), repeat steps 2 and 3 for the libprotobuf and libprotoc projects.
+ If you are compiling them as static libraries, then you will need to link
+ against the zlib library directly from your own app.
+6) Edit config.h (in the vsprojects directory) and un-comment the line that
+ #defines HAVE_ZLIB. (Or, alternatively, define this macro via the project
+ settings.)
+
+Notes on Compiler Warnings
+==========================
+
+The following warnings have been disabled while building the protobuf libraries
+and compiler. You may have to disable some of them in your own project as
+well, or live with them.
+
+C4018 - 'expression' : signed/unsigned mismatch
+C4146 - unary minus operator applied to unsigned type, result still unsigned
+C4244 - Conversion from 'type1' to 'type2', possible loss of data.
+C4251 - 'identifier' : class 'type' needs to have dll-interface to be used by
+ clients of class 'type2'
+C4267 - Conversion from 'size_t' to 'type', possible loss of data.
+C4305 - 'identifier' : truncation from 'type1' to 'type2'
+C4355 - 'this' : used in base member initializer list
+C4800 - 'type' : forcing value to bool 'true' or 'false' (performance warning)
+C4996 - 'function': was declared deprecated
+
+C4251 is of particular note, if you are compiling the Protocol Buffer library
+as a DLL (see previous section). The protocol buffer library uses templates in
+its public interfaces. MSVC does not provide any reasonable way to export
+template classes from a DLL. However, in practice, it appears that exporting
+templates is not necessary anyway. Since the complete definition of any
+template is available in the header files, anyone importing the DLL will just
+end up compiling instances of the templates into their own binary. The
+Protocol Buffer implementation does not rely on static template members being
+unique, so there should be no problem with this, but MSVC prints warning
+nevertheless. So, we disable it. Unfortunately, this warning will also be
+produced when compiling code which merely uses protocol buffers, meaning you
+may have to disable it in your code too.